[英]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 函數中聲明數組后嘗試預先遞增數組時,出現以下錯誤。
沒錯,因為在main
, a
是一個數組,而不是一個指針。 您不能增加數組。
我剛剛開始學習 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.