1. 程式人生 > >數組不是指針

數組不是指針

nbsp 字符串 但是 字面量 size tor str urn 大小

作者:孫明琦
鏈接:https://zhuanlan.zhihu.com/p/24799071
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。

首先,數組名不是常量指針,從兩方面:

  1. 類型方面,數組的類型是type[size],和常量指針類型type* const不同
  2. 使用方面,sizeof(數組名)等於數組所有元素的大小,而不是sizeof(指針);對數組取地址,得到的指針進行加減,增減字節數是sizeof(數組);你可以用字符串字面量初始化一個字符數組,但是不能用常量指針來初始化一個字符數組。

其次,為什麽很多老師都說數組是常量指針

  1. 他們不了解C語言的類型系統和隱式轉換規則
  2. 他們怕下面的人聽不懂
  3. 他們解釋不清為什麽數組名不能進行賦值或者++之類的運算而指針可以

切入正題,我們從類型系統和隱式轉換規則來講:


  • 數組名的類型就是數組類型type[size] (參見Array declaration)
  • 對數組取址,得到的類型是指向數組的指針type(*)[size] (參見Member access operators)

  • 數組名在大部分情況下會隱式轉換為首元素指針右值,除了(參見 Implicit conversions)

    1. sizeof運算的時候
    2. 取址的時候
    3. 用字符串字面量初始化字符數組的時候
    4. 以及C11的_Alignof運算符(這個本文不考慮)

其他情況下都會發生數組到指針隱式轉換,比如你用方括號取值,如果方括號左邊是個數組,那麽數組會被隱式轉換為首元素指針右值,然後對這個值進行的解引用。(參見Member access operators)

更進一步,二維數組type[size1][size2],實際上就是元素類型是數組的數組,進行隱式轉換後得到的首元素指針類型是type(*)[size2],指向數組的指針,對這個指針加減,得到的也是數組的指針,對它解引用,得到數組。這一套過程,用那個什麽數組名是常量指針的說法,是解釋不來的。

最後出一個題:寫出程序輸出

typedef char(*AP)[5];
AP foo(char* p) {
    for (int i = 0; i < 3; i++) {
        p[strlen(p)] = ‘A‘;
    }
    return (AP)p+1;
}
int main() {
    char s[] = "FROG\0SEAL\0LION\0LAMB";
    puts(foo(s)[1] + 2);
}

這個題用數組名是指針那套理論是做不出來的。

數組不是指針