二维数组可以被视为连接的一维数组吗?
考虑以下代码片段:
int a[25][80]; a[0][1234] = 56; int* p = &a[0][0]; p[1234] = 56;
问题:代码是否访问数组超出其范围,导致未定义的行为?
答案:是的,第 2 行和第 4 行都表现出未定义的行为。
在 C 中,数组索引本质上是指针算术。当访问 a[i][j] 时,编译器有效地将其转换为 *(a[i] j)。类似地,p[i] 引用 *(p i)。
在这种情况下,数组 a 的维度为 25 x 80。数组的第一行 a[0] 包含 80 个元素(范围为a[0][0] 到 a[0][79]) 并分配在连续的内存位置。
通过访问a[0][1234],代码尝试访问第一行中索引 1234 处的元素,尽管 a[0] 仅包含 [0, 79] 范围内的元素。这是越界并触发未定义的行为。
相同的逻辑适用于第 4 行。虽然 p 指向 a[0] 的第一个元素,但数组的尺寸仍然为 25 x 80。访问 p[ 1234] 本质上是一个越界指针算术运算,再次导致未定义的行为。
此外,正如 Language Lawyer 在注释中,使用 constexpr 的类似代码片段将无法编译,因为编译器在常量表达式中检测到此类未定义的行为:
constexpr int f(const int (&a)[2][3]) { auto p = &a[0][0]; return p[3]; } int main() { constexpr int a[2][3] = { 1, 2, 3, 4, 5, 6, }; constexpr int i = f(a); }
这可以正确编译,因为使用 constexpr 访问 p[3] 会触发编译器检测未定义的行为并抛出错误。
以上是使用指针算术访问超出其范围的 2D 数组元素是否会导致未定义的行为?的详细内容。更多信息请关注PHP中文网其他相关文章!