1

我有一个 malloc 的指针数组,形成一个哈希表。要逐步遍历哈希表,我会使用指针算术,例如:

node_t ** tc = table;
size_t tcs = sizeof(node_t *);
for(long i = 0; i < tableSize; tc+=tcs, ++i) { 
    // Do some stuff with *tcs location in the table.
}

问题是我应该将size_t返回的sizeof()to 转换ptrdiff_t为条件的增量部分中的正确添加for吗?还是加起来有关系?

4

3 回答 3

3

您需要ptrdiff_t处理负值。size_t处理正值,例如sizeof您的示例中的结果,因此您不需要强制转换。

话虽如此,代码看起来很可疑:C 编译器将 的大小纳入您的指针算术,因此您必须添加到双指针struct的事实可能是一个错误。如果要前进到指针数组中的下一个指针,请添加到该指针的当前值。编译器足够聪明,可以根据指针的类型为您乘以。sizeof(node_t*)node_t11sizeof(*ptr)

于 2015-05-17T11:18:25.630 回答
2

不,你不需要。

指针运算是根据指针的类型T *执行的。添加 asize_t不会影响指针算术,因为增量是使用sizeof(T).

引用标准(C11 草案):

6.5.6 加法运算符

当一个整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向与原始元素偏移的元素,使得结果和原始数组元素的下标之差等于整数表达式。换句话说,如果表达式 P 指向数组对象的第 i 个元素,则表达式 (P)+N(等效于 N+(P))和 (P)-N(其中 N 的值为 n)指向分别到数组对象的第 i+n 个和第 i-n 个元素,前提是它们存在。此外,如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向数组对象的最后一个元素,如果表达式 Q 指向数组对象的最后一个元素,则表达式 (Q)-1 指向数组对象的最后一个元素。如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。如果结果指向数组对象的最后一个元素,则不应将其用作计算的一元 * 运算符的操作数。否则,行为未定义。如果结果指向数组对象的最后一个元素,则不应将其用作计算的一元 * 运算符的操作数。否则,行为未定义。如果结果指向数组对象的最后一个元素,则不应将其用作计算的一元 * 运算符的操作数。

另一方面,转换size_tptrdiff_t可能会导致不正确的代码,因为ptrdiff_tsize_t符号而无符号类型。因此,如果结果值大于ptrdiff_t可以容纳的值,那么就会出现问题。简而言之,将任何整数类型添加到指针类型时,指针算术是明确定义的,您根本不需要这样的强制转换。

于 2015-05-17T11:16:59.020 回答
1

这里不需要,ptrdiff_t因为周围没有指针差异。

你可能想要的是:

for (node_t ** tc = table; tc < (table + tableSize); ++tc) {
  ...
}
于 2015-05-17T11:27:48.317 回答