《征服 C 指標》摘錄5:函數形參 和 空的下標運算子[]

來源:互聯網
上載者:User

標籤:

一、函數的形參的聲明

C 語言可以像下面這樣聲明函數的形參:

void func(int a[]){    // ...}

對於這種寫法,無論怎麼看都好像要向函數的參數傳遞數組。

可是,在 C 中是不能夠將數組作為函數的參數進行傳遞的。無論如何,在這種情況下,你只能傳遞指向數組初始元素的指標。

在聲明函數形參時,作為類型分類的數組,可以被解讀成指標。

void func(int a[]){}

可以被自動地解讀為

void func(int *a){}

此時,就算你定義了數組的元素的個數,也會被無視。

要點

只有在聲明函數形參的情況下,int a[] 和 int *a 才具有相同的意義。

 

下面是一個稍微複雜一點的形參聲明的例子:

void func(int a[][5])

a 的類型為“int 的數組(元素個數 5)的數組(元素個數不明)”,因此它可以解讀成“指向 int 數組(元素個數 5)的指標”。因此,上面的聲明本來的意思是:

void func(int (*a)[5])

要點

在下面聲明的形參,都具有相同的意義。

int func(int *a);  /* 寫法1 */
int func(int a[]);  /* 寫法2 */
int func(int a[10]); /* 寫法3 */

寫法 2 和 寫法 3 是寫法 1 的文法糖。

 

二、關於空的下標運算子[]

在 C 語言中,遇到以下情況,下標運算子[]可以將元素個數省略不寫。

對於這些情況,不同編譯器會有各自特別的解釋,所以不能作為普通的規則來使用。

(1)、函數形參的聲明

正如上節中說明的那樣,對於函數的形參,最外層的數組會被解讀成指標,即使定義了元素個數也會被無視。

(2)、根據初始設定式可以確定數組大小的情況

在下面的情況下,編譯器可以根據初始設定式來確定元素的個數,所以可以省略最外層數組的元素個數。

int a[] = {1, 2, 3, 4, 5};char str[] = "abc";double matrix[][2] = {{1, 0}, {0, 1}};char *color_name[] = {    "red",    "green",    "blue"};char color_name[][6] = {    "red",    "green",    "blue"};

注意:int a[]; 會報錯

在初始化 數組的數組 的時候,如果有初始設定式,貌似即使不是最外層的數組,編譯器也應該能夠確定其元素個數。可是,在 C 語言中,允許下面這樣不整齊的數組初始化,因此還是不能簡單地確認最外層數組以外的元素個數。

int a[][3] = { /* int a[3][3]的省略形式 */    {1, 2, 3},    {4, 5},    {6}};char str[][3] = { /* char str[3][5]的省略形式 */    "hoge",    "hog",    "ho"};

似乎可以考慮讓編譯器選擇一個最大值,但 C 的文法並沒有這麼做。

如果這麼做是為了排查程式員的編程失誤,那什麼沒有把上面“不整齊的數組”也規定為錯誤?對於這種現象,我至今百思不得其解(莫非只是因為疏忽?)。

順便說一下,在初始化上面這樣不整齊的數組的時候,沒有對應的初始設定式的元素會被初始化為 0。

(3)、使用 extern 聲明全域變數的情況

全域變數多個編譯單元(.c 檔案)中的某一個中定義,然後從其他代碼檔案通過 extern 進行聲明。

在定義的時候還是需要元素個數的,但是在使用 extern 進行聲明的時候,在串連的時候編譯器可以確定實際的數組大小,所以可以省略最外層數組的元素個數。

正如前面說明的那樣,只有在聲明函數形參的時候,數組的聲明才可以被解讀成指標。

像下面這樣進行全域變數聲明的時候,將數組和指標混在一起,除了程式不能正常運行外,編譯器通常也不會報告任何警告或者錯誤。這一點需要引起注意(如今的連結器,有時也會報錯)。

    file_1.c......中
        int a[100];
    file_2.c......中
        extern int *a;

 

補充: 聲明 和 定義

在 C 語言中,“聲明”在規定變數或者函數的實體的時候被稱為“定義”。

比如,像下面這樣聲明全域變數的行為,就是“定義”。

int a;

以下的 extern 的聲明,意味著“使在某處聲明的對象能夠在當前的地方使用”,因此它不是“定義”。

extern int a;

同樣地,函數的原型是“聲明”,函數的“定義”是指寫著函數的實際執行代碼的部分。

自動變數的情況下,區別定義和聲明是沒有意義的,因為此時聲明必然伴隨著定義。

 

《征服 C 指標》摘錄5:函數形參 和 空的下標運算子[]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.