根据C++ 语言标准[expr.add], 7.6.6/4,如果我们有一个指向某个元素数组p的i第-个元素的指针n,并且有一个整数值j,那么该指针p + j指向i + j-th 元素 if if 0 <= i + j <= n; 否则,程序的行为是未定义的。
所以下面代码的行为是未定义的:
int arr[2];
int *pi = arr + 3; //UB
但是,如果我们“超越”二维数组的子数组会发生什么?例子:
int arr[2][2];
int (*p)[2] = arr;
int *pi = *p;
pi = pi + 3; //UB?
指针p指向数组的第一个元素arr,即 到类型为 的两个元素的数组int。指针pi指向类型为 的两个元素组成的数组的第一个元素int。在表达式中,尽管我们仍在数组内部,但pi + 3我们走出了两个 type 元素的数组。intarr
问题 1.pi + 3从语言标准的角度来看,表达是否是未定义的行为?
问题 2. 以下代码是否正确:
int arr2[1];
int *pi2 = arr2 + 1;
*pi2; //OK?
我对字符串感兴趣*pi2;。
考虑到 (1),标准明确指出这是未定义的行为。
子数组在内存中是连续的这一事实意味着这很可能在实践中起作用,但这仍然是未定义的行为。
关于第 (2) 种情况尚不完全清楚,但无论如何最好不要这样做。
这里建议这种取消引用与取消引用空指针具有相同的状态。关于这一点,如果不使用结果或仅从中获取地址,是否允许也不清楚。
一个二维数组就是2个数组合一,也就是一个序列。
对于数组
int arr[2][2],arr[0] 是指向第一个元素的指针。数组本身有4元素,所以很正常,因为它
p指向第四个元素问题 2 - 不。数组中只有 1 个元素。
问题 1 - 数组是一块分配的,就像它是一个普通的指针一样。
只有你一开始就错了:
0 <= i + j <= n.n对于元素数组0 <= i + j < n。