C语言多文件编译时,编译器不检测其声明的变量类型与定义时的类型是否匹配

比如我在文件1里定义int c = 0x31323334;

在文件2里声明extern char c;   编译器并不会报错的。


//File: 1.c

char a[100] = {0x31, 0x32, 0x33, 0x34, 0x35};
char *b = "abcde";
int c = 0x31323334;

char* f(void)
{
    return b;
}

//File: 2.c

#include <stdio.h>
extern char *a;
extern char b[ ];
extern char c;
extern f();

int main(void)
{
    //char *d1 = (char *)(b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24));
    char *d = (char *)((unsigned char)b[0] + ((unsigned char)b[1] << 8) + \
            ((unsigned char)b[2] << 16) + ((unsigned char)b[3] << 24));

    printf("%x\n", a);
    //printf("%c\n", *a);//这里运行会出错:Segmentation fault (core dumped)
    printf("%x\n", f()); //"abcde"这个字串的首地址,
    printf("%x\n", d); //  d  = f();
    //printf("%x\n", d1);
//必须先将char转换成unsigned char,因为char参加运算时会被提升为int型,而对于有符号型数据,
//在扩展时,高位由符号位决定,为1则补1,为0则补0.无符号型数据全补0
    printf("%x %x %x %x\n", b[0], b[1], b[2], b[3]);
    printf("%x %x %x %x\n", (unsigned char)b[0], (unsigned char)b[1], \
            (unsigned char)b[2], (unsigned char)b[3]);
    
    printf("%c\n", c);
    return 0;
}

运行结果:

34333231
80485d4
80485d4
ffffffd4 ffffff85 4 8
d4 85 4 8
4


虽然在文件 1 中,编译器知道 a 是一个数组,但是在文件 2 中,编译器并不知道这点。大多数编译器是按文件分别编译的,编译器只按照本文件中声明的类型来处理。所以,虽然 a 实际大小为 100 个 byte,但是在文件 2 中,编译器认为 a 是一个char*指针,只占 4 个 byte。编译器会把存在指针变量中的任何数据当作地址来处理。故文件2中a存放的数据其实是文件1中数组a的前4个元素,即文件2中a=0x34333231(小端机器),对这个未定义的地址进行访问,所以出错了。


而文件2中,编译器把b当作char数组了,在文件1中 b实际上是指向了"abcde"这个字串的首地址,故文件2中b数组的前四个元素为"abcde"这个字符串的首地址,我将文件中b数组4个元素的值转换成一个指针d,d的值与f()所返回的值相同


文件2中,编译器将c 当做char型,c的值为文件1中int c第一个字节的值




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值