C語言中對于下面的兩種情況,是否相同呢?
char a[] = "abcdefg";---------------1
char *p = "abcdefg";-----------------2
在談到這些區別時,應該先談一下計算機中對變量是如何存儲的。從編譯原理中我們知道,對于所有的變量他都會影射到一個符號表中。為了簡化,這里給出一種最簡單的便于理解的符號表:
表1 一個簡單的符號表示例
以上表格中a代表一個變量,0xffaa則為變量a的內容的存儲地址;p代表另一個變量,0xffcc為變量p的內容的存儲地址。對于數組型的變量和指針型的變量,其地址代表的含義不同。
對于數組a:
這個0xffaa地址就是其存放數組內容的首地址了。對于a[i]的引用步驟如下:
步驟一、取出i的值,將他與0xffaa相加;
步驟二、取出為(0xffaa+i)中的內容。
對于指針p:
這個0xffcc地址就是中存放的不是字符串的內容,而是一個地址,這個地址才是字符串的首地址,對p[i]或者用指針表示*(p+i)的應用步驟如下:
步驟一、取出0xffcc地址中的內容,例如為0xffdf;
步驟二、取出地址0xffdf中的內容。
數組和指針的對比如下圖:
下面是在VC6.0下作的一個試驗,通過這個試驗大家可以看到,雖然同過[]和通過*引用都一樣,但在內部處理的方法是不一樣的。
#include "stdafx.h"
#include "stdio.h"
int main(int argc, char* argv[])
{
int a[3]={1,2,3};
int *p =a;
printf("a:%d,&a:%d,a[0]:%d,*a:%d,p:%d,&p:%d,*p:%d,p[0]:%d",a,&a,
a[0],*a,p,&p,*p,p[0]);
return 0;
}
輸出結果:
a:1310580,&a:1310580,a[0]:1,*a:1,p:1310580,&p:1310576,*p:1,p[0]:1。
由上面的分析可知,如果在一個文件中定義了一個數組int maychar[100],那么下面的聲明就是完全錯誤的。
extern int *maychar;
這樣的話,在引用時他就會按照指針的方法來引用數組。正確的聲明應該是exter int maychar[];這里數組的大小并不重要。下面將指針與數組的區別用表格的形式列出如下:
指針 | 數組 |
保存數據的地址 | 保存數據 |
間接訪問數據 | 直接訪問 |
通常用于動態數據結構 | 通常用于存儲固定數目數據類型相同的元素 |
相關操作malloc(),free()等 | 隱式分配和刪除 |
同常指向匿名數據 | 自身即為數據名 |
表2 指針與數組的區別
還要提醒一點的就是:
char a[] = "abcdefg";---------------數組內容能修改(字符數組)
char *p = "abcdefg";-----------------內容不能修改(字符串常量)
在ANSI C中,初始化指針是所創建的字符串時常量,被定義為只讀,如果試圖通過指針修改這個字符串的值,程序就會出現為定義的行為。