对于一个数组的变量名(就是arrary【】中的array),我们无法像指针一样直接用&取址。下面是一个很好的例子。 在一个文件中变量定义成指针,而在其他文件中extern成数组在编译器中的处理的确很有趣。 第一种情况: file1.c char p[]= "Hello every one "; file2.c extern char *p; 定义了数组 p, 编译器为这个数组分配了内存来放这个数组, 并记下这个内存的地址和符号表中的 p 对应 p -> 0x10000000 并且把 0x10000000 的内容写为 48 65 6c 6c 6f ... 按指针来访问的时候,首先取出符号 p 对应的地址 0x10000000,然后在这个地址上取出四个字节作为指针指向的地址,这是得到的是 0x6c6c6548, 显然这个地址并没有被分配过,除非其它某个地方恰好使用了这个内存,否则访问就会出错。 第二中情况: file1.c char *p; ....... p=(char *)malloc(20*sizeof(char)); ....... file2.c extern char p[]; 定义的是一个指针,编译器首先为 p 分配四个字节的内存,比如地址是 0x20000000 - 0x20000003 来存放一个地址。然后在符号表中 p -> 0x20000000. p = (char*)malloc(...) 的时候,比如 malloc 分配得到的地址是 0x3000000, 运行的时候就会把 0x20000000 - 0x20000003 的内存内容改为 00 00 00 30, 在 0x3000000 中是字符串内容。 把 p 按数组来访问的时候, 编译器首先找到 p 对应的地址 0x20000000 做完数组首地址, p[3] 访问到的就是 0x2000003 的内容,而根据前面的描述,这个内存是已经分配过在使用中的,并不会出现访问违规的情况。 而且可以看到得到的结果实际上是 malloc 返回的地址,得不到想要的字符串的。 考虑下面的测试代码: file1.c: int *p; void foo() { printf( "int *p/n "); printf( "foo-- p[%x]/n ",p); printf( "foo--&p[%x]/n ",&p); printf( "foo--*p[%x]/n/n ",*p); } file2.c: extern int p[]; extern void foo(); int a=0xaaaa; int main(); { p[0]=&a; foo(); printf( "extern int p[]/n "); printf( "main- p[%x]/n ",p); printf( "main-&p[%x]/n ",&p); printf( "main-*p[%x]/n ",*p); return 0; } 运行结果: int *p foo-- p[500a00] foo--&p[500a10] foo--*p[aaaa] extern int p[] main- p[500a10] main-&p[500a10] main-*p[500a00] 从上面的运行结果来看,变量原型定义成指针,但是在另外的文件中extern成数组,那在这个extern的文件中是按照数组来处理这个变量,数组的首地 址为改指针变量的地址,(而非其内容指向的地址),数组的存储首地址跟编译器为变量原型指针所分配的内存地址一致。在C专家中好像是没有提到这种用法,但 是事实上是可以这么用的。
数组和指针确实是不一样的
最新推荐文章于 2025-01-01 16:47:55 发布