3

有一个关于以下代码的指针我无法弄清楚:函数中的部分set_array([][9]),为什么编译器给出允许这个而不是正常的完整表达式set_array([4][9])。但是在main部分中int array1[4][9]array1[][9]不允许。

#include <stdio.h>
void set_array(int t_array[][9]);
int main(void) {
    int array1[4][9]; // array1[][9] doesn't allowed

    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 9; j++) {
            array1[i][j] = j + 1;
        }
    }
    set_array(array1);
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 9; j++) {
            printf("%d ", *(*(array1 + i) + j));
            //printf("%d ", array1[i][j]);
        }
        puts("\n");
    }
    return 0;

}
void set_array(int t_array[][9]) {
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 9; j++) {
            t_array[i][j] = 1;
        }
    }   
};

对此有何解释?

4

6 回答 6

2

在函数调用中,数组实际上被视为指针,因此在函数定义 t_array[][9]中实际上是(*t_array)[9] //pointer to array 但在数组的声明中,如果声明静态数组,则必须明确给出大小,以便编译器为数组分配那么多内存。因此,array1[4][9]是正确的,而array1[][9]错误是. 但是如果你正在做array1[][9],那么你必须提供初始化列表。

于 2012-10-24T06:57:59.650 回答
2

作为比较(C89):

当你写

int a[] 

编译器不知道需要为“a”分配多少内存,在这种情况下,编译器需要使用初始化来确定数组的大小:

int a[] = {1,2,3}; // sizeof(a)==sizeof(int)*3

当你只写

int a[][9]; 

编译器不知道“a”有多大,因此无法分配足够的内存

如果您将数组作为参数

void foo(int a[][9]) 

该函数不需要知道两个维度有多大,因为它没有分配任何东西,它只是引用'a'。从参数中,函数知道它应该在取消引用时将“a”视为多维数组(其中第一个维度是任意数字)。

于 2012-10-24T07:02:27.520 回答
1

在 C 语言中,您必须在静态声明数组大小时为其指定一个值,否则编译器将不知道要为该变量分配多少内存。

当您将数组作为数组 [] [9] 传递时,它可以工作,因为编译器只需要知道数组中元素的大小,而不需要知道它包含多少元素。因此,将 array[][] 作为参数传递将不起作用,因为编译器不知道所存储元素的大小。

于 2012-10-24T06:49:17.600 回答
1

您可以使用初始化列表在不指定第一个维度的情况下声明和初始化:

int array1[][9] = {
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9},
};

在 C 中,如果您内联初始化数组,则只需要从第二个开始指定尺寸大小。它们对于编译器生成索引它的代码是必需的,请记住多维数组(在 C 中)是一个连续缓冲区。

于 2012-10-24T06:51:50.683 回答
1

发生这种情况是因为当您在做两件不同的事情时:

首先,您要声明一个名为array1. 在 C 中,编译器需要知道您声明的空间量,以便为您保留该内存量。因此,您必须指定数组的完整大小:

int array1[4][9];

这样你的编译器就知道你需要4 * 9分配整数。

现在,在您的函数中,编译器不需要知道数组的大小(在幕后您的数组被转换为函数调用上的指针),它只需要知道其元素的大小。t_array指向 size 元素的指针也是如此9 * sizeof(int)。这是因为您可以按照您声明的方式声明您的函数:

void set_array(int t_array[][9])

但也可以声明所有维度大小:

void set_array(int t_array[4][9])

但这对编译器无关紧要。

于 2012-10-24T07:07:06.927 回答
0

您不能分配给数组,只能初始化它们,因此您必须一次完成所有操作:

int array1[4][9] = {
 {1,2,3,4,5,6,7,8,9},
 {1,2,3,4,5,6,7,8,9},
 {1,2,3,4,5,6,7,8,9},
 {1,2,3,4,5,6,7,8,9},
};
于 2012-10-24T06:48:46.007 回答