使用单个指针访问二维数组 [英] Accesing a 2D array using a single pointer

查看:29
本文介绍了使用单个指针访问二维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有很多这样的代码:

#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;
}

但根据此答案,行为未定义.

But based on this answer, the behavior is undefined.

N1570.6.5.6 p8:

N1570. 6.5.6 p8:

当一个整数类型的表达式被加或减时从指针,结果具有指针操作数的类型.如果指针操作数指向数组对象的一个​​元素,数组足够大,结果指向一个元素偏移量原始元素使得下标的差异结果和原始数组元素等于整数表达式.换句话说,如果表达式 P 指向一个数组对象,表达式 (P)+N(等价于 N+(P))和 (P)-N(其中 N 的值为 n)分别指向第 i+n 个和数组对象的第 i 个元素,前提是它们存在.而且,如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向数组对象最后一个元素后的位置,如果表达式 Q 指向数组的最后一个元素对象,表达式 (Q)-1 指向数组的最后一个元素目的.如果指针操作数和结果都指向元素相同的数组对象,或数组的最后一个元素对象,评价不得产生溢出;否则,行为未定义.如果结果指向最后一个元素的数组对象,它不得用作一元的操作数* 被评估的运算符.

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 保证被合法地评估为地址,并且可比该序列中的其他地址,但可以 被取消引用.这是过去的地址.

The array who's base address (pointer to first element) p is assigned is of type int[2]. This means the address in p can legally be dereferenced only at locations *p and *(p+1), or if you prefer subscript notation, p[0] and p[1]. Furthermore, p+2 is guaranteed to be a legally evaluated as an address, and comparable to other addresses in that sequence, but can not be dereferenced. This is the one-past address.

您发布的代码在传递了它所在的数组中的最后一个元素后,通过取消引用 p 违反了过去规则.它所在的数组被另一个具有相似维度的数组支撑,这与引用的正式定义无关.

The code you posted violates the one-past rule by dereferencing p once it passes the last element in the array in which it is homed. That the array in which it is homed is buttressed up against another array of similar dimension is not relevant to the formal definition cited.

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

That said, in practice it works, but as is often said. observed behavior is not, and should never be considered, defined behavior. Just because it works doesn't make it right.

这篇关于使用单个指针访问二维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆