有人可以让我知道黑白的区别
int vector[]={10,20,30}
int *p = vector
和
int *p= &vector
通过提及数组名称,我知道它是基地址。第二句话是警告我
从不兼容的指针类型初始化
为什么警告,两个语句都给出数组的基地址。
答案 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指针存在一些技术问题,这意味着在特定意义上指向同一位置的两个指针可能并非完全“相同”。在这个答案中,我不会详细介绍。在本讨论中,我们可以将指向同一位置的指针视为相同的地方。