c - 使用单个指针访问二维数组

标签 c arrays pointers

像这样的代码有很多:

#include <stdio.h>

int main(void)
{
    int a[2][2] = {{0, 1}, {2, -1}};
    int *p = &a[0][0];

    while (*p != -1) {
        printf("%d\n", *p);
        p++;
    }
    return 0;
}

但是基于这个answer , 行为未定义。

N1570。 6.5.6 p8:

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

谁能详细解释一下?

最佳答案

基地址(指向第一个元素的指针)p 被赋值的数组是int[2] 类型。这意味着 p 中的地址只能在位置 *p*(p+1) 处合法地取消引用 ,或者如果您更喜欢下标表示法,p[0]p[1]。此外,p+2 保证是合法评估的地址,并且可与该序列中的其他地址,但被解除引用。这是过去地址。

您发布的代码通过取消引用 p 违反了一次过去的规则,一旦它传递了它所在数组中的最后一个元素。它所在的阵列支撑在另一个类似尺寸的阵列上,这与引用的正式定义无关。

也就是说,在实践中它是有效的,但正如人们常说的那样。 观察到的行为不是,也不应被视为定义的行为。仅仅因为它有效并不能说明它是正确的。

关于c - 使用单个指针访问二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25303647/

相关文章:

C 将大文件读入 char* 数组太慢

c++ - BLAS与CMake链接错误

c - 在 C 中,fopen/fread/fgets PID 是安全的吗?

Android:从自定义 ListView 中单击的按钮获取 ListView 项

java - 是否无法将 BigDecimal 值存储在一维数组中

arrays - 在 Rust 中,我可以在不对值进行硬编码的情况下实例化我的 const 数组吗?编译时评估?

c++ - C++ 禁止指针和整数的比较

c - 用旧内容重新定义宏/制作文件包含计数器

c++ - 使用指针访问类的私有(private)或 protected 数据

c++ - 使用指针对象的 std::vector。当 vector 超出范围时,有没有办法从 vector 中删除该项目?