C语言中的负数数组索引

3
在论坛中,已经有其他关于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)
当索引超出其声明范围时,编译器是否强制返回任何固定值?
3个回答

14

由于您正在访问超出数组范围的内容,因此这是未定义行为。

然而,负索引并不一定意味着未定义行为。以下代码是定义良好的:

int test_array[5] = {1,2,3,4,5};
int *p = test_array + 1;
int i = p[-1];//i now has the value 1

这等同于:

int i = *(p-1);

6

访问数组超出其边界会导致未定义行为(UB)
-ve索引不是有效索引,会导致未定义行为。

未定义行为意味着可以发生任何事情,如果你很幸运,程序会崩溃并检测到问题,如果你很不幸,代码一直运行良好,但有一天所有的问题都爆发了。
因此,始终避免编写任何导致未定义行为的代码。

如果索引超出其声明范围,编译器是否强制返回任何固定值?


程序员必须自己处理这个问题。标准不需要编译器为此给出任何指示/警告。标准只将其定义为未定义行为

此外,标准确定以下所有情况都会导致未定义行为

  • 将指针加或减一个整数类型的值,使其进入或刚好超出数组对象,并产生一个不指向相同数组对象或刚好超出该数组对象的结果。
  • 将指针加或减一个整数类型的值,使其进入或刚好超出数组对象,并产生一个指向该数组对象刚好超出并被一元*运算符作为操作数进行评估的结果。
  • 数组下标超出范围,即使使用给定下标可以访问对象(如在lvalue表达式a [1] [7]中给出声明int a [4] [5])。

1

访问数组外的元素是未定义行为

此外,使指针指向数组之外的元素(除了不存在的最后一个元素)也是未定义行为。访问最后一个元素之后的元素是未定义行为(指针存在是可以的)。

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 */

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接