数组不兼容的指针类型

时间:2018-10-12 13:39:43

标签: c arrays pointers

有人可以让我知道黑白的区别

int vector[]={10,20,30}
int *p = vector

int *p= &vector

通过提及数组名称,我知道它是基地址。第二句话是警告我

从不兼容的指针类型初始化

为什么警告,两个语句都给出数组的基地址。

3 个答案:

答案 0 :(得分:4)

在表达式中使用时,在大多数情况下,数组名称会衰减指向其第一个元素的指针。

所以这个:

int *p = vector;

等效于:

int *p = &vector[0];

&vector[0]的类型为int *,因此类型兼容。

当数组是地址运算符&的对象时,数组衰减的次数之一。那么&array是数组的地址,类型为int (*)[3],即指向大小为3的数组的指针。这与int *不兼容,因此会出错。

尽管数组的地址及其第一个元素的地址具有相同的,但它们的类型不同。

答案 1 :(得分:2)

&vector的类型为int (*)[3],即数组的 pointer ,而没有vector的{​​{1}}将衰减为&指向第一个元素。

int *,即使指向相同的地址int (*)[3]不兼容,因此您的程序有约束冲突,这使您的程序成为 invalid < / em>程序,并且编译器必须发出诊断消息。

C标准在[脚注(C11 footnote 9)中明确提到允许编译器成功编译无效程序:

  

9)目的是,实现应识别每种违规的性质,并在可能的情况下进行本地化。当然,只要仍然正确转换了有效程序,实现就可以自由生成任何数量的诊断信息。 它也可能成功翻译了无效的程序。

即只要有效程序已正确翻译,编译器就可以对给定的源代码进行任何处理。因此,许多编译器会使用默认设置通过手指查看这些内容,并提供具有或多或少预期-或同样出乎意料的结果-的翻译,并且您将仅 警告< / strong>。

答案 2 :(得分:2)

C语言中的表达式具有类型

给出int vector[] = {10, 20, 30};vector是一个数组。 C有一个规则,当在某些地方 1 之外的表达式中使用数组时,它会自动转换为指向其第一个元素的指针。然后,它的值实际上是数组 2 的起始地址,其类型是“指向int的指针”。

表达式&vector获取数组的地址。这与它的第一个元素的地址不同。在很大程度上,它们都具有相同的 value 。数组及其第一个元素都从内存中的同一位置开始。但是它们有不同的类型&vector的类型是“指向3 int的数组的指针”。

C有关于类型的规则,并且您不能在需要其他类型的情况下自动使用一种类型。有时,类型会自动转换,例如将较窄的整数转换为较宽的整数时。但是,通常在类型对于软件的意义很重要的地方,没有自动转换(或有限的转换)。如果您尝试将指向数组的指针分配给指向int的指针,那么好的编译器会警告您您做的事情不正确。

将一种类型的指针分配给另一种类型的指针时,可能是因为程序员犯了一个错误。这就是编译器警告您的原因。

此外,具有不同类型的相同值的行为可能有所不同。由于array是指向其第一个 的指针,因此a + 1是指向第二个元素的指针。但是,由于&array是指向 array 的指针,因此&array + 1是指向数组末尾的指针(如果存在,则该数组之后的下一个数组将从此处开始)。

脚注

1 当数组是sizeof的操作数或一元&的操作数或者是用于初始化数组的字符串文字时,数组不会自动转换。 / p>

2 当然,数组在内存中与第一个元素相同的位置开始。因此它们具有相同的虚拟地址。因此,它们在这个意义上具有相同的价值。但是,关于C指针存在一些技术问题,这意味着在特定意义上指向同一位置的两个指针可能并非完全“相同”。在这个答案中,我不会详细介绍。在本讨论中,我们可以将指向同一位置的指针视为相同的地方。