混淆C宏展开和整数运算

混淆C宏展开和整数运算,c,macros,c-preprocessor,C,Macros,C Preprocessor,可能重复: 关于以下片段,我有几个问题: #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; } 它按

可能重复:

关于以下片段,我有几个问题:

#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;
}
它按预期显示所有数组元素

  • 这种类型转换是如何工作的
基于此,我有几个问题:

  • 这是否意味着如果我有一些宏观定义:

    #定义AA(-64)

在C语言中,默认情况下,所有定义为宏的常量都等价于有符号整数

如果是,那么

  • 但是,如果我必须强制使宏中定义的某个常量表现为无符号int,是否有任何常量后缀超出了我的使用范围(我尝试了UL,UD都不起作用)

  • 如何在宏定义中定义常量,使其表现为无符号int


sizeof
返回无符号格式的字节数。这就是为什么你需要演员

查看更多信息。

查看这一行:

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)

for(d=-1;d关于您关于

#define AA (-64)
请参见
C预处理器中的:

类对象宏通常被用作良好编程实践的一部分,用于为常量创建符号名,例如

#定义PI 3.14159

……而不是硬编码整个代码中的那些数字。然而,C和C++都提供了const指令,这提供了另一种避免整个代码中硬编码常数的方法。


定义为宏的常量没有关联的类型。尽可能使用
const

只回答一个子问题:

若要“在宏中定义常量”(这有点草率,您不是定义“常量”,只是做了一些文本替换技巧)是无符号的,您应该使用“u”后缀:

#define UNSIGNED_FORTYTWO 42u
这将在键入
unsigned_FORTYTWO
的任何位置插入一个
unsigned int
文本

类似地,您经常会看到(例如)用于设置精确浮点类型的足够信息:

#define FLOAT_PI 3.14f

这将在代码中键入
float\u PI
的任何位置插入一个
float
(即“单精度”)浮点文本。

@Skurmedel:这很好。但是如果我将宏定义为#define bb(-64*(sizeof(int)/sizeof(int)))然后使用bb,它表现为有符号的int,我认为它应该表现为无符号的int,因为在bb的宏定义中,有符号的int与无符号的int相乘,所以结果应该是无符号的int(C提升规则)。根据C99标准(6.3.1.8),我是不正确的还是遗漏了什么:否则,如果有符号整数类型的操作数类型可以表示无符号整数类型的操作数类型的所有值,则无符号整数类型的操作数将转换为有符号整数类型的操作数类型。我猜sizeof返回的是无符号long,其值可以表示由有符号整型进行签名,因此生成的类型是有符号的。上面的部分解释了如果无符号类型的秩等于或大于有符号类型,则有符号类型将转换为无符号类型。也就是说,如果sizeof将返回无符号整型。但是,编译器可能会让sizeof返回无符号长字符串。@Miroslav:我应该使用什么后缀用于在macro.fyi中定义无符号常量,循环和数组的C习惯用法如下:int i;for(int i=0;ifor(d=-1;d <= ((sizeof(array) / sizeof(array[0]))-2);d++)
#define AA (-64)
#define UNSIGNED_FORTYTWO 42u
#define FLOAT_PI 3.14f