【问题标题】:Negative array index in CC中的负数组索引
【发布时间】:2011-11-15 09:03:04
【问题描述】:

论坛中有关于 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 arrays pointers


    【解决方案1】:

    在您编写它时这是未定义的行为,因为您正在越界访问数组。

    但是,负指数并不一定意味着未定义的行为。以下代码定义明确:

    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);
    

    【讨论】:

      【解决方案2】:

      访问超出范围的数组会导致未定义行为(UB)。
      -ve 索引不是有效索引并导致未定义行为。

      未定义的行为意味着任何事情都可能发生,如果幸运,您的程序将崩溃并检测到问题,如果您不幸运,代码一直运行良好,总有一天会崩溃。
      因此,请始终避免编写任何会导致 Undefined Behaivor 的代码。

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

      否
      程序员必须注意这一点。标准不需要编译器为此提供任何指示/警告。标准只是将其定义为 UB。

      此外,该标准确定了以下所有导致未定义行为的场景:

      • 将指针添加或减少到数组对象或仅超出数组对象和整数类型会产生不指向或仅超出同一数组对象的结果。
      • 对数组对象和整数类型的指针进行加法或减法运算会产生一个刚好超出数组对象的结果,并用作被评估的unary * operator 的操作数。
      • 数组下标超出范围,即使一个对象显然可以使用给定的下标访问(如左值表达式a[1][7] 给定的声明int a[4][5])。

      【讨论】:

        【解决方案3】:

        访问数组外的元素是Undefined Behaviour。

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

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

        【讨论】:

          猜你喜欢
          • 2011-04-29
          • 2018-04-27
          • 2018-07-13
          • 1970-01-01
          • 2018-04-20
          • 2014-01-21
          • 2011-03-29
          • 1970-01-01
          • 2020-02-03
          相关资源
          最近更新 更多