Nat*_*ows 2 c arrays pointers multidimensional-array implicit-conversion
我一直在研究和测试我在 C 方面的知识(我是一名新的计算机工程专业的学生),遇到了一个我无法弄清楚的问题。
在尝试将 2D 数组传递给函数时,我了解到您不能使用动态分配的数组这样做,因为编译器需要知道 array[][columns]。但是,我了解到二维数组存储在一维数组中,其中每个新行的元素都跟在前一行的元素之后。当我将数组名称作为指向数组的指针传递给函数时,情况似乎如此,我的代码运行良好。但是,在声明 2D 数组的函数中,它表现为一个指针数组。
#include <stdio.h>
void printArray(int *A, int* dimA) {
for(int i = 0; i < dimA[0]; ++i) {
for(int j = 0; j < dimA[1]; ++j) {
printf("%3d", A[i*dimA[1] + j]);//This would work if the elements of A[] are the rows of a 2D array mapped into a 1D array
}
printf("\n\n");
}
return;
}
int main(){
int A[2][2] = {{1,2},{3,4}};
int dimA[2] = {2,2};//dimensions of the array
int i, j;
for(i = 0; i < dimA[0]; ++i) {
for(j = 0; j < dimA[1]; ++j) {
printf("%3d", *(A[i] + j)); //This would work if the elements of A[] are pointers
}
printf("\n\n");
}
for(i = 0; i < dimA[0]; ++i) { //Same code as printArray function
for(j = 0; j < dimA[1]; ++j) {
printf("%3d", A[i*dimA[1] + j]);//This would work if the elements of A[] are the rows of a 2D array mapped into a 1D array
}
printf("\n\n");
}
printArray(A, dimA);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当数组被视为指针数组时,以下代码在 main() 中正确输出数组,但当被视为一维整数数组时则不会。但是,当我将相同的数组作为指针传递给 printArray 函数时,我可以将其视为一维整数数组并且它可以工作。任何帮助将不胜感激(我已经知道我可以使用指针数组,但我真的很想了解问题所在)。谢谢!
根据 C 标准(6.3.2.1 左值、数组和函数指示符)
3 除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为“array of type”的表达式将转换为类型为“pointer”的表达式键入 '' 指向数组对象的初始元素并且不是左值。如果数组对象具有寄存器存储类,则行为未定义。
因此在第一个 for 循环中
for(i = 0; i < dimA[0]; ++i) {
for(j = 0; j < dimA[1]; ++j) {
printf("%3d", *(A[i] + j)); //This would work if the elements of A[] are pointers
}
printf("\n\n");
}
Run Code Online (Sandbox Code Playgroud)
表达式A[i]
的类型为int[2]
。被转换为指针,它的类型为int *
。因此,对于每个 i 表达式A[i]
指向数组的每个“行”的第一个元素A
。
该表达式A[i] + j
指向每行的第 j 个元素。因此,取消引用指针,您将获得数组第 i 行的第 j 个元素。
在第二个循环中
for(i = 0; i < dimA[0]; ++i) { //Same code as printArray function
for(j = 0; j < dimA[1]; ++j) {
printf("%3d", A[i*dimA[1] + j]);//This would work if the elements of A[] are the rows of a 2D array mapped into a 1D array
}
printf("\n\n");
}
Run Code Online (Sandbox Code Playgroud)
表达式A[i*dimA[1] + j]
具有类型int *
并指向i *dimA[1] + j
数组的“行”,即它指向数组之外。所以循环没有意义。
函数声明如下
void printArray(int *A, int* dimA);
Run Code Online (Sandbox Code Playgroud)
被称为像
printArray(A, dimA);
Run Code Online (Sandbox Code Playgroud)
具有该类型的第二个参数int[2]
确实被转换为指向int *
数组第一个元素的类型的指针。
至于第一个参数,它也被转换为指向其第一个元素的指针。数组的元素是什么?这个二维数组的元素是一个类型为 的一维数组int[2]
。所以指向这种类型的对象的指针将具有类型int ( * )[2]
指针int *
和int ( * )[2]
不兼容,因此编译器应发出诊断消息。
函数的正确声明应该是这样的
void printArray(int ( *A )[2], int *dimA);
Run Code Online (Sandbox Code Playgroud)