zoukankan      html  css  js  c++  java
  • 理解extern char s[100]与extern char *s

    在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是个符号, 它既是一个数组的名称, 又是数组的起始地址(作为名称是因为他是一个标号,作为地址是因为symbol代表的就是一个地址), 假设编译器在编译的时候给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程序员一定要搞清数组和指针并不是完全相同的。

    上面这段其实是在网上摘的,还有一点要说讲清楚:对于需要重定向的”标号“,在链接前,标号代表的地址都是零,以上面的文字中l.c为例,由于他不知道也不需要知道要链接的另一个文件是char []型的,所以对s的操作是按照指针来操作,将数组当作指针来操作当然会出错。

  • 相关阅读:
    使用cocoapods出现问题fetch of the ‘master’ 的解决方法
    说说ASP.NET的表单验证
    php分页类
    php校验
    mySQL时间
    asp .NET弹出窗口 汇总(精华,麒麟创想)
    (转)MVC 3 数据验证 Model Validation 详解
    (转)linux性能优化总结
    (转)ASP.NET缓存全解析6:数据库缓存依赖
    SQL Server是如何让定时作业
  • 原文地址:https://www.cnblogs.com/johnnyflute/p/3593937.html
Copyright © 2011-2022 走看看