- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
每个 C 程序员都可以使用这个众所周知的宏来确定数组中元素的数量:
#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a])
这是一个典型的用例:
int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19};
printf("%lu\n", NUM_ELEMS(numbers)); // 8, as expected
但是,没有什么能阻止程序员不小心传递指针而不是数组:
int * pointer = numbers;
printf("%lu\n", NUM_ELEMS(pointer));
在我的系统上,这会打印 2,因为显然,指针的大小是整数的两倍。我想了想如何防止程序员误传一个指针,找到了解决办法:
#define NUM_ELEMS(a) (assert((void*)&(a) == (void*)(a)), (sizeof(a)/sizeof 0[a]))
这是有效的,因为指向数组的指针与指向其第一个元素的指针具有相同的值。如果您改为传递一个指针,该指针将与指向其自身的指针进行比较,这几乎总是错误的。 (唯一的异常(exception)是递归 void 指针,即指向自身的 void 指针。我可以接受。)
不小心传递指针而不是数组现在会在运行时触发错误:
Assertion `(void*)&(pointer) == (void*)(pointer)' failed.
不错!现在我有几个问题:
我使用 assert
作为逗号表达式的左操作数是否有效标准 C?也就是说,标准是否允许我使用 assert
作为表达式?对不起,如果这是一个愚蠢的问题:)
能否以某种方式在编译时完成检查?
我的 C 编译器认为 int b[NUM_ELEMS(a)];
是一个 VLA。有什么办法可以说服他吗?
我是第一个想到这个的吗?如果是这样,我能指望有多少处女在天堂等着我? :)
最佳答案
Is my usage of assert as the left operand of the comma expression valid standard C? That is, does the standard allow me to use assert as an expression?
是的,它是有效的,因为逗号运算符的左操作数可以是 void
类型的表达式。 assert
函数的返回类型为 void
。
My C compiler thinks that int b[NUM_ELEMS(a)]; is a VLA. Any way to convince him otherwise?
之所以这么认为,是因为逗号表达式的结果永远不是常量表达式(例如,1、2 不是常量表达式)。
EDIT1:在下方添加更新。
我有另一个在编译时运行的宏版本:
#define NUM_ELEMS(arr) \
(sizeof (struct {int not_an_array:((void*)&(arr) == &(arr)[0]);}) * 0 \
+ sizeof (arr) / sizeof (*(arr)))
而且它似乎甚至可以与具有静态存储持续时间的对象的初始化程序一起使用。它也可以与您的 int b[NUM_ELEMS(a)]
编辑 2:
地址@DanielFischer评论。上面的宏适用于 gcc
without -pedantic
只是因为 gcc
接受:
(void *) &arr == arr
作为整数常量表达式,同时它考虑
(void *) &ptr == ptr
不是整型常量表达式。根据 C,它们都不是整数常量表达式,并且使用 -pedantic
,gcc
在这两种情况下都能正确发出诊断。
据我所知,没有 100% 可移植的方法来编写此 NUM_ELEM
宏。 C 在初始化常量表达式方面有更灵活的规则(请参阅 C99 中的 6.6p7),可以利用这些规则来编写此宏(例如使用 sizeof
和复合文字),但在 block 范围内 C 不需要初始化器成为常量表达式,因此不可能有一个适用于所有情况的宏。
编辑 3:
我认为值得一提的是,Linux 内核有一个 ARRAY_SIZE
宏(在 include/linux/kernel.h
中)在稀疏(内核静态分析检查器)被执行。
他们的解决方案不可移植并且使用了两个 GNU 扩展:
typeof
运算符__builtin_types_compatible_p
内置函数基本上它看起来像这样:
#define NUM_ELEMS(arr) \
(sizeof(struct {int :-!!(__builtin_types_compatible_p(typeof(arr), typeof(&(arr)[0])));}) \
+ sizeof (arr) / sizeof (*(arr)))
关于c - 可靠地确定数组中元素的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12784136/
我有几个带有视频和图像的 Bootstrap slider 。在 slider 之外,我想要一个可以转到包含视频的幻灯片的按钮。包含视频的幻灯片的数量因 slider 而异。我想做的是获取幻灯片的数量
我在编写一个查询时遇到了一些问题。 我有一个由文件及其大小(以字节为单位)组成的表。它看起来像这样: FileUrl | FileSize ------------------ xyz.docx |
我有一个带 iframe 的网站和一个带另一个 iframe 的网站,所以它是一个 iframe 内嵌另一个 iframe(都在不同的域上)。那么有没有办法从父div或父主div的url(parent
以下表达式在 JavaScript 中给出了特殊的结果。 typeof (5 + "7") // Gives string typeof (5 - "7") // Gives number 如
我有一个名为“交易”的表,每当有人在我的网站上进行购买时,我都会在其中输入用户 ID、购买类型和金额。 我想向每个用户显示过去 7 天的这些统计信息。 目前,我有这个: $data = array()
我一整天都在努力寻找解决这一挑战的办法。 我有一张 table : id | amount | type | date |
我正在尝试在 10 个数据节点的集群中测试 Map reduce 程序的性能。在此过程中,我使用了 5 个 Reducers,然后是 10 个等等。 我在想增加 reducer 的数量也会使工作完成得
我正在使用 html5 输入 type="number"。我想监视此输入的变化,但是: 因为在支持它的浏览器中 它有旋转控件 我不能只监视 .keyup, 因为我不想等待它失去焦点,所以我不能只监视
我的购物车表格有问题。我创建了一个如下所示的表格: SQL Fiddle 我的问题是我希望能够选择产品 ID,并计算该产品 ID 在表格中重复的次数,以便我可以显示用户在购物车中拥有的商品数量。 寻找
我使用许多包含来显示我网站的一小部分。使用许多 include 是否合适,或者我应该减少它们(尽可能多)。包含函数要多花多少时间? 我的主页加载速度很慢。有什么方法可以让它加载更快。 (我的主页每天在
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: length of array in function argument 我的数组大小是5。例如: arrC
是否有标准的 Python 方法来处理 Python 中的物理单位/数量?我看到了来自不同领域(如物理学或神经科学)的不同模块特定解决方案。但我更愿意使用标准方法而不是“孤岛”解决方案,因为其他人应该
基本上就像标题所说的那样,有没有办法从 JavaScript 程序中查看事件循环中当前存在多少个 promise ?最好在 Deno 上。 最佳答案 Deno v1.26 添加了一个内部 API,可用
我只是想知道大型项目-比如说航空公司的预订系统,它可能有多少类/对象。 对象:客户,飞机,机场,路线,机票,订单。这就是我能想到的。该项目可能是成千上万的代码行,那么是否可能会有更多的类(执行与对象无
如果有办法限制Scala中未处理的 future 数量,我将无法提供资金。 例如下面的代码: import ExecutionContext.Implicits.global for (i
从昨天开始,我一直在努力做到这一点,尽管还没有运气。我找到了解决方案,在我想要完成的事情上总是有细微的差别。 我试图获得所有可能的组合,稍微像这样:combination_k ,但我也希望相同的项目与
我正在尝试更新 1500 个 QuickBooks Online 库存项目的现有数量。我可以从商店中提取 1500 种产品。 这个更新可以做吗?我看到手头没有数量的物品: https://develo
我想与工作人员一起扩展应用程序。 可能有 1 名 worker 或 100 名 worker ,我想无缝扩展它们。 这个想法是使用副本集。然而,由于特定领域的原因,扩展它们的适当方法是让每个工作人员知
Android Studio 有没有办法显示 XML 布局中存在的 View 数量?众所周知,布局应该包含 <=80 个 View ,因此超过此值就会出现此警告,因此告知数量会非常有帮助。 Layou
虽然编码时总是出现有关 IBOutlet 保留计数的相同问题:从 NIB 取消归档对象后保留计数?何时对 IBOutlet 使用 @property?设置时保留还是分配? Mac 和 iPhone 之
我是一名优秀的程序员,十分优秀!