C 数组指针编译时警告:警告:从不兼容的指针类型初始化
使用涉及阵列点的简单示例会生成以下警告。代码的编译和执行也会引发问题 这是整数数组。 整数[3]={101,202,303} 这两个调用生成警告C 数组指针编译时警告:警告:从不兼容的指针类型初始化,c,arrays,pointers,C,Arrays,Pointers,使用涉及阵列点的简单示例会生成以下警告。代码的编译和执行也会引发问题 这是整数数组。 整数[3]={101,202,303} 这两个调用生成警告 int *p2 = &numbers; int **p3 = &numbers; 以下是生成的警告 > cc -o myApp test.c test.c: In function 'main': test.c:9:12: warning: initialization from incompatible
int *p2 = &numbers;
int **p3 = &numbers;
以下是生成的警告
> cc -o myApp test.c
test.c: In function 'main':
test.c:9:12: warning: initialization from incompatible pointer type [enabled by default]
int *p2 = &numbers;
^
test.c:10:13: warning: initialization from incompatible pointer type [enabled by default]
int **p3 = &numbers;
^
使用的代码如下所示:
#include <stdio.h>
int main ()
{
int numbers[3] = { 101, 202, 303};
int size = sizeof(numbers) / sizeof (numbers[0]);
int *p = numbers;
int *p2 = &numbers;
int **p3 = &numbers;
int *p4 = &numbers[0];
int *end = p + size;
printf("p = 0x%d\n", p);
printf("p2 = 0x%d\n", p2);
printf("p3 = 0x%d\n", p3);
printf("numbers = 0x%d\n", numbers);
printf("&numbers = 0x%d\n", &numbers);
printf("numbers[0] = 0x%d\n", numbers[0]);
printf("&numbers[0] = 0x%d\n", &numbers[0]);
for (; p != end; p++)
{
printf ("0x%d\n", p);
}
}
p2和p3以及p都指向同一地址。
我真的认为使用p3作为双指针可以解决警告问题,但似乎没有。
为什么p2和p3会生成警告?它想说什么?应该是这样的
int numbers[3] = { 101, 202, 303};
及
成员的访问方式应如下所示
(*p2)[0],(*p2)[1] and (*p2)[2]
这与
*(*(p2)+0),*(*(p2)+1) and *(*(p2)+2)
而且
p2[0][0],p2[0][1] and p2[0][2] // Since array notation can be used to dereference pointers.
应该是的
int numbers[3] = { 101, 202, 303};
及
成员的访问方式应如下所示
(*p2)[0],(*p2)[1] and (*p2)[2]
这与
*(*(p2)+0),*(*(p2)+1) and *(*(p2)+2)
而且
p2[0][0],p2[0][1] and p2[0][2] // Since array notation can be used to dereference pointers.
我明白了让你感到困惑的原因。你第一次看到
int *p = numbers;
不要认为数字是指针类型。它只是一个数组对象(int[3]
),它被转换成指向它的第一个元素的指针,即int*
。这称为阵列衰减
现在您可以在int**p3=&numbers代码>-&数字
将为int**
类型
这就是诀窍所在-数组衰减在某些情况下不会发生-当数组用作&
运算符的操作数时-那么它就是这样一种情况-所以它不会衰减。它将是一个数组对象,其指针被认为是int(*)[3]
有了这个逻辑,int*p2=&numbers
编译器也会抱怨。正确的答案应该是这里所说的int(*pp)[3]=&numbers
。请注意,打印指针(不是函数指针)使用%p
格式说明符,参数转换为void*
编译器试图警告您指针类型不匹配。(对于指针,它所指向的类型很重要,因为指针算术由该类型决定)
从§
除非它是sizeof
运算符的操作数、\u Alignof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为“array of type”的表达式将转换为类型为“pointer to type”的表达式它指向数组对象的初始元素,不是左值
我明白了让你感到困惑的原因。你第一次看到
int *p = numbers;
不要认为数字是指针类型。它只是一个数组对象(int[3]
),它被转换成指向它的第一个元素的指针,即int*
。这称为阵列衰减
现在您可以在int**p3=&numbers代码>-&数字
将为int**
类型
这就是诀窍所在-数组衰减在某些情况下不会发生-当数组用作&
运算符的操作数时-那么它就是这样一种情况-所以它不会衰减。它将是一个数组对象,其指针被认为是int(*)[3]
有了这个逻辑,int*p2=&numbers
编译器也会抱怨。正确的答案应该是这里所说的int(*pp)[3]=&numbers
。请注意,打印指针(不是函数指针)使用%p
格式说明符,参数转换为void*
编译器试图警告您指针类型不匹配。(对于指针,它所指向的类型很重要,因为指针算术由该类型决定)
从§
除非它是sizeof
运算符的操作数、\u Alignof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为“array of type”的表达式将转换为类型为“pointer to type”的表达式它指向数组对象的初始元素,不是左值
首先,始终使用%p
打印指针值:
printf( "%p\n", (void *) p );
printf( "%p\n", (void *) p1 );
根据声明
int numbers[3];
那么以下是正确的:
Expression Type "Decays" to Value
---------- ---- ----------- -----
numbers int [3] int * Address of first element of array
&numbers int (*)[3] n/a Address of array (which is the same as above)
*numbers int n/a Value of numbers[0]
除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则类型为“array ofT
”的表达式将转换(“decay”)为类型为“pointer toT
”的表达式,表达式的值将是数组第一个元素的地址。因此,在大多数情况下(如赋值的RHS或函数的参数),表达式numbers
的类型为int*
那么如何正确初始化p2
和p3
?这取决于编写p2+1
或p2[1]
和p3+1
或p3[1]
时希望发生什么。如果希望p2+1
指向numbers
中的第二个元素,或者希望p2[1]
等于numbers[1]
,则可以编写
int *p2 = numbers;
int (*p2)[3] = &numbers;
如果希望p2+1
指向numbers
数组末尾后面的int
的下一个3元素数组,则可以编写
int *p2 = numbers;
int (*p2)[3] = &numbers;
然后将p3
初始化为
int **p3 = &p2;
或
基于p2
的声明方式
一张照片可能会有帮助。假设以下声明:
int numbers[3] = { 0, 1, 2 };
int *p0 = numbers;
int (*p1)[3] = &numbers;
然后事情看起来是这样的:
+---+
numbers: | 0 | numbers[0] <------ p0, p1
+---+
| 1 | numbers[1] <------ p0 + 1
+---+
| 2 | numbers[2]
+---+
... <------ p1 + 1
+--+
数字:| 0 |数字[0]首先,始终使用%p
打印指针值:
printf( "%p\n", (void *) p );
printf( "%p\n", (void *) p1 );
根据声明
int numbers[3];
那么以下是正确的:
Expression Type "Decays" to Value
---------- ---- ----------- -----
numbers int [3] int * Address of first element of array
&numbers int (*)[3] n/a Address of array (which is the same as above)
*numbers int n/a Value of numbers[0]
除非它是sizeof
或一元&