关于使用size_t

时间:2017-07-03 16:54:42

标签: c

如果我使用'x'int,我想使用size_t字符初始化一个字符数组?

char *pch = (char *) malloc(100);
for (size_t s = 0; s < 100; s++)
    pch[s] = 'x';

注意:我知道memset和其他'技巧',我的问题只是关于int VS size_t

3 个答案:

答案 0 :(得分:5)

由于变量是对数组建立索引,因此使用size_t更合适,因为数组索引不能(通常)为负数。

此外,由于数组索引经常与strlen调用或sizeof运算符的结果进行比较,因此使用size_t生成int两者都会产生memset签名/未签名比较的警告。

但是,如果您要将缓冲区的所有字节初始化为给定值,则应使用memset(pch, 'x', 100);

df.loc[index,column_name]

答案 1 :(得分:3)

size_t更适合索引数组,因为它保证所有数组大小都具有正确的范围。然而,有一些问题需要考虑:

  • size_t是无符号类型,因此您必须小心,只能在测试中计算正值。

    例如,以这种方式向下迭代将不起作用:

    for (size_t i = size - 1; i >= 0; i--) {
         array[i] = 0;
    }
    

    这种天真的方法有两个问题:即使size0,它也会迭代,并且它永远循环,因为i >= 0始终为真。

    更好的方法是:

    for (size_t i = size; i-- > 0;) {
         array[i] = 0;
    }
    
  • size_t可能会大于int,因此%d中的格式printf不适合此类型的索引值。标准转换说明符为%zd,但许多Windows系统不支持它。您可能需要将size_t值转换为(int)或使用%llu并将size_t值转换为unsigned long long

  • 有些人认为size_t不优雅,可能是因为_或只是因为他们不习惯。

由于这些和其他原因,将索引变量定义为int是很常见的。虽然小数组和短循环都可以,但是在这些假设最终失败的代码中很难找到错误。

答案 2 :(得分:2)

生成的代码可能是相同的,特别是对于这种简单的情况。对于更复杂的数学,签名类型(如果可以安全地使用它们)稍微更优化,因为允许编译器假设它们永远不会溢出。对于签名类型,如果您决定与负指数进行比较,您也不会感到不愉快。

所以,如果总结一下:

        very_large_arrays negative_comparison_safe maybe_faster
int     no                yes                      yes 
size_t  yes               no                       no

看起来int可能更适合绝对小 - (如果你的架构目标保证的话,是<2 ^ 15或者也许是2 ^ 31)范围,除非你能想到size_t的另一个标准胜。

size_t的优点在于,只要您不与负指数进行比较,无论大小如何,它肯定适用于任何数组。 (这可能比负面比较安全性和未定义溢出的潜在速度增益更重要)。

ssize_t(== signed size_t)结合了两者的优点,除非你需要size_t的最后一位(你肯定不在64位机器上)。