謠言終結:陣列名並不是乙個指標,也不是指標常量,它只是乙個符號。但是很多資料為了方便理解把陣列名當作指標常量來對待,這就說明乙個問題,陣列名可以代表一首個元素的位址,但是陣列名不能進行算術運算
程式:
1 #include2輸出結果:using
namespace
std;34
intmain()5;
7 cout/
i8 cout<
ii9 cout<1
/iii10 cout<
/iv11
return0;
12 }
引用《c和指標》p141中的理論:
在c中, 在幾乎所有使用陣列的表示式中,陣列名的值是個指標常量,也就是陣列第乙個元素的位址。 它的型別取決於陣列元素的型別: 如果它們是int型別,那麼陣列名的型別就是「指向int的常量指標「。
對於ii 和 iv 則是特殊情況,在《c和指標》p142中說到,在以下兩中場合下,陣列名並不是用指標常量來表示,就是當陣列名作為sizeof操作符和單目操作符&的運算元時。 sizeof返回整個陣列的長度,而不是指向陣列的指標的長度。 取乙個陣列名的位址所產生的是乙個指向陣列的指標,而不是乙個指向某個指標常量的指標。
所以&a後返回的指標便是指向陣列的指標,跟a(乙個指向a[0]的指標)在指標的型別上是有區別的,可以這麼理解
a == &a[0]
&a+1 == a + sizeof(a) 程式中乙個指向int的指標位址佔4位元組,陣列中有四個元素 0x30 + 4*4 =0x40
以下為中興內部資料:
陣列和指標之區別列表
以下面**為例:
char *p;
char array[100];
說明如下:
1 因為任何型別的指標變數(針對我們用的32位cpu而言)的長度為4,故sizeof(p)為4;但sizeof(array)為100. 這一點是由編譯器在編譯階段確定的,即編譯器對於sizeof(p)是直接以常數4替換的,對sizeof(array)是直接以100替換的。由此也可知道,用sizeof不但可讀性、可擴充套件性好,而且絲毫不降低**效率(包括時間和空間上的)。
2 sizeof(*p)和sizeof(array[0])則相同,都為1
3 設n為一整數,p[n]等價於*(p + n),array[n]等價於*(array + n),即不管是指標還是陣列,都有這兩個等效的表示方法
4 陣列形式的形參本質上是指標。後面詳述。
5 array在許多情況下代表第乙個元素的位址,即&array[0]。例如
p = array; /* 等價於 p = &array[0]; */
fun(array); /* 等價於 p = fun(&array[0]); */
這個現象讓許多人得出「陣列即指標」的錯誤結論。
6 但陣列畢竟是陣列,當array取sizeof或位址時,array代表整個陣列,這時它不能替換為 &array[0]。例如:
sizeof(array)為100,而 sizeof(&array[0])等於sizeof(char*);
&array表示整個陣列的位址,它可以賦值給乙個指向同型別陣列(即100個char變數組成的陣列)的指標。而 &(&array[0])表示什麼?什麼也不是,根本不合語法(編譯不過)。
使用陣列名時,前面加不加&符號有何區別?
void main()
上面的**中,b=a; c=&a;二者都獲得的是陣列a的首位址,所以b與c的值相同。
但從本質上說,a和&a的型別是不同的:在b=a中,a等價於&a[0],所以此處是當作char*(即指向char變數的指標)型別使用的;而&a表示陣列a的位址,所以其型別是「指向含4個char元素的陣列的指標」。
看下面的例子(vc下編譯的結果),就說明問題
void main()
由於c指向的是含20個char元素的陣列,故c+1其實是對c的值加了20,可作如下測試:
printf(「%u\n」, (unsigned int)(c + 1) - (unsigned int)c);
觀察列印為20.
但下面的**編譯則無任何問題,因為b c為void*,可接收任何型別的指標的賦值
void main()
指向陣列的指標的應用
指向陣列的指標應用不多,但偶爾也會碰到,下舉一例(部門人員碰到的):
char a[10][20], b[10][20];
…if (..)
else
兩分支**除a b之分外,完全相同。這種**浪費空間,且不易維護——兩處要同步更改。
借用陣列指標,可以這樣:
char (*p)[10][20];/*括號不能省略,否則p變成了指標構成的陣列*/
if (..)
else
(*p)[i][j]… /* 僅乙份** */
或者這樣:
char (*p)[20];/*括號不能省略,否則p變成了指標構成的陣列*/
if (..)
else
p[i][j]… /* 僅乙份** */
陣列形式的形參本質上是指標
void fun1(char v[100])
完全應該這樣理解:
void fun1(char *v)
1 fun1中v++是合法的。
2 sizeof(v)的值不是100,而是等於sizeof(char*),即4
void fun1(char v[100])與void fun1(char *v)以及void fun1(char v)是完全等價的寫法。我們應按void fun1(char *v)來理解,編譯器也都是按這種方式體現的意義來編譯的。寫**時,從語法上說可以隨便用哪種形式。但是從習慣上來說,如果設計該函式時是打算接受上層函式(即呼叫者)的陣列名作為實參,則通常定義為陣列形式(char陣列除外);如果設計該函式時是打算接受上層函式(即呼叫者)的某乙個變數的位址作為實參,則通常定義為指標形式。
指標與陣列,指標陣列 陣列指標
int a 10 print n a p,a p a,a print n a 1 p,a 1 p a 1,a 1 a做乙個指標,步長為4,指向乙個元素,a做乙個指標,步長為40,指向乙個維陣列 int b 3 4 print n b p,b p,b p b,b,b print n b 1 p,b 1...
指標陣列與陣列指標
1.指標陣列 指標陣列中每乙個元素都是乙個指標,也既是存放字串的首位址。所以指標陣列適合處理若干個長度不等的字串。定義的一般形式為 型別說明符 指標陣列名 陣列長度 例如 int p 3 宣告乙個陣列,指標陣列p,由3個int型別指標變數元素組成 從運算子的優先順序分析,由於 的優先順序大於 所以p...
指標陣列與陣列指標
呵呵,實在是厭倦了繞口的解釋。指標陣列,故名思義,就是指標的陣列,陣列的元素是指標 陣列指標,同樣,就是直想陣列的指標。簡單舉例說明 int p 2 首先宣告了乙個陣列,陣列的元素是int型的指標。int p 2 宣告了乙個指標,指向了乙個有兩個int元素的陣列。其實這兩種寫法主要是因為運算子的優先...