为什么编译器不会阻止我使用大于数组长度的整数减去一和负整数来索引到数组中?
允许这样做的理由是什么?
答案 0 :(得分:4)
编译器不能这样做,因为这是运行时的规定。
但是为什么std::vector
没有界限检查[]
运算符。这是因为已经有边界检查方法at()
。这将执行边界检查,如果索引超出边界,则会引发异常。
但是不付不使用的钱的C ++原则也在起作用。如果您已经保证它在范围之内,为什么还要检查一个超出范围的异常。
for(int loop = 0; loop < cont.size(); ++loop) {
std::cout << cont[loop] << "\n"; // Do I need to bounds check here?
} // loop is guaranteed to be in range
// why should I pay for the cost of
// of a check? So beginners don;t make
// mistakes?
因此,如果要限制检查的访问权限,请使用at()
;如果要不限制检查的访问权限,请[]
。
从评论中:
p[-10]
为什么起作用?因为在指针类型上,这只是*(p - 10)
的语法糖。那么您想想,检查有效性就困难得多。
int q[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int* p = q + 11;
std::cout << p[-10]; // This is valid operation.
答案 1 :(得分:1)
C ++运行时无法跟踪数组的大小,因此无法防止索引超出数组末尾。
如果您有一个指向数组中间位置的指针,则为负值编制索引会很有用。例如:
int a[] = { 1, 2, 3, 4, 5 };
int *p = &a[2];
std::cout << p[-1] << std::end;
这将打印2,因为p
指向包含3的元素。