为什么我不能直接在C中为指针分配数组?

我有以下程序。 但是,我无法理解为什么我必须传递数组的地址。 当他们都指向同一个地址时。 这是int数组的第一个元素的地址。

当我尝试执行“从不兼容的指针类型分配”时,我收到警告:

ptr = var; 

完整源代码:

 void print_values(int (*ptr)[5]) { size_t i = 0; for(i = 0; i < 5; i++) { printf("%d: [ %d ]\n", i, (*ptr)[i]); } } int main(void) { /* declare a pointer to an array integers */ int (*ptr)[5] = NULL; /* array of integers */ int var[] = {1, 2, 3, 4, 5}; /* assign the address of where the array is pointing to (first element) */ ptr = &var; /* Both are pointing to the exact same address */ printf("var [ %p ]\n",(void*)var); printf("&var [ %p ]\n", (void*)&var); print_values(ptr); return 0; } 

我用gcc 4.4.4 c89 -Wall -Wextra -O0编译代码

这纯粹是一个类型问题。

在大多数表达式上下文中,数组的名称(例如var )衰减为指向数组初始元素的指针,而不是指向数组的指针。 [注意,这并不意味着var是一个指针 – 它不是一个指针 – 它的行为就像一个指向大多数表达式中数组的第一个元素的指针。

这意味着在表达式var通常衰减到指向int的指针,而不是指向int数组的指针。

由于运算符地址( & )的操作数是一个不应用此衰减规则的上下文(另一个作为sizeof运算符的操作数)。 在这种情况下, &var的类型直接从var的类型派生,因此类型是指向5 int数组的指针。

是的,指针具有相同的地址值(数组的第一个元素的地址是数组本身的地址),但它们有不同的类型( int* vs int(*)[5] )因此在分配。

ISO / IEC 9899:1999 6.3.2.1/4:

除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为“array of type ”的表达式转换为“指向类型的指针”类型的表达式指向数组对象的初始元素,而不是左值。 …

C是一种强类型语言。 当函数需要int *类型的参数时,必须传递int *类型的参数。 不是double * ,不是char * ,而是int * 。 即使那些double *char *的实际数字地址与你想要传递的那个“相同”,它仍然不会改变任何东西 – 你仍然必须传递一个int * 。 该语言禁止您传递错误类型的值。

这正是你的情况。 该函数采用int (*)[5]类型的参数。 这意味着您必须传递该类型的参数。 不允许传递int * 。 地址是否相同也没有区别。

var本身是一个(*int)指向数组中的第一个元素。 C中的指针和数组非常相似。 改变int (*ptr)[5] = NULL; to int* ptr = NULL;ptr = &var;ptr = var;

从我可以告诉你的是将数组指针( var )分配给指向数组指针的指针( (*ptr)[5] ),这就是你得到那个警告的原因。

相反,尝试使用

 int *ptr = NULL;