C 编程#define?
#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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在同一变量上使用多个 ++ 运算符的表达式的结果在 C 中正式是一种未定义行为。
The result of an expression with more than one ++ operator on the same variable is officially an undefined behavior in C.
#define
是一条指示预处理器的指令,用于将宏的每次出现逐字替换为其扩展。因此,代码中的相关行将传递给编译器,如下所示:正如 Seva 所说,这些表达式正式未定义;但即使我们采取可以说是最明智的阅读方式,您仍然会得到
b1 = 2 * 3;
和b2 = 3 * 4;
(两者都a1
和a2
在行后设置为 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: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;
andb2 = 3 * 4;
(with botha1
anda2
set to 4 after the lines.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.
因为定义只是替换了表达式。所以你得到结果:
所以,你得到了两次双倍增量。它会导致未定义的行为。
because define just replaces the expression. so you get in result:
So, you get double increment twice. It results in undefined behaviour.
恭喜!您刚刚发现了为什么在此类事情上使用宏是一个坏主意。作为一般规则,只有在无法使用函数完成的情况下才将其设为宏。在这种情况下,
SQ
可以轻松地实现为函数: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:将宏中的操作数括在括号之间:
另外,尽量不要在同一个赋值中使用 x++ 和 x 进行操作。可能导致未定义的行为。
干杯!
Wrap the operands in the macro between parenthesis:
Also, try not to operate with x++ and x in the same assignment. Could lead to undefined behavior.
Cheers!
这些行
扩展到
调用未定义的行为(对象的值在序列点之间最多可以修改一次),这意味着任何结果都被认为是“正确的”。
这就是这类宏的问题;您确实希望对参数求值一次,但由于扩展,它会被求值两次。
表达式来调用它也存在问题
使用像This will Expand to
这可能不是你想要的 。为了保持运算符优先级,扩展应该包裹在
()
中,例如The lines
expand to
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
This will expand to
which is probably not what you wanted. To preserve operator precedence, the expansion should be wrapped in
()
, such as查看代码,因为它将由预处理器扩展:
这是未定义的行为,因为您多次修改一个变量,而它们之间没有序列点。
Look at the code as it will be expanded by the preprocessor:
This is undefined behavior, because you are modifying a variable more than once without a sequence point between them.
我真的不知道你的问题是什么,但也许你的预期输出有问题......
请注意,#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.