C 编程#define?

发布于 2024-09-30 15:02:08 字数 579 浏览 5 评论 0原文

可能的重复:
谁能解释一下这些未定义的行为(i = i++ + ++i , i = i++ 等...)

#include<stdio.h>
#include<conio.h>

#define SQ(x) x*x

void main()
{
   int a1 , a2;
   int b1 , b2;

   a1 = 2;
   a2 = 2;

   b1 = 0;
   b2 = 0;

   b1 = SQ(a1++);
   b2 = SQ(++a2);

   printf("Frist = %d",b1);
   printf("Second = %d",b2);
}

我知道代码的输出是什么。

作为其他程序中的 #define 工作 这样它在上面的代码中不起作用 为什么。?

Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

#include<stdio.h>
#include<conio.h>

#define SQ(x) x*x

void main()
{
   int a1 , a2;
   int b1 , b2;

   a1 = 2;
   a2 = 2;

   b1 = 0;
   b2 = 0;

   b1 = SQ(a1++);
   b2 = SQ(++a2);

   printf("Frist = %d",b1);
   printf("Second = %d",b2);
}

I know what is the output of the code.

as #define work in other programe
that way it is not working in above code
Why.?

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

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

发布评论

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

评论(9

痴情 2024-10-07 15:02:08

在同一变量上使用多个 ++ 运算符的表达式的结果在 C 中正式是一种未定义行为

The result of an expression with more than one ++ operator on the same variable is officially an undefined behavior in C.

冷月断魂刀 2024-10-07 15:02:08

#define 是一条指示预处理器的指令,用于将宏的每次出现逐字替换为其扩展。因此,代码中的相关行将传递给编译器,如下所示:

b1 = a1++ * a1++;
b2 = ++a2 * ++a2;

正如 Seva 所说,这些表达式正式未定义;但即使我们采取可以说是最明智的阅读方式,您仍然会得到 b1 = 2 * 3;b2 = 3 * 4; (两者都 a1a2 在行后设置为 4。

#define is an instruction to the preprocessor to literally replace each occurrence of the macro with its expansion. So the relevant lines in your code will pass to the compiler as:

b1 = a1++ * a1++;
b2 = ++a2 * ++a2;

As Seva states, these expressions are officially undefined; but even if we take what is arguably the most sensible reading you'll still get b1 = 2 * 3; and b2 = 3 * 4; (with both a1 and a2 set to 4 after the lines.

箜明 2024-10-07 15:02:08

SQ 的两种使用都会调用未定义的行为,因为它们在每个序列点多次分配给 a1 和 a2。您不应传递具有副作用的表达式,例如对宏进行赋值或增量。

Both uses of SQ invoke undefined behaviour, as they are assigning to a1 and a2 more than once per sequence point. You should not pass expressions with side effects such as assignments or increments to macros.

捂风挽笑 2024-10-07 15:02:08

因为定义只是替换了表达式。所以你得到结果:

b1 = (a1++)*(a1++);
b2 = (++a2)*(++a2;

所以,你得到了两次双倍增量。它会导致未定义的行为。

because define just replaces the expression. so you get in result:

b1 = (a1++)*(a1++);
b2 = (++a2)*(++a2;

So, you get double increment twice. It results in undefined behaviour.

素食主义者 2024-10-07 15:02:08

恭喜!您刚刚发现了为什么在此类事情上使用宏是一个坏主意。作为一般规则,只有在无法使用函数完成的情况下才将其设为宏。在这种情况下,SQ 可以轻松地实现为函数:

int sq (int x)
{
    return x * x;
}

Congratulations! You have just discovered why it is a bad idea to use macros for this sort of thing. As a general rule, only make something a macro if it cannot be done using a function. In this case, SQ could easily be implemented as a function instead:

int sq (int x)
{
    return x * x;
}
故事灯 2024-10-07 15:02:08

将宏中的操作数括在括号之间:

#define SQ(X) (X)*(X)

另外,尽量不要在同一个赋值中使用 x++ 和 x 进行操作。可能导致未定义的行为。

干杯!

Wrap the operands in the macro between parenthesis:

#define SQ(X) (X)*(X)

Also, try not to operate with x++ and x in the same assignment. Could lead to undefined behavior.

Cheers!

等风也等你 2024-10-07 15:02:08

这些行

b1 = SQ(a1++);
b2 = SQ(++a2);

扩展到

b1 = a1++ * a1++;
b2 = ++a2 * ++a2;

调用未定义的行为(对象的值在序列点之间最多可以修改一次),这意味着任何结果都被认为是“正确的”。

这就是这类宏的问题;您确实希望对参数求值一次,但由于扩展,它会被求值两次。

表达式来调用它也存在问题

x = SQ(a + b);

使用像This will Expand to

x = a + b * a + b;

这可能不是你想要的 。为了保持运算符优先级,扩展应该包裹在 () 中,例如

#define SQ(x) (x) * (x)

The lines

b1 = SQ(a1++);
b2 = SQ(++a2);

expand to

b1 = a1++ * a1++;
b2 = ++a2 * ++a2;

which invoke undefined behavior (an object may have its value modified at most once between sequence points), meaning any result is considered "correct".

That's the problem with these sorts of macros; you really want the argument to be evaluated once, but because of the expansion it gets evaluated twice.

There's also the problem with calling it with an expression like

x = SQ(a + b);

This will expand to

x = a + b * a + b;

which is probably not what you wanted. To preserve operator precedence, the expansion should be wrapped in (), such as

#define SQ(x) (x) * (x)
一页 2024-10-07 15:02:08

查看代码,因为它将由预处理器扩展:

b1 = a1++ * a1++;
b2 = ++a2 * ++a2;

这是未定义的行为,因为您多次修改一个变量,而它们之间没有序列点。

Look at the code as it will be expanded by the preprocessor:

b1 = a1++ * a1++;
b2 = ++a2 * ++a2;

This is undefined behavior, because you are modifying a variable more than once without a sequence point between them.

浮华 2024-10-07 15:02:08

我真的不知道你的问题是什么,但也许你的预期输出有问题......
请注意,#define 是在代码编译之前运行的“简单”文本替换。
这种文本替换不考虑范围或语法正确性。它只是替换与您所说的内容匹配的任何内容。
在你的情况下,它不会真正对“a++”的结果进行平方,而是会
生成此代码:b1 = a++ * a++;

如果您查看此处:有关 C 编程的问题,您可以看到一些解释,解释为什么“a++ * a++” " 是正式未定义的行为。

I really don't know what your question is, but maybe you have problems with your expected output...
Be aware that #define is a "simple" text-replacement that is running before your code compiles.
This text-replacement has no respect for scope or syntactic correctnes.. it just replaces anything that matches with what you said it.
In your case it would not really make a square of the result of "a++", instead it would
generate this code: b1 = a++ * a++;

If you look here: Question about C programming you can see some explanations as why "a++ * a++" is officially undefined behaviour.

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