简体   繁体   English

在 C 中增加 2D 数组

[英]Incrementing a 2D array in C

I have just started learning 2D arrays in C and I came across this code where a 2D array is directly pre-incremented like this ++array .我刚刚开始学习 C 中的二维数组,我遇到了这段代码,其中二维数组像这个++array一样直接预先递增。

I tried to print the matrix in 3 different places(After initializing, in function after increment, in main function after function call), but I can't understand how the pre-incrementation works.我试图在 3 个不同的地方打印矩阵(初始化之后,在函数中,在函数调用之后的函数中,在函数调用之后的主函数中),但我无法理解预增量是如何工作的。

I also noticed that a[1][1]++ is reflected in the original matrix(8 is incremented to 9) but nothing else.我还注意到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;
}

The output that I got is,我得到的输出是,

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

Also when I tried to pre-increment the array after declaring it in the main function I got the following error.此外,当我在 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++;

You cannot increment an array, that makes no sense.你不能增加一个数组,这是没有意义的。 You can increment a pointer.你可以增加一个指针。 Pointers and arrays are two different things.指针和数组是两种不同的东西。

++a; ++a; //what does this do? //这是做什么的?

This increments a pointer , because a is a pointer.这会增加一个指针,因为a是一个指针。 Although it is declared as int a[][3] , it is not a 2D array.尽管它声明为int a[][3] ,但它不是二维数组。

Why is it a pointer and not an array?为什么是指针而不是数组? Because it is a function parameter.因为它是一个函数参数。 A function parameter cannot be an array.函数参数不能是数组。 You can declare it with square brackets, but it still won't be an array.你可以用方括号声明它,但它仍然不会是一个数组。 It means exactly the same thing as int (*a)[3] — only if it is a function parameter.它的含义与int (*a)[3]完全相同——仅当它是函数参数时。 In printmatrix too.printmatrix也是如此。 This is important .这很重要

It is a pointer to a 1D array, which is the first element of a 2D array aka an array of arrays.它是一个指向一维数组的指针,它是二维数组的第一个元素,也就是数组的数组。 After the increment takes place, it starts pointing to the second element of the same array.增量发生后,它开始指向同一数组的第二个元素。 If you think of your 2D array as a matrix, it now points to the second row of the matrix.如果您将 2D 数组视为矩阵,它现在指向矩阵的第二行。 That's what incrementing a pointer does.这就是增加指针的作用。 If it pointed to the n th element of an array before, it will point to the n+1 th element afterwards (and elements of this particular array are 1D arrays, aka rows).如果它之前指向数组的第n个元素,那么它将指向之后的第n+1个元素(这个特定数组的元素是一维数组,也就是行)。

This makes printing that happens in printmatrix(a);这使得在printmatrix(a);中发生的打印printmatrix(a); undefined behaviour .未定义的行为 a now points to the second element of a 2D array, but printmatrix has no idea about it, and prints as if there are still 3 rows ahead of it. a现在指向 2D 数组的第二个元素,但printmatrix不知道它,并且打印时好像它前面还有 3 行。

Also when I tried to pre-increment the array after declaring it in the main function I got the following error.此外,当我在 main 函数中声明数组后尝试预先递增数组时,出现以下错误。

That's right, because in main , a is an array, not a pointer.没错,因为在maina是一个数组,而不是一个指针。 You cannot increment an array.您不能增加数组。

I have just started learning 2D arrays in C and I came across this code where a 2D array is directly pre-incremented like this ++array .我刚刚开始学习 C 中的二维数组,我遇到了这段代码,其中二维数组像这个++array一样直接预先递增。

No, you didn't.不,你没有。 At least not in a program that any C compiler I know would accept.至少不是在我知道的任何 C 编译器都会接受的程序中。 Arrays often contain modifiable elements, but whole arrays are not modifiable units.数组通常包含可修改的元素,但整个数组不是可修改的单元。

In this function ...在这个功能...

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

... although parameter a is expressed using array syntax, it is in fact a pointer, not an array. ...虽然参数a使用数组语法表示,但它实际上是一个指针,而不是一个数组。 This is a quirk of C, though it works out pretty consistently with other C semantics around arrays.这是 C 的一个怪癖,尽管它与围绕数组的其他 C 语义非常一致。 The function signature is equivalent to ...函数签名等价于...

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

..., which declares a as a pointer to an array of 3 int s. ...,它将a声明为指向 3 个int数组的指针。 Thus, the ++a within has its normal effect: it computes a pointer to the next int[3] following *a and updates a to point to that.因此,其中的++a具有其正常效果:它计算一个指向*a之后的下一个int[3]的指针,并更新a以指向该指针。

Now consider main() :现在考虑main()

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

In main() , identifier a designates a 2D array, but with a couple of notable exceptions, wherever it appears in an expression, it is converted to a pointer to its first element.main() ,标识符a指定一个二维数组,但有几个值得注意的例外,它出现在表达式中的任何地方,它都会被转换为指向其第一个元素的指针。 Such a pointer has exactly the type that function() expects for its parameter, so the function call is just fine.这样的指针正好具有function()对其参数所期望的类型,因此函数调用就可以了。

Note well that C function calls have strictly pass-by-value semantics.请注意,C 函数调用具有严格的按值传递语义。 The function receives its own copy of that pointer, so changes it makes do not affect the pointer value in main() (which has no enduring storage) much less the array from which it was derived.该函数接收它自己的该指针的副本,因此它所做的更改不会影响main()的指针值(它没有持久存储),更不用说派生它的数组了。

Also when I tried to pre-increment the array after declaring it in the main function I got the following error.此外,当我在 main 函数中声明数组后尝试预先递增数组时,出现以下错误。

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

As I wrote already, whole arrays are not modifiable.正如我已经写过的,整个数组是不可修改的。 The diagnostic message produced by your compiler is a bit off, however.但是,编译器生成的诊断消息有点偏离。 The a in that fragment is an lvalue.该片段中的a是一个左值。 But it is not a modifiable lvalue, which is what the pre- and post-increment operators require for an operand.但它不是可修改的左值,这是操作数的前置和后置运算符所要求的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM