浅议数组不等于指针

    在刚搞C开发的时候,对于char *p="abc"char p[3]="abc"这两句话的理解有些问题,认为他们基本上是等同的,直到有一次在一个头文件中定义了char p[3]="abc" 在另一个文件中写了extern char *p,编译器报错!然后我就对这两句话的含义做了下分析,有空写出来备份下。呵呵 GOGO

      

     一、当p被定义为数组时。

 

先看第一种情况 char p[3]="abc"。这时编译器会将变量p理解为数组,在编译时就为p申请了3char大小的空间,并使p等于此连续的空间的首地址,如:4081 ,这时的内存模式为:

      

对于p[1]来说,就可以对p进行直接内存解引,相当于 *(p+1)

取值的运行步骤为:

1.找到p的首地址;

2.p地址进行偏移1个单位,直接取此地址的值;

 

二、当p被定义为指针时。

再看第二种情况 char *p="abc"。这时编译器会将变量p理解为指针,在编译时就为这个指针对象申请了一个指针的空间大小(一般我们可以把一个指针的空间大小认为是4个字节),编译器为了记住这个指针对象需要另外一个指针指向这个指针对象,此时p所指向的是这个指针对象的地址,如:5035这时的内存模式为:

对于p[1]来说,就可以对p进行间接内存解引。

取值的运行步骤为:

1.找到p的地址;

2.p进行解引,找到”abc”字符串常量的首地址;

2.”abc” 字符串常量的首地址进行1个单位,取此地址的值;

 

三、当char p[3]遇上char *p

现在我们可以来看 如果一个“傻乎乎”的编译器让我们的代码:char p[3]="abc"; extern char *p;通过了编译,我们运行时会出现什么呢?

此时对p[1]进行的取值操作运行步骤为:

1.  由于p声明为指针,编译器会用指针对象的“待遇”对待p,也就是对p解引操作(此时对p进行解引操作 取出来的值就是char类型的’a’);

2.  当然此时还不会出现什么错误,接下来编译器会认为它找到了”abc”字符串常量的首地址,并对此“地址”进行1个单位的偏移。

3.  接下来编译器会对这个已经偏移过的地址进行解引操作,Oh on! 这时杯具出现啦!因为对’a’进行1个单位的偏移后的地址进行解引谁也不会知道出现什么事。。。更杯具的事 你的程序还会带着这个神秘的值跑下去!

 

你可能感兴趣的:(浅议数组不等于指针)