理解extern char s[100]与extern char *s

参考资料:
首先要搞清楚编译程序占用的内存的分区形式:
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于

数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据

结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态

变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统

释放。
4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区
这是一个前辈写的,非常详细
//main.cpp
  int a=0;    //全局初始化区
  char *p1;   //全局未初始化区
  main()
  {
   int b;栈
   char s[]="abc";   //栈
   char *p2;         //栈
   char *p3="123456";   //123456/0在常量区,p3在栈上。
   static int c=0;   //全局(静态)初始化区
   p1 = (char*)malloc(10);
   p2 = (char*)malloc(20);   //分配得来得10和20字节的区域就在堆区。
   strcpy(p1,"123456");   //123456/0放在常量区,编译器可能会将它与p3所向"123456"优化成一个

 

 

字符数组和字符串指针的区别

  char a[] = "Hello World";

  char *p = "Hello World";

  *(a+1) =u;    *(p+1) =u;

  *(a+1) =u;操作会通过,而*(p+1) =u;操作则会出现段错误。这是什么原因呢?那么我们需要了解下,程

  序空间分配中存储区问题。C/C++程序所对应的存储区,分位三类:

  1.)静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存

  放静态数据、全局数据和常量。

  2.)栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自

  动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  3.)堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适

  当的时候用free或delete释放内存。

  这里char a[] = "Hello World",其空间是分配在栈中的,所以你可以对其中的内容进行修改。而char *p

  = “Hello World”,其空间是分配在静态存储区的。且Hello world为字符串常量,是不允许修改

在x.c中定义了一个字符数组 char s[100],
在l.c中进行引用extern char s[200], 有些c程序新手经常把它写成extern char *s。 这两种写法的含义一样吗?

首先得理解声明与定义的含义:
定义一个变量意味着要给它进行内存分配, 而声明一个变量则可以在其他文件中, 只是进行一种声明, 表示有这个变量存在, 但是在其他文件中定义, 声明后不用分配内存。

我们看一下extern char s[100]与extern char *s在执行s[10]的取值过程是什么样的:

1、 extern char s[100], s是个符号, 它既是一个数组的名称, 又是数组的起始地址, 假设编译器在编译的时候给s分配的地址是6789, 那么程序在执行s[10]的时候, 先找到s符号的地址6789, 然后在取(6789+10)地址上的内容。

2、extern char *s它声明了s是个指针, 既然是指针, 那么取址的过程就是间接的。 s这个符号在编译的时候也是有地址的, 不过这个地址上的内容又是一个地址, 在这个地址上保存的才是要存取的内容。当在x.c中定义s为字符数组后, 在l.c中声明s却是个指针, 这样在用s[10]操纵的时候会出现什么问题呢?
s在x.c中被编译器分配的地址是6789, 在l.c中被当成指针了, 所以先找到6789这个地址, 在这个地址上取值作为内容的地址,6789上实际保存的是s[0]的值, 我们假设为'a', 然后程序会把'a'这个值当成地址, 然后去'a'这个地址上取内存内容, 'a'地址上显然存放的是内核数据段或代码段, 应用程序显然会报错的。 如果s[0]存放的即使是应用层程序可以访问的内容, 那么程序也会出现莫名其妙的bug。

所以c程序员一定要搞清数组和指针并不是完全相同的。

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值