C中指针变量的冲突类型(错误)
(1)
#include #include int a = 10, b = 20 , c = 30, d, e, *pa, *pb, *pc; d= 10; e= 100; pa = &a; pb = &b; int main() { printf("%i, %i, %i, %i", pa, pb, d, e); return 0; }
(2)
#include #include int a = 10, b = 20 , c = 30, d, e, *pa, *pb, *pc; d= 10; e= 100; int main() { pa = &a; pb = &b; printf("%i, %i, %i, %i", pa, pb, d, e); return 0; }
为什么在初始化主函数(1)之外的指针变量pa和pb时会出现错误? 当pa和pb在主函数内部时,它可以很好地工作(2) 。 为什么我可以初始化主函数(d,e)之外的正常变量而不是指针变量?
我在CodeBlocks中收到的错误消息是:pa的文件类型冲突。 先前的pa声明在这里:第4行。
可执行代码必须进入函数内部。 这是因为C程序的执行流程始于调用main()
。
像int a = 10;
被称为声明 ,它们可能被认为是在程序开始之前“发生”。 通常,编译器将生成所有全局变量数据的块,并在启动程序时加载它。
当你写d = 10;
在文件范围内,这被视为int d = 10;
。 由于在文件范围内不允许语句,因此它不是赋值语句。 编译器认为这是一个声明,你打算写int
但想通过将其保留来保存输入。
这被称为隐式int ,C89有它,尽管它在C99中被删除了。
所以当你写pa = &a;
,implicit int使其成为int pa = &a;
并且你得到一个错误,因为你已经声明了类型为int *
pa
,然后再使用int
,它们是不同的类型。
然而,将变量声明为int
然后将其重新声明为int
(就像对d
和e
所做的那样)只要第一个没有初始化器就可以了。 这称为暂定定义 。
为了避免这一切,请确保任何不是声明的代码都在函数内部。 你可以写文件范围:
int a = 5; int *pa = &a;
等等。
另外, printf("%i, %i, %i, %i", pa, pb, d, e);
导致未定义的行为 。 %i
说明符必须与int
匹配。 要解决此问题,您需要传递(int)pa
而不是pa
等,或使用%p
说明符。
你可以初始化main()之外的指针,但声明需要随后定义。 检查代码:
` #include #include int a = 10, b = 20 , c = 30, d, e; d= 10; e= 100; int *pa = &a; int *pb = &b; int main() { printf("%p, %p, %i, %i", pa, pb, d, e); return 0; }
`
分配和初始化是不同的操作。
int *pa = &a;
是一个带初始化程序的声明,可以在函数或文件范围内发生。
int *pa; pa = &a;
是一个声明,后跟一个赋值语句。 赋值语句(与任何其他可执行语句一样)必须在函数体内发生。
我猜这是一个较旧的编译器仍然允许隐式int
声明,所以它正在处理语句
d = 10; e = 100;
作为使用初始化器定义声明,而不是赋值语句。 它将之前的d
和e
声明视为非定义声明,并且因为它们被声明为int
,所以没有冲突。
相比之下,这些陈述
pa = &a; pb = &b;
被初始化器处理为隐式int
声明,但由于您之前将它们声明为int *
,因此编译器会抱怨类型不匹配。
注意:输出语句有问题。
printf("%i, %i, %i, %i", pa, pb, d, e);
如果要在pa
和pb
指向的变量中打印整数值,则必须在printf
调用中取消引用它们:
printf("%i, %i, %i, %i", *pa, *pb, d, e);
如果要打印存储在pa
和pb
的指针值,则必须使用%p
转换说明符:
printf("%p, %p, %i, %i", (void *)pa, (void *)pb, d, e);
以及将指针值转换为void *
(这几乎是你在C中显式地将指针转换为void *
的时候)。