C99 中的数组索引应该使用什么类型?它必须适用于 LP32、ILP32、ILP64、LP64、LLP64 等。它不一定是 C89 类型。
我找到了 5 个候选人:
size_t
ptrdiff_t
intptr_t
/uintptr_t
int_fast*_t
/uint_fast*_t
int_least*_t
/uint_least*_t
有简单的代码可以更好地说明问题。在这两个特定循环中,i
和 j
的最佳类型是什么。如果有充分的理由,两种不同的类型也可以。
for (i=0; i<imax; i++) {
do_something(a[i]);
}
/* jmin can be less than 0 */
for (j=jmin; j<jmax; j++) {
do_something(a[j]);
}
附言 在问题的第一个版本中,我忘记了负索引。
附言 我不会编写 C99 编译器。然而,编译器程序员的任何回答对我来说都是非常有值(value)的。
类似问题:
- size_t vs. uintptr_t
尽管这个问题的上下文有所不同。
最佳答案
我认为你应该使用ptrdiff_t
,原因如下
- 索引可以是负数。因此对于一般性的陈述,所有无符号类型,包括
size_t
,都是不合适的。 p2 - p1
的类型是ptrdiff_t
。如果i == p2 - p1
,那么你应该能够通过p2 == p1 + i
得到p2
。请注意,*(p + i)
等同于p[i]
。- 作为此“通用索引类型”的另一个指示,当内置
operator[]
(例如,在指针上)与用户竞争时,重载决策所使用的索引类型所提供的operator[]
(例如 vector 的)正是(http://eel.is/c++draft/over.built#16): >For every cv-qualified or cv-unqualified object type T there exist candidate operator functions of the form
T* operator+(T*, std::ptrdiff_t); T& operator[](T*, std::ptrdiff_t); T* operator-(T*, std::ptrdiff_t); T* operator+(std::ptrdiff_t, T*); T& operator[](std::ptrdiff_t, T*);
编辑:如果你有一个真的大数组或指向一个非常大的内存部分的指针,那么我的“通用索引类型”不会削减它,因为它不能保证您可以从最后一个元素的地址中减去第一个元素的地址。然后应该使用@Ciro 的回答https://stackoverflow.com/a/31090426/34509 .就我个人而言,我尽量避免使用无符号类型,因为它们无法表示负面的边缘情况(例如,向后迭代时循环结束值),但这是一种宗教辩论(不过我并不孤单) .当然,在需要使用无符号类型的情况下,我必须抛开我的宗教信仰。
关于c - C 中数组索引的正确类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3174850/