避免在C语言中使用模板式语法sizeof(x) / sizeof(x[0])。

3

我经常写这个:

for (size_t i = 0; i < sizeof(some_variable) / sizeof(some_variable[0]); i++) {
   // ...
}

根据这个问题,我也可以编写一个类似的宏:

#define ArrayLength(x) (sizeof(x)/sizeof(x[0]))

然而,我认为将这个非常简单的东西混淆在宏下面并不是一个好的解决方案。

是否有C99或C11定义的更好的替代方案?

由于这种样板语法,我经常发现我的同事硬编码变量的大小,或者更糟糕的是使用像这样的define

#define ELEMENTS 23
int foo[ELEMENTS];
for (size_t i; i < ELEMENTS; i++);

不会。另请注意,如果将“some_variable”作为参数传递给函数,则上面的代码将无法正常工作。 - Rishikesh Raje
stddef中,例如可以找到非常有用的offsetof。它是一种标准化的方式来获取结构体中的成员偏移量。我正在寻找类似于此的内容,可能称为elementsof - nowox
我更喜欢将其写出来,这样更清晰。如果你觉得它太长了,在循环之前将其作为常量放置,让优化器完成其工作。 - AndersK
1
@Marian 这是无用的,因为你失去了宝贵的信息:ELEMENTS 属于 foo。如果你只是为了 foo 使用 ELEMENTS 并遍历它,那么最好使用 sizeof(foo) / sizeof(foo[0])。此外,你让代码更难读懂,因为不能直接读取 foo 的大小,必须查找可能在上面某个地方找到的 ELEMENTS - nowox
@nowox for (size_t i; i < ELEMENTS; i++); 不是“无用的”。最佳编码实践通常取决于更大的代码上下文和团队采用的样式指南。 - chux - Reinstate Monica
显示剩余4条评论
2个回答

3

到目前为止,最好的方法是维护一个单独的参数来存储数组中的元素数量。

这样,在将代码移动到函数中时,由于指针衰减导致的所有错误都不会再发生。

如果不能实现上述方法,请始终使用完整拼写的sizeof习语。


2
您IP地址为146.190.162.183,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。
 for (size_t i = 0; i < sizeof(some_variable) / sizeof(some_variable[0]); i++) {

相对而言,更好的选择是使用注释,这样不会让人类读者对实际实现或目的感到困惑。无论如何,任何半靠谱的编译器都将执行所需的优化(适用于任何情况)。


如果这个宏是定义在整个项目中使用的基本头文件中的一个实用程序,那么这并不是一个问题。用户很快就能熟练地使用这个宏。 - StoryTeller - Unslander Monica
@StoryTeller 正如我之前所说,这是个选择问题。作为编写者,我喜欢使用宏,但作为读者,我更愿意看到其扩展形式。 :) - Sourav Ghosh
3
不需要换行,可以使用一个存储大小的变量。 - 2501
2
也许我是一个老教条主义者,但如果有人为此使用宏,我会完全失控——因为如果循环移入函数并将数组传递给函数时存在指针衰减的问题。 - Bathsheba
如果传递了指针,您可以使用一些技巧使宏产生错误。 - R.. GitHub STOP HELPING ICE
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接