Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么不';我们必须将多维数组的行大小传递给函数吗?_C_Arrays - Fatal编程技术网

C 为什么不';我们必须将多维数组的行大小传递给函数吗?

C 为什么不';我们必须将多维数组的行大小传递给函数吗?,c,arrays,C,Arrays,函数void transpossematrix(int a[][arraySize])中的第一个索引为空的原因是什么 当您拥有foo类型的n对象数组a时,编译器可以通过将i乘以foo对象的大小添加到a的起始地址来计算元素a[i]的位置 请注意,此计算仅涉及foo的大小和下标i。它不涉及元素的数量n。编译器不需要知道元素的数量就可以计算元素的位置 您需要知道数组中的元素数,以避免超出数组的末尾。然而,在C语言中,防止超出数组末尾并不是编译器的工作。函数的作者负责这样做。因此,为此,编译器不需要知道

函数
void transpossematrix(int a[][arraySize])
中的第一个索引为空的原因是什么

当您拥有
foo
类型的
n
对象数组
a
时,编译器可以通过将
i
乘以
foo
对象的大小添加到
a
的起始地址来计算元素
a[i]
的位置

请注意,此计算仅涉及
foo
的大小和下标
i
。它不涉及元素的数量
n
。编译器不需要知道元素的数量就可以计算元素的位置

您需要知道数组中的元素数,以避免超出数组的末尾。然而,在C语言中,防止超出数组末尾并不是编译器的工作。函数的作者负责这样做。因此,为此,编译器不需要知道数组中有多少个元素

现在假设每个
foo
对象本身就是
m
类型的
bar
对象数组。编译器确实需要知道
foo
对象的大小。一个
foo
有多大?由于
foo
bar
类型的
m
对象数组,其大小是
m
乘以
bar
的大小。因此,要知道
foo
有多大,编译器需要知道数组中有多少个元素


因此,当向[FirstDimension][SecondDimension]传递
int时,编译器不需要知道
FirstDimension
,而是需要知道
SecondDimension
,,因为
TransposeSematrix
接收的实际上不是2D数组,而是指向1D数组的指针

除非它是
sizeof
或一元
&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则“T
的N元素数组”类型的表达式将被转换(“衰减”)为“指向
T
的指针”类型的表达式,表达式的值将是数组第一个元素的地址

如果将数组声明为

int arr[N][M];
并将其传递给函数

void foo( arr );
然后表达式
arr
从类型“int的M元素数组的N元素数组”转换为“int的M元素数组的指针”(
int(*)[M]

在函数参数声明中,
ta[N]
ta[]
被“调整”为
ta*a
-IOW,这三个函数都将
a
声明为指向
T
的指针(这仅适用于函数参数声明)

因此,

void transposeMatrix(int a[][arraySize])
相当于

void transposeMatrix(int (*a)[arraySize])
使用
a[][M]
而不是
(*a)[M]
是一种符号方便(类似于使用
p->M
而不是
(*p).M
通过指针访问
struct
union
成员)

由于数组索引的工作方式,您可以像任何其他二维数组一样索引到
a
。请记住,下标操作
a[i]
定义为
*(a+i)
-给定起始地址
a
,找到
a
后面的
i
第个元素(不是字节)的地址,然后取消引用结果。因此:

(*a)[i] == (*(a + 0))[i] == (a[0])[i] == a[0][i]
意义

(*(a + j))[i] == (a[j])[i] == a[j][i]

因为数组会衰减为指针。因为函数只需要第二个维度就可以正确计算
a[i][j]
的位置。据推测,函数还有其他方法来确定行数。另请参见。请注意,第一个维度不是“行大小”;它是行数。行大小是二维数组的第二个维度,必须提供。如果你处理的是3D或更高维的数组,那么除了第一个以外的所有大小都必须以这样或那样的方式提供(“另一个”使用VLA表示法)。数组到指针的自动转换是如何相关的?假设数组没有自动转换为指针。然后,当一个数组
a
被传递给一个函数时,它必须通过一些其他机制来传递,例如通过引用或复制,尽管其他方法也是可能的。例如,如果它是一个非常小的数组,例如n的
char[n][2]
≤4,它可以完全在8字节寄存器中传递,就像一些ABI对小结构所做的那样。被调用的例程不需要知道n。因此,并不是转换为指针才可以省略第一个维度。