extern char *a与extern char a[]

来源:互联网 发布:js设置div背景颜色 编辑:程序博客网 时间:2024/06/06 02:09

《C陷阱与缺陷》提到要特别注意extern char *a与extern char a[]之间的区别。所以特意测试了一下。测试环境VC6

b.cpp

char *a="ABCDEF";char b[]="ABCDEF";
第一种情况:主文件中声明

extern char a[];
extern char b[];

#include <iostream.h>extern char a[];extern char b[];int main(){cout<<a<<endl;cout<<b<<endl;return 0;}
此时运行结果:


可以看到a乱码了。

第二种情况:主文件声明

extern char *a;
extern char *b;

#include <iostream.h>extern char *a;extern char *b;int main(){cout<<a<<endl;cout<<b<<endl;return 0;}

此时运行结果:


可以看到a正确输出,然后程序出错。

原因分析:

char *a="ABCDEF";
char b[]="ABCDEF";

定义a时,a存储的字符串常量的地址。当以extern char a[];声明外边变量a时,编译器在b.cpp文件中寻找到变量a,并

认为a是char数组类型。a中本来存储的"ABCDEF"的地址,现在编译器却把a当作char数组,所以把a中存储的地址翻译

成字符,如果没有对应的字符,应该就乱码了。

定义b时,b是作为字符串数组的首址。当以extern char *b;声明外部变量b时,编译器在b.cpp中寻找到变量b,并认为b是char*类型。所以把"ABCD"当作地址,并访问这个地址,所以出现内存访问出错。

验证:

b.cpp

char *a="ABCDEF";char b[]="ABCDEF";//获取指针a本身存储的内容,并转化为无符号整数unsigned int a_address(){return (unsigned int)a;}//32为系统,所以获取数组前四个字节转化为无符号整数unsigned int b_int(){return *(unsigned int*)b;}

test.cpp

#include <iostream.h>extern char a[];extern char *b;extern unsigned int a_address();extern unsigned int b_int();int main(){if(*(unsigned int*)a==a_address())cout<<"指针a被错误的认为是数组"<<endl;if((unsigned int)b==b_int())cout<<"数组b被错误的认为是指针"<<endl;return 0;}



所以,声明和定义一定要以相同的形式出现。

原创粉丝点击