对C宏扩展和整数运算感到困惑

发布于 2024-07-23 01:20:25 字数 968 浏览 3 评论 0原文

可能的重复:
一个谜语(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 的宏定义 as

 #define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0]))

它会按预期显示所有数组元素。

  • 这种类型转换是如何运作的?

基于此,我有几个问题:

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

    #define AA (-64)

在 C 中默认 ,所有定义为宏的常量都相当于signed int

如果是,那么

  • 但是如果我必须强制使宏中定义的某些常量表现为无符号整数,是否有任何我可以使用的常量后缀(我尝试了 UL、UD 都不起作用)?

  • 如何在宏定义中定义常量以使其表现为 unsigned int?

Possible Duplicate:
A riddle (in C)

I have a couple of questions regarding the following snippet:

#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;
}

Here the output of the code does not print the array elements as expected. But when I add a typecast of (int) the the macro definition of ELEMENTS as

 #define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0]))

It displays all array elements as expected.

  • How does this typecast work?

Based on this I have few questions:

  • Does it mean if I have some macro definition as:

    #define AA (-64)

by default in C, all constants defined as macros are equivalent to signed int.

If yes, then

  • But if I have to forcibly make some constant defined in a macro behave as an unsigned int is there any constant suffix than I can use (I tried UL, UD neither worked)?

  • How can I define a constant in a macro definition to behave as unsigned int?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忘羡 2024-07-30 01:20:25

看这一行:

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

在第一次迭代中,您正在检查

-1 <= (TOTAL_ELEMENTS-2)

运算符 size_of 是否返回无符号值,并且检查失败(在 32 位计算机上 -1 有符号 = 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 表示 unsignedul 表示 unsigned long)。

Look at this line:

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

In the first iteration, you are checking whether

-1 <= (TOTAL_ELEMENTS-2)

The operator size_of returns unsigned value and the check fails (-1 signed = 0xFFFFFFFF unsigned on 32bit machines).

A simple change in the loop fixes the problem:

for(d=0;d <= (TOTAL_ELEMENTS-1);d++)
printf("%d\n",array[d]);

To answer your other questions: C macros are expanded text-wise, there is no notion of types. The C compiler sees your loop as this:

for(d=-1;d <= ((sizeof(array) / sizeof(array[0]))-2);d++)

If you want to define an unsigned constant in a macro, use the usual suffix (u for unsigned, ul for unsigned long).

冰雪之触 2024-07-30 01:20:25

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

请参阅此处了解更多信息。

sizeof returns the number of bytes in unsigned format. That's why you need the cast.

See more here.

傻比既视感 2024-07-30 01:20:25

关于您关于

#define AA (-64)

C 预处理器中的宏定义和扩展的问题代码>:

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

#define PI 3.14159

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

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

Regarding your question about

#define AA (-64)

See Macro definition and expansion in the C preprocessor:

Object-like macros were conventionally used as part of good programming practice to create symbolic names for constants, e.g.

#define PI 3.14159

... instead of hard-coding those numbers throughout one's code. However, both C and C++ provide the const directive, which provides another way to avoid hard-coding constants throughout the code.

Constants defined as macros have no associated type. Use const where possible.

身边 2024-07-30 01:20:25

只回答你的一个子问题:

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

#define UNSIGNED_FORTYTWO 42u

无论您在何处键入 UNSIGNED_FORTYTWO,都会插入一个 unsigned int 文字。

同样,您经常看到(例如在中)用于设置精确的浮点类型:

#define FLOAT_PI 3.14f

这会在任何位置插入 float (即“单精度”)浮点文字您在代码中输入FLOAT_PI

Answering just one of your sub-questions:

To "define a constant in a macro" (this is a bit sloppy, you're not defining a "constant", merely doing some text-replacement trickery) that is unsigned, you should use the 'u' suffix:

#define UNSIGNED_FORTYTWO 42u

This will insert an unsigned int literal wherever you type UNSIGNED_FORTYTWO.

Likewise, you often see (in <math.h> for instance) suffices used to set the exact floating-point type:

#define FLOAT_PI 3.14f

This inserts a float (i.e. "single precision") floating-point literal wherever you type FLOAT_PI in the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文