(1)
#include <stdio.h>
#include <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
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)。为什么我可以在main函数(d,e)之外初始化正常变量而不是指针变量?
我在CodeBlocks中收到的错误消息是:pa的文件类型冲突。先前的pa声明在这里:第4行。
答案 0 :(得分:4)
你可以初始化main()之外的指针,但声明需要随后定义。检查代码:
`
#include <stdio.h>
#include <stdlib.h>
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;
}
`
答案 1 :(得分:4)
可执行代码必须进入函数内部。这是因为C程序的执行流程始于调用main()
。
int a = 10;
之类的行称为声明,可能会被视为&#34;发生&#34;在程序开始之前。通常,编译器将生成所有全局变量的集合。数据并在启动程序时加载。
在文件范围内编写d = 10;
时,会将其视为int d = 10;
。由于在文件范围内不允许语句,因此它不是赋值语句。编译器认为这是一个声明,你打算写int
,但想把它留出来保存输入。
这被称为 implicit int ,C89拥有它,尽管它已在C99中删除。
因此,当您编写pa = &a;
时,隐式int使其成为int pa = &a;
,并且您收到错误,因为您已使用类型pa
声明int *
,然后再使用{{1} },这是不同的类型。
然而,将变量声明为int
,然后将其重新声明为int
(正如您对int
和d
所做的那样)只要第一个就可以了没有初始化程序。这称为暂定定义。
为避免这一切,请确保任何不属于声明的代码都在函数内部。你可以写文件范围:
e
等等。
此外,int a = 5;
int *pa = &a;
会导致undefined behaviour。 printf("%i, %i, %i, %i", pa, pb, d, e);
说明符必须与%i
匹配。要解决此问题,您需要传递int
而不是(int)pa
等,或使用pa
说明符。
答案 2 :(得分: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 *
的指针。)