簡體   English   中英

在 C 中增加 2D 數組

[英]Incrementing a 2D array in C

我剛剛開始學習 C 中的二維數組,我遇到了這段代碼,其中二維數組像這個++array一樣直接預先遞增。

我試圖在 3 個不同的地方打印矩陣(初始化之后,在函數中,在函數調用之后的函數中,在函數調用之后的主函數中),但我無法理解預增量是如何工作的。

我還注意到a[1][1]++反映在原始矩陣中(8 增加到 9),但沒有其他反映。

#include <stdio.h>
void printmatrix(int[3][3]);
int function(int a[][3])
{
    int i,j;
    ++a; //what does this do?
    printf("In function...\n");
    printmatrix(a);
    a[1][1]++;
}
void printmatrix(int a[3][3])
{
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
printf("Initially...\n");
printmatrix(a);
function(a);
printf("In main...\n");
printmatrix(a);
printf("a[2][1]-a[1][2]=%d",a[2][1]-a[1][2]);
return 0;
}

我得到的輸出是,

Initially...
1 2 3 
4 5 6 
7 8 9 

In function...
4 5 6 
7 8 9 
32765 0 0 

In main...
1 2 3 
4 5 6 
7 9 9 

a[2][1]-a[1][2]=3

此外,當我在 main 函數中聲明數組后嘗試預先遞增數組時,出現以下錯誤。

int a[3][3]={1,2,3,4,5,6,7,8,9};
a++;
main.c: In function ‘main’:
main.c:28:2: error: lvalue required as increment operand
 a++;

你不能增加一個數組,這是沒有意義的。 你可以增加一個指針。 指針和數組是兩種不同的東西。

++a; //這是做什么的?

這會增加一個指針,因為a是一個指針。 盡管它聲明為int a[][3] ,但它不是二維數組。

為什么是指針而不是數組? 因為它是一個函數參數。 函數參數不能是數組。 你可以用方括號聲明它,但它仍然不會是一個數組。 它的含義與int (*a)[3]完全相同——僅當它是函數參數時。 printmatrix也是如此。 這很重要

它是一個指向一維數組的指針,它是二維數組的第一個元素,也就是數組的數組。 增量發生后,它開始指向同一數組的第二個元素。 如果您將 2D 數組視為矩陣,它現在指向矩陣的第二行。 這就是增加指針的作用。 如果它之前指向數組的第n個元素,那么它將指向之后的第n+1個元素(這個特定數組的元素是一維數組,也就是行)。

這使得在printmatrix(a);中發生的打印printmatrix(a); 未定義的行為 a現在指向 2D 數組的第二個元素,但printmatrix不知道它,並且打印時好像它前面還有 3 行。

此外,當我在 main 函數中聲明數組后嘗試預先遞增數組時,出現以下錯誤。

沒錯,因為在maina是一個數組,而不是一個指針。 您不能增加數組。

我剛剛開始學習 C 中的二維數組,我遇到了這段代碼,其中二維數組像這個++array一樣直接預先遞增。

不,你沒有。 至少不是在我知道的任何 C 編譯器都會接受的程序中。 數組通常包含可修改的元素,但整個數組不是可修改的單元。

在這個功能...

 int function(int a[][3]) { int i,j; ++a; //what does this do? printf("In function...\\n"); printmatrix(a); a[1][1]++; }

...雖然參數a使用數組語法表示,但它實際上是一個指針,而不是一個數組。 這是 C 的一個怪癖,盡管它與圍繞數組的其他 C 語義非常一致。 函數簽名等價於...

int function(int (*a)[3])

...,它將a聲明為指向 3 個int數組的指針。 因此,其中的++a具有其正常效果:它計算一個指向*a之后的下一個int[3]的指針,並更新a以指向該指針。

現在考慮main()

 int main() { int a[3][3]={1,2,3,4,5,6,7,8,9}; printf("Initially...\\n"); printmatrix(a); function(a); // [...]

main() ,標識符a指定一個二維數組,但有幾個值得注意的例外,它出現在表達式中的任何地方,它都會被轉換為指向其第一個元素的指針。 這樣的指針正好具有function()對其參數所期望的類型,因此函數調用就可以了。

請注意,C 函數調用具有嚴格的按值傳遞語義。 該函數接收它自己的該指針的副本,因此它所做的更改不會影響main()的指針值(它沒有持久存儲),更不用說派生它的數組了。

此外,當我在 main 函數中聲明數組后嘗試預先遞增數組時,出現以下錯誤。

 int a[3][3]={1,2,3,4,5,6,7,8,9}; a++;

正如我已經寫過的,整個數組是不可修改的。 但是,編譯器生成的診斷消息有點偏離。 該片段中的a是一個左值。 但它不是可修改的左值,這是操作數的前置和后置運算符所要求的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM