在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的操作是按照指针来操作,将数组当作指针来操作当然会出错。

理解extern char s[100]与extern char *s的更多相关文章

  1. 字符串的高级应用-char a[100] = "1+2=;3-2=;2*5=;8/4=;" 得到char a[100] ="1+2=3;3-2=1;2*5=10;8/4=2;"

    1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 char a[100] = "1+2=;3 ...

  2. 【转载】理解C语言中的关键字extern

    原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...

  3. char * p = "abc"与const char *p = "abc"

    char * p = "abc"与const char *p = "abc"的区别是什么呢? 第一个语句会产生问题: warning: deprecated c ...

  4. 20130324 LBP CSLBP 全局存储区 局部存储区 char c[]=”hello world”和char *str=”hello world”的区别

    1.LBP and CSLBP 2.再论char c[]=”hello world”和char *str=”hello world”的区别 /**************代码1************ ...

  5. char s[]字串和char *s字串有什麼区别?

    C語言有兩種字串宣告方式char s[]和char *s,兩者有什麼差異呢? Introduction char s[] = "Hello World"; (只是用字符串常量初始化 ...

  6. C语言char*字符串数组和unsigned char[]数组的相互转换

    #include <iostream> #include <string> using namespace std; void convertUnCharToStr(char* ...

  7. char a[] = "hello world1"和char *p = "hello world2";的区别(转)

    转自:jianchi88 http://blog.csdn.net/jianchi88/article/details/6876405 #include<stdio.h> int main ...

  8. Delphi7中的Char和XE中的Char

    我用FillChar()函数时,发现两个版本中的Char不一样. 在delphi7中 procedure TForm2.Button1Click(Sender: TObject); var s: ar ...

  9. char * const p和const char *p的区别

    1. 前者定义P为常量,即只能单向赋值一次,P++展开为p=p+1,重复赋值给常量,出错,后者P为地址变量,地址变量是指向该变量的存储地址值如:4B3F6A,不能赋给一个字符值(字符相当于ascii表 ...

随机推荐

  1. 关于C++引用的一些注意点

    C++的引用首先跟指针的最大区别就是引用不是一个对象,而指针是一个对象:其次引用在其定义时就要初始化,而指针可以不用. ; int &rval = val; 此时rval就绑定了val,其实就 ...

  2. CentOS-6.5安装配置JDK-7|Tomcat-8

    安装说明 系统环境:centos-6.5 安装方式:rpm安装 软件:jdk-7-linux-x64.rpm 下载地址:http://www.oracle.com/technetwork/java/j ...

  3. 使用OpenXml操作Excel,以下方法用于在添加列时修改Cell的CellReference属性。

    以下方法实现了递增Excel中单元格的CellReference的功能,只支持两位字母. public static string CellReferenceIncrement(string cell ...

  4. 2014年辛星完全解读Javascript第三节

    经过第一节的入门和第二节的运算符,那么接下来我们就可以学习Javascript的函数了,当然了,不管大家之前学习的是什么编程语言,都会有函数的概念,如果大家学的是Pascal,还会有”过程“的概念,但 ...

  5. C#网络编程简单实现通信小例子-1

    1.主界面 2.源程序 Send public partial class formUdpSend : Form { //声明一个UdpClient对象 UdpClient udpClient; pu ...

  6. 关于分区技术的索引 index

    关于分区技术---索引 Index 一.   分区索引分类: 本地前缀分区索引(local prefixedpartitioned index) 全局分区索引(global partitionedin ...

  7. nginx低版本不支持pathinfo模式,thinkphp针对此问题的解决办法

    将一个thinkphp项目从apache环境移到nginx1.2上,怎奈,nginx这个版本默认不支持pathinfo模式 首先,编辑nginx的虚拟主机配置文件 location ~ .*.(php ...

  8. 开发之前的思考-UI结构设计

    UI结构设计遵循的一些要点 1.尽量不要让UI作为Camera的子物体 因为UI和摄像机敏感的关系,尽量不要将UI作为摄像机的子物体,避免出现一些因为透视(3D UI)等问题导致的视觉Bug. 2.尽 ...

  9. 浏览器对象模型BOM(Browser Object Model)

    1.结构 BOM是Browser Object Model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是w ...

  10. apache与nginx日志文件的区别(转载)

    apache与nginx日志文件的区别 转载:http://www.xfcodes.com/apache/log/3270.htm 导读:apache与nginx日志文件的区别,在apache与ngi ...