在C语言中访问数组

3

关于C语言中的二维数组有几个问题。

  1. If I create an two dimensional array:

    int c[5][25];
    

    Then create a pointer to the beginning of the array:

    int *p = c;
    

    Edit: Changing the second line to:

    int (*p)[25] = c;
    

    worked. Will this still let me access the array in the following questions?

  2. Would *(c+26) access the array at c[1][1]?

    I know in a one dimensional array like the following:

    double *p;
    double balance[10];
    
    p = balance;
    

    *(balance + 4) is the same as balance[4], but wasn't sure if the memory is assigned "back to back" for a 2D array.

  3. Can you access c[1][1] by doing something like c[2][-24]?

    Would be an odd way to do it, but I couldn't find anything addressing that specific scenario.

  4. Would you be able to access c[1][1] by the statement p[1][1]?

    My guess would be no, since p is a pointer array.

  5. Saw these examples a while ago and wrote them down, but don't remember if they are correct or not:

    1[c[1]];
    26[p];
    

    Would either of those be equivalent to c[1][1]?

我知道很多这方面的内容都很基础,但我在网上找不到针对这些具体情况的资料。

谢谢!


错误信息:'initializing' :无法将 'int [5][25]' 转换为 'int **'。 - user3421751
在某些情况下,如果按照内存序列访问,c[0][24] 可能会被 c[1][0] 所跟随,但并没有什么保证。我想编译器可以自由选择如何存储这些矩阵,因此做出假设可能会导致未定义的行为。 - Havenard
在格式*(c+27)中,访问c[1][1]的等效符号是什么? @Havenard - user3421751
请注意,这仅在您将其声明为静态矩阵时才可能实现。通常,矩阵是作为指向数组的指针数组构建的,以便可以将它们作为参数传递给其他函数。这就是main()中参数argv的情况。如果以这种方式进行,则无法像那样按顺序访问值。 - Havenard
@MattMcNabb 是的,但我们这里不是在谈论数组,对吧? - Havenard
显示剩余3条评论
1个回答

2

问题:1)我是否正确声明了第二行?

回答:不,你没有。正确的方式应该是:

int (*p)[25] = c;

问题: 2.) *(c+26)会访问c[1][1]的数组吗?

答案: 不会。 *(c+26)c[26]相同。在您的情况下,这将导致未定义的行为,因为数组索引26对于您的数组无效。

问题: 3.) 是否可以通过类似c[2][-24]的方式访问c[1][1]

答案: 不可以。使用超出范围的数组索引将导致未定义的行为。

编辑 尽管-24似乎是一个超出边界的数组索引,但使用c[2][-24]似乎与使用c[1][1]相同。我撤回了我的第一个答案。

问题: 4.) 通过语句p[1][1],您能够访问c[1][1]吗?

答案: 如果您按照我所做的那样更改p的声明方式,就可以。

问题: 1[c[1]];26[p];

它们中的任何一个是否等同于c[1][1]?

答案: 1[c[1]]等同于c[1][1]26[p]等同于p[26],但无论p是按照您的方式定义还是按照我的方式定义,它都不等同于c[1][1]


当声明int ** p = c时,会出现错误:'initializing' : cannot convert from 'int [5][25]' to 'int **'。然而,正如Tejas Patel向我展示的那样,int (*p)[25] = c不会引发错误。以这种方式声明会影响您对我的问题的回答吗? - user3421751
使用您的输入和Havenard的输入,在问题2中,*(c+26)将在矩阵为静态时导致c[1][1],否则将抛出异常。@R Sahu @Havenard - user3421751
@user3421751 c+26c[26] 是相同的。*(c+26)*(c[26]) 也是相同的,这与 c[26][0] 相同。正如您所看到的,这显然是越界访问。 - R Sahu
Q3:它真的越界了吗?它在已经声明的对象内部,因此地址将为(char*)&c + 2 * sizeof(c[0]) - 24 * sizeof(c[0][0]) = (char*)&c + 2 * 25 * sizeof(int) - 24 * sizeof(int)(char*)&c + 1 * sizeof(c[0]) + 1 * sizeof(c[0][0])=(char*)&c + 1 * 25 * sizeof(c[0][0]) + 1 * sizeof(c[0][0]),这两个都使得(char*)&c + 26 * sizeof(int)。显然,这在c的范围内。 - glglgl
@glglgl 感谢您的解释。我已经在我的答案中添加了一个编辑。 - R Sahu
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接