对C宏扩展和整数运算感到困惑
可能重复:
一个谜语(在C中)
关于以下代码段,我有几个问题:
#include #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; }
这里代码的输出不会按预期打印数组元素。 但是当我添加一个(int)的类型转换时,ELEMENTS的宏定义为
#define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0]))
它按预期显示所有数组元素。
- 这种类型转换是如何工作的?
基于此,我有几个问题:
-
如果我有一些宏定义,这是否意味着:
#define AA (-64)
默认情况下,在C中,所有定义为宏的常量都等同于signed int 。
如果是,那么
-
但是,如果我必须强制在宏中定义一些常量,因为unsigned int是否有任何常量后缀而不是我可以使用(我试过UL,UD既不起作用)?
-
如何在宏定义中定义常量以表现为unsigned int?
看看这一行:
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
在第一次迭代中,您正在检查是否
-1 <= (TOTAL_ELEMENTS-2)
运算符size_of返回无符号值,检查失败(在32位机器上签名为-1 signed = 0xFFFFFFFF)。
循环中的一个简单更改可以解决问题:
for(d=0;d <= (TOTAL_ELEMENTS-1);d++) printf("%d\n",array[d]);
回答你的其他问题:C宏是按文本扩展的,没有类型的概念。 C编译器将您的循环视为:
for(d=-1;d <= ((sizeof(array) / sizeof(array[0]))-2);d++)
如果要在宏中定义无符号常量,请使用通常的后缀( u
表示unsigned
, ul
表示unsigned long
ul
)。
sizeof
以无符号格式返回字节数。 这就是你需要演员的原因。
在这里查看更多。
关于你的问题
#define AA (-64)
请参阅C preprocessor
中的宏定义和扩展 :
类似对象的宏通常被用作良好编程实践的一部分,以创建常量的符号名称,例如
#define PI 3.14159
…而不是在整个代码中对这些数字进行硬编码。 但是,C和C ++都提供了const指令,它提供了另一种避免整个代码中的硬编码常量的方法。
定义为宏的常量没有关联类型。 尽可能使用const
。
回答你的一个子问题:
要“在宏中定义一个常量”(这有点草率,你没有定义一个“常量”,只是做一些未签名的文本替换技巧),你应该使用’u’后缀:
#define UNSIGNED_FORTYTWO 42u
这将在您键入UNSIGNED_FORTYTWO
任何位置插入unsigned int
literal。
同样,您经常会看到(例如在
#define FLOAT_PI 3.14f
这FLOAT_PI
在代码中键入FLOAT_PI
任何位置插入float
(即“单精度”)浮点文字。