为什么C支持负数组索引?

box*_*__l 13 c arrays pointers

从SO中的这篇文章来看,很明显C支持负指数.

  1. 为什么在程序中支持这种潜在的内存违规?

  2. 编译器不应该至少抛出一个负指数警告吗?(我正在使用GCC)

  3. 或者这个计算是在运行时完成的?

编辑1: 任何人都可以暗示它的用途吗?

编辑2: 用于3.)使用[]数组/指针中的循环计数器表示指数的运行时计算.

Zif*_*ion 19

计算在运行时完成.

负指数不一定必须导致违规,并且有其用途.

例如,假设您有一个指针,该指针当前指向数组中的第10个元素.现在,如果您需要在不更改指针的情况下访问第8个元素,则可以使用负索引-2轻松地执行此操作.

char data[] = "01234567890123456789";
char* ptr = &data[9];
char c = ptr[-2]; // 7
Run Code Online (Sandbox Code Playgroud)


Eri*_*hil 11

这是一个使用示例.

无限脉冲响应滤波器部分地根据最近的先前输出值计算.通常,会有一些输入值数组和一个放置输出值的数组.如果当前输出元素是y i,则y i可以被计算为y i = a 0 ·x i + a 1 ·x i-1 + a 2 ·y i-1 + a 3 ·y i-2.

为此编写代码的一种自然方式是:

void IIR(float *x, float *y, size_t n)
{
    for (i = 0; i < n; ++i)
        y[i] = a0*x[i] + a1*x[i-1] + a2*y[i-1] + a3*y[i-2];
}
Run Code Online (Sandbox Code Playgroud)

观察到i零时,y[i-1]并且y[i-2]具有负指数.在这种情况下,调用者负责创建一个数组,将输出的初始两个元素设置为"起始值"(通常为零或从前一个缓冲区保留的值),并将指针传递给第一个新值的位置是要写的.因此,此例程IRR通常接收指向数组中间的指针,并使用负索引来处理某些元素.

  • 一个现实世界的例子很好的答案.但是我认为,你应该在i = 2处开始你的循环,这样很明显你没有试图超出范围. (3认同)

Yu *_*Hao 8

为什么在程序中支持这种潜在的内存违规?

因为它遵循指针算术,并且在某些情况下可能有用.

编译器不应该至少抛出一个负指数警告吗?(我正在使用GCC)

array[10]当数组只有10个元素时,编译器在访问时不会发出警告的原因相同.因为它将这项工作留给了程序员.

或者这个计算是在运行时完成的?

是的,计算是在运行时完成的.


use*_*959 5

阐述Taymon的答案:

float arr[10];
float *p = &arr[2];

p[-2]
Run Code Online (Sandbox Code Playgroud)

现在完全可以.我没有看到负面指数的良好使用,但是如果你指向一个有效范围之外,如果它通常是不可判定的,那么为什么标准会将其排除.