溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C之?dāng)?shù)組參數(shù)和指針參數(shù)(三十一)

發(fā)布時間:2020-06-25 04:24:19 來源:網(wǎng)絡(luò) 閱讀:3727 作者:上帝之子521 欄目:編程語言

        我們在前面講了在 C 語言中,數(shù)組參數(shù)會退化為指針。那么這是為什么呢?在 C 語言中只會以值拷貝的方式傳遞參數(shù),當(dāng)向函數(shù)傳遞數(shù)組時,不是將整個數(shù)組拷貝一份傳入函數(shù)而是將數(shù)組名看做常量指針傳數(shù)組首元素地址。

        那么當(dāng)初在設(shè)立 C 語言時,主要是用于 Unix 操作系統(tǒng),而 Unix 效率要求很高。所以 C 語言以高效作為最初設(shè)計目標(biāo):a> 參數(shù)傳遞的時候如果拷貝整個數(shù)組執(zhí)行效率將會大大下降;b> 參數(shù)位于棧上,太大的數(shù)組拷貝將導(dǎo)致棧溢出。函數(shù)調(diào)用棧是用一片內(nèi)存來存放的,如果棧溢出,那么函數(shù)調(diào)用將無法執(zhí)行,程序?qū)懒恕?/p>

        二維數(shù)組參數(shù)同樣也存在退化,它可以看做是一維數(shù)組,它中的每個元素是一維數(shù)組。二維數(shù)組參數(shù)中第一維的參數(shù)可以省略,如:void f(int a[5]) ==> void f(int a[]) ==> void f(int* a);  void g(int a[3][3]) ==> void g(int [][3]) ==> void g(int (*a)[3]);那么我們平時所說的一維數(shù)組作為參數(shù)時將會退化為一維指針,二維數(shù)組并不會退化為二維指針,而是退化為數(shù)組指針。那么什么樣的參數(shù)將退化為二維指針呢?我們總結(jié)了下面這張表

數(shù)組參數(shù)
等效的指針參數(shù)
一維數(shù)組:float a[5]
指針:float* a
指針數(shù)組:int* a[5]
指針的指針:int** a
二維數(shù)組:char a[3][4]
數(shù)組的指針:char(*a)[4]

        我們可以看出指針數(shù)組作為參數(shù)時才退化為二維指針。那么在 C 語言中無法向一個函數(shù)傳遞任意多的多維數(shù)組,必須提供除第一維之外的所有維長度;其中第一維之外的維度信息用于完成指針運算,N維數(shù)組的本質(zhì)是一維數(shù)組,元素是 N - 1 維的數(shù)組,對于多維數(shù)組的函數(shù)參數(shù)只有第一維是可變的。下來我么以代碼為例進行分析,代碼如下

#include <stdio.h>

void access(int a[][3], int row)
{
    int col = sizeof(*a) / sizeof(int);
    int i = 0;
    int j = 0;
    
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(*a) = %d\n", sizeof(*a));
    
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            printf("%d\n", a[i][j]);
        }
    }
    
    printf("\n");
}

int main()
{
    int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
    int aa[2][2] = {0};
    
    access(a, 3);
    access(aa, 2);
    
    return 0;
}

        我們看到在程序中我們在第25和26行分別定義了3*3,2*2的二維數(shù)組,但是 access 函數(shù)里參數(shù)的數(shù)組參數(shù)第二維指定是3。所以我們在第29行調(diào)用這個函數(shù)會報錯,因為類型不匹配。我們來看看編譯結(jié)果

C之?dāng)?shù)組參數(shù)和指針參數(shù)(三十一)

        我們看到它報警告了,也就是說這個程序雖然通過編譯了,但是它允許的結(jié)果是不確定的。我們看到我們定義的 aa 數(shù)組是 2*2 的,但是它打印出了6個數(shù),也就是當(dāng)成 2*3 的了。所以我們這樣調(diào)用是不對的。

        下來我們看個三維數(shù)組的代碼,代碼如下

#include <stdio.h>

void access_ex(int b[][2][3], int n)
{
    int i = 0;
    int j = 0;
    int k = 0;
    
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("sizeof(*b) = %d\n", sizeof(*b));
    
    for(i=0; i<n; i++)
    {
        for(j=0; j<2; j++)
        {
            for(k=0; k<3; k++)
            {
                printf("%d\n", a[i][j][k]);
            }
        }
    }
    
    printf("\n");
}

int main()
{
    int aa[2][2] = {0};
    int b[1][2][3] = {0};
    
    access_ex(b, 1);
    access_ex(aa, 2);
    
    return 0;
}

        我們在 access_ex 函數(shù)里指定的是第二維是2,第三維是3。但是我們定義的數(shù)組 aa 不是這樣的,我們看看編譯結(jié)果C之?dāng)?shù)組參數(shù)和指針參數(shù)(三十一)

        我們看到第二個編譯出的結(jié)果也是不確定的。通過本節(jié)對數(shù)組參數(shù)和指針參數(shù)的學(xué)習(xí),總結(jié)如下:1、C 語言中只會以值拷貝的方式傳遞參數(shù),并且數(shù)組參數(shù)必然退化為指針;2、多維數(shù)組參數(shù)必須提供除第一維之外的所有維長度;3、對于多維數(shù)組的函數(shù)參數(shù)值第一維是可變的。


         歡迎大家一起來學(xué)習(xí) C 語言,可以加我QQ:243343083。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI