当函数fun()在main()上面定义时,变量'a'不能通过预处理器宏解析,但在main()下定义时工作正常。
#include <stdio.h>
void fun()
{
printf("%d",a);
}
int main()
{
#define a 5
fun();
return 0 ;
}
背后的原因是什么?我们怎样才能使它工作,这样我就不必移动函数fun()定义。
答案 0 :(得分:5)
C预处理器运行自上而下并替换#define
s(&#34;文本替换&#34;)。因此,当#define a 5
中的main()
时,它可以“返回”#34;并替换a
中的func()
;它只能替换a
以下的#define
,如果有的话。
您只需要在func()
上方定义它。
来自C11 draft, 6.10.3 Macro replacement:
表单
的预处理指令# define identifier replacement-list new-line
定义一个类似于对象的宏,导致每个后续实例 要替换的宏名称 171 ) 构成其余部分的预处理令牌列表 指示。然后重新扫描替换列表以获取更多宏名称 如下所述。
自标准前C以来,情况相同。来自Dennis Ritchie's C Reference Manual:
12.1令牌替换格式为
的编译器控制行#define identifier token-string
(注意:没有尾随分号)会导致预处理器被替换 具有给定字符串标记的标识符的后续实例 (编译器控制线除外)。替换令牌字符串 有评论从中删除,它被空白包围。没有 尝试重新扫描替换字符串。
(强调我的)。
答案 1 :(得分:4)
当然,在定义预处理器宏之前,你不能引用预处理器宏,而不是它的工作方式。
没有&#34;变量&#34;在这里,你对这个词的使用非常混乱。预处理器只是进行文本替换,编译器永远不会看到a
符号,而是会看到5
(如果定义了宏)。
我不知道如何让它发挥作用&#34;因为目标很奇怪。如果要访问全局变量,请使用:
#include <stdio.h>
int fun(int x)
{
extern int a;
return a + x;
}
int a = 12;
int main(void) {
printf("a=%d, fun() returned %d\n", a, fun(11));
return 0;
}
此处extern
让我们在a
之后定义fun()
,但它不能在main()
内。
答案 2 :(得分:3)
预处理器将在宏定义之后将a
的任何实例替换为5。您可以将#define行放在函数上方。
作为旁注,void fun()
{
printf("%d", 5);
}
不是变量,预处理器只会在编译之前进行文本替换。
{{1}}
答案 3 :(得分:3)
预处理步骤在编译步骤之前完成。而且,预处理器不知道C;对于预处理器,源文件只是文本。
在您的示例中,函数fun()
中使用的符号a
在使用前未声明,这是一个错误。在fun()
的预处理器定义中,有一点无关紧要。由于定义更进一步,它不适用于<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillAfter="true">
<translate
android:fromXDelta="-4%p"
android:toXDelta="4%p"
android:repeatCount="2"
android:repeatMode="reverse"
android:duration="10" />
</set>
的主体:永远记住,对于proeprocessor,源文件只是文本,它不知道C.预处理指令适用于它们出现在的位置文字,从未有过。