目前已在论坛上用C负阵列上的其他问题/答案,但我会要求回答这些对于32位编译器: 如果我们有一个数组定义int test_array[5] = {1,2,3,4,5};
负数组索引
那应该下列语句返回 test_array[20]
,test_array[-2]
,test_array[-32764]
,test_array[4294967700]
(值比32位可以容纳更大),*(a-32764)
等
该编译器力的情况下,指数要返回任何固定值超出其宣称的范围?
目前已在论坛上用C负阵列上的其他问题/答案,但我会要求回答这些对于32位编译器: 如果我们有一个数组定义int test_array[5] = {1,2,3,4,5};
负数组索引
那应该下列语句返回 test_array[20]
,test_array[-2]
,test_array[-32764]
,test_array[4294967700]
(值比32位可以容纳更大),*(a-32764)
等
该编译器力的情况下,指数要返回任何固定值超出其宣称的范围?
访问数组超出范围导致未定义行为(UB)。
-ve
索引不是有效的索引并导致未定义的行为。
一个未定义的Bheavior意味着任何事情都可以直接发生,如果幸运的话,你的程序将崩溃并且检测到问题,如果你不走运,代码一直工作得很好,并且有一天所有地狱都会崩溃。
因此,请务必避免编写任何导致未定义的行为的代码。
在索引超出其声明范围的情况下,编译器是否强制返回任何固定值?
NO
程序员必须照顾这。该标准不需要编译器给你提供任何指示/警告。标准只是将其定义为UB。
另外的标准识别所有下列情况导致未定义行为:一个指针的
- 加法或减法成,或者刚好超出,阵列对象和一个整数型产生的结果的确不要指向或超出相同的数组对象。
- 将指针加入或减去一个指向数组对象或整数类型的指针会产生一个结果,该结果仅指向数组对象之外,并用作被评估的
unary * operator
的操作数。- 数组下标超出范围,即使某个对象明显可以使用给定的下标进行访问(如给出声明
int a[4][5]
的左值表达式a[1][7]
)。
因为您正在访问数组越界,所以它是不确定的行为。
然而,负指数并不一定意味着未定义的行为。下面的代码被很好地定义:
int test_array[5] = {1,2,3,4,5};
int *p = test_array + 1;
int i = p[-1];//i now has the value 1
这等效于:外部的阵列是Undefined Behaviour
int i = *(p-1);
访问的元素。
此外,使指针指向数组之外的元素(除了(不存在的)one-past-the-last外)也是Undefined Behavior。访问过去的最后一个是未定义的行为(指针存在可以)
int arr[42] = {0};
int *ptr = arr;
ptr += 41; /* ok, ptr points to the last element of arr */
*ptr; /* ok */
ptr += 1; /* ok, ptr points to one-past-the-last */
*ptr; /* UB */
ptr += 1; /* UB */
ptr = arr;
ptr -= 1; /* UB */