? ? ? ? 對于一個數組,如 int a[4];? 如果只是給出數組名a,編譯器不知道該取該數組的第幾個元素,因此編譯器不會自動取值,而是返回該數組的首地址(第一個元素的地址)。其實,數組名a就是數組本身,并不是數組的首地址,只是當只是給出了數組名a的時候,而又同時需要取值時,數組名a才會被隱式轉換為該數組的首地址。因此,int *p=&a;和int *p=a的效果是一樣的,只是前者是顯示的,而后者是隱式的。
? ? ? ? 例如,數組名a在以下情況就不是數組的首地址的:1.sizeof(a)? 得到的結果為16,即a是一個數據類型,長度為4的int數組類型,是數組本身,沒有進行隱式轉換;2.&a? ?表示數組的首地址,并不是指針的指針,而是指向長度為4的int數組的指針,一個常量指針,其指針類型為: in (*)[4],此處4不能省略,因為"指向不確定長度的指針" 是沒有意義的,編譯器若不知道該指針指向的類型,就無法編譯指針的加減法運算(指針指向類型的長度未知,加減法的位移量就未知)。int (*p)[4]=&a; 定義一個指針p,并初始化為數組a的地址,等價于:int *p=a;? 3. C++中取引用時a也不是指針。
char* test2()
{char p[] = "hello world";return p;
} //錯誤代碼char* test2()
{char *p = "hello world";return p;
}
? ? ? ? 對于以上代碼,char p[ ] = "hello world";與char *p?= "hello world";是有著本質區別的,前者首先定義了一個數組p,且用后面的字符串初始化該數組p,數組p的作用域為該函數內部,數組生存期和作用域與聲明方式相關。而且該數組沒有 const 資格符,字符串內容是可以修改的。這個數組首地址不能在函數中返回(因為函數結束的同時,p已經被銷毀了),除非聲明用了 static 。對于后者,聲明一個指針。字符串字面量本身成為一個靜態存儲期的數組,它再隱式轉換成指針以初始化聲明的指針。這個字符串是不可修改的(修改會導致未定義行為,數組本身可放在只讀內存區)。它的首地址可以在函數中返回。
? ? ? ? 對于函數名,其原理與上面基本相同。函數名其實并不是函數的入口地址,只是被隱式轉換了。函數名只是函數本身。