C中指针变量的冲突类型(错误)

时间:2015-07-23 01:02:36

标签: c variables pointers compiler-errors

(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行。

3 个答案:

答案 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(正如您对intd所做的那样)只要第一个就可以了没有初始化程序。这称为暂定定义

为避免这一切,请确保任何不属于声明的代码都在函数内部。你可以写文件范围:

e

等等。

此外,int a = 5; int *pa = &a; 会导致undefined behaviourprintf("%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;

用于使用初始化程序定义声明,而不是赋值语句。它将先前的de声明视为非定义声明,并且因为它们被声明为int,所以没有冲突。

相比之下,陈述

pa = &a;
pb = &b;

被视为具有初始值设定项的隐式int声明,但由于您之前将它们声明为int *,因此编译器会抱怨类型不匹配。

注意:输出语句存在问题。

printf("%i, %i, %i, %i", pa, pb, d, e);

如果要在papb 指向的变量中打印整数值,则必须取消引用 printf致电:

printf("%i, %i, %i, %i", *pa, *pb, d, e);

如果要打印存储在papb中的指针值,则必须使用%p转换说明符:

printf("%p, %p, %i, %i", (void *)pa, (void *)pb, d, e);

以及将指针值强制转换为void *(这几乎是你在C语言中明确地转换为void *的指针。)