为了遍历数组,我们应该使用size_t还是ptrdiff_t?

时间:2018-07-07 21:41:12

标签: c pointers size-t errata ptrdiff-t

在此blog entry by Andrey Karpov entitled, "About size_t and ptrdiff_t"中,他显示了一个示例,

for (ptrdiff_t i = 0; i < n; i++)
  a[i] = 0;

但是,我不确定是否正确,看来应该是

for (size_t i = 0; i < n; i++)
  a[i] = 0;

这正确吗?

我知道我们也应该使用memset之类的东西,但是让我们完全避免这种情况。我只问类型

3 个答案:

答案 0 :(得分:8)

a blog post中,我认为您应始终避免分配大于PTRDIFF_MAX(*)的内存块,因为这样做会使Clang和GCC等编译器生成无意义的代码,即使您这样做不会以导致结果溢出的方式减去该块的指针。

(*)即使malloc成功传递时,其值也大于PTRDIFF_MAX。问题的症结在于,当与这样的malloc链接时,GCC和Clang仅生成正确运行的代码,但是Glibc提供的malloc函数没有实现此限制。

如果遵循该约束(我鼓励您这样做:这是博客文章的内容),那么两种类型都同样正确。

这就是说,由于只需要表示正偏移量,因此size_t是您示例中的自然选择。

答案 1 :(得分:2)

因为 foreach($data as $key=>$val){ $keys[] = $key; $vals[] = ":".$key; } $keys = "`".implode("`,`", $keys)."`"; $vals = implode(",", $vals); $sql = "INSERT INTO `".$tab."`(".$keys.") VALUES (".$vals.")"; $prep_insert = $this->pdo->prepare($sql); $prep_insert->execute($data); 被翻译为ptrdiff_t,所以可以使用a[i]

如果您使用两个指针*(a + i)p1,则建议您使用:

p2

鉴于ptrdiff_t d = p2 - p1; // Assuming p2 - p1 is valid. ,即p2 == p1 + d是有效的表达式。 <ptr type> + ptrdiff_t还是ptrdiff_t更好,因为索引类型取决于团队中的观点和/或编码风格。

答案 2 :(得分:0)

OP问题的答案是肯定的,size_t最适合示例代码,其中没有相互减去指针值,并且在malloc行为方面没有交叉编译器/库兼容性问题。无论堆管理器有何不同,在C语言中,数组的长度可以为SIZE_MAX个字节,并且需要一个size_t来表示它。标准中没有要求堆管理器能够分配堆中的所有进程内存空间,或为此最多分配SIZE_MAX个字节,但是数组的长度可以为SIZE_MAX ,因此size_t是合适的。

即使n已签名,对ptrdiff_t使用i也无济于事,因为如果{{1 }}为负数,因为i < n初始化为零。 n索引无法访问i的索引。唯一需要i的地方是从另一个指针值中减去一个指针值,而OP并没有要求这样做。