Mic*_*has 40 c indexing types c99
应该使用C99中的数组索引的类型?它必须适用于LP32,ILP32,ILP64,LP64,LLP64等.它不一定是C89类型.
我找到了5位候选人:
size_tptrdiff_tintptr_t/uintptr_tint_fast*_t/uint_fast*_tint_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]);
}
Run Code Online (Sandbox Code Playgroud)
PS在问题的第一个版本中,我忘记了负面索引.
PPS我不打算编写C99编译器.但是编译器程序员的任何答案对我来说都是非常有价值的.
类似的问题:
Joh*_*itb 37
我认为你应该使用ptrdiff_t以下原因
size_t,都是不可能的)p2 - p1是ptrdiff_t.该类型i == p2 - p1的反向的事情,p2应该是那种太(请注意,p2 == p1 + i是等同于*(p + i))R..*_*R.. 25
我几乎总是size_t用于数组索引/循环计数器.当然,在某些特殊情况下您可能需要签名偏移,但通常使用签名类型会遇到很多问题:
最大的风险是,如果你通过调用者传递一个巨大的大小/偏移量来处理未签名的东西(或者如果你从一个错误信任的文件中读取它),你可能会把它解释为一个负数并且不能理解它是出界.例如,if (offset<size) array[offset]=foo; else error();它会写在不应该的地方.
另一个问题是带有符号整数溢出的未定义行为的可能性.无论你是使用无符号算术还是有符号算术,都需要注意和检查溢出问题,但我个人觉得无符号行为更易于处理.
使用无符号算术的另一个原因(通常) - 有时我使用索引作为位数的偏移量,我想使用%8和/ 8或%32和/ 32.对于签名类型,这些将是实际的除法操作.使用无符号时,可以生成预期的按位和/位移操作.
Amn*_*non 13
由于sizeof(array)(和malloc's参数)的类型是size_t,并且数组不能容纳比其大小更多的元素,因此size_t可以用于数组的索引.
编辑
此分析适用于基于0的数组,这是常见的情况.ptrdiff_t在任何情况下都可以工作,但索引变量有一个指针差异类型有点奇怪.
如果你开始size_t使用size_t,因为该类型必须能够索引任何数组:
0返回它,因此对于具有多个size_t元素的数组无效sizeof 正如Amnon所提到的那样把它作为论据如果你从零开始,然后转移到零开始,并使用size_t,由于上述原因,保证可以工作.所以替换:
for (j = jmin; j < jmax; j++) {
do_something(a[j]);
}
Run Code Online (Sandbox Code Playgroud)
有:
int *b = &a[jmin];
for (size_t i = 0; i < (jmax - jmin); i++) {
do_something(b[i]);
}
Run Code Online (Sandbox Code Playgroud)
为什么不使用:
ptrdiff_t:此表示的最大值可能小于最大值malloc.
这在cppref中提到,如果数组太大,可能会出现未定义的行为,建议在C99 6.5.5/9:
当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异.结果的大小是实现定义的,其类型(有符号整数类型)是标头中定义的ptrdiff_t. 如果结果在该类型的对象中无法表示,则行为未定义.
出于好奇,size_t也可能size_t比分段内存架构更大:https://stackoverflow.com/a/1464194/895245
GCC还对静态数组对象的最大大小施加了进一步的限制:C中数组的最大大小是多少?
uintptr_t:我不确定.所以我只是使用intptr_t因为我更确定:-)
我的选择:ptrdiff_t
许多人投票支持ptrdiff_t,但有些人表示使用指针差异类型进行索引很奇怪。对我来说,这是完全有道理的:数组索引是与原点指针的差值。
有些人还说这size_t是正确的,因为它是为了容纳尺寸而设计的。然而,正如一些人评论的那样:这是以字节为单位的大小,因此通常可以容纳比最大可能数组索引大几倍的值。