可能重复:
A riddle (in C)
关于以下代码段,我有几个问题:
#include<stdio.h>
#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?
答案 0 :(得分:12)
看看这一行:
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
。
答案 1 :(得分:7)
sizeof
以无符号格式返回字节数。这就是你需要演员的原因。
查看更多here。
答案 2 :(得分:3)
关于
的问题#define AA (-64)
请参阅C preprocessor
中的Macro definition and expansion:
类似对象的宏通常被用作良好编程实践的一部分,为常量创建符号名称,例如。
#define PI 3.14159
...而不是在整个代码中对这些数字进行硬编码。但是,C和C ++都提供了const指令,它提供了另一种避免整个代码中硬编码常量的方法。
定义为宏的常量没有关联类型。尽可能使用const
。
答案 3 :(得分:1)
回答您的一个子问题:
要“在宏中定义常量”(这有点草率,你没有定义一个“常量”,只是做一些无符号的文本替换技巧),你应该使用'u'后缀:
#define UNSIGNED_FORTYTWO 42u
这将在您键入unsigned int
的任何位置插入UNSIGNED_FORTYTWO
字面值。
同样,您经常会看到(在&lt; math.h&gt;中)用于设置精确浮点类型的足迹:
#define FLOAT_PI 3.14f
这会在代码中键入float
的任何位置插入FLOAT_PI
(即“单精度”)浮点文字。