百科问答小站 logo
百科问答小站 font logo



#define 不是简单的替换吗,为什么下面的代码错误? 第1页

  

user avatar   sun-ruo-xi 网友的相关建议: 
      

预处理(宏展开)是在词法分析做完之后实施的,词法分析后的结构是一个一个的token,此时OP和=是两个token,宏展开后依然是两个token。而如果没有用宏而是写成*=,词法分析会把他们识别成一个token,即乘等操作符。希望题主能够理解这个意思。

更新一发评论中的回答:

词法分析器不是通过加空格来划分token的(事实上不做词法分析他又怎么知道要在哪里加空格呢?),他有自己的一套规则。对你这个例子,他遇到O后会认为这是一个标识符token的开头(标识符是字母数字下划线组合,且不能数字开头),继续往前找直到遇到一个不满足标识符规则的字符,=不满足所以断到=前面,如果是空格也是一样断,于是识别出的token是一个内容为OP的标识符。同样的道理,如果你写的是OPabcd,那么就会断到d后面,然后识别出的token就是一个内容为OPabcd的标识符,结果就是你并不会看到他被展开成*abcd。以上要说的就是宏展开是基于词法分析得到的token流而不是直接在原始C代码上做的简单字符替换。

最后教你一招:

#define OP(o) *##o

使用时,如果想用乘等:

a OP(=) b;

如果想用乘:

c = a OP() b;

gcc上可以,不保证别的编译器也能编过。

手机敲代码累死。。。


user avatar   be5invis 网友的相关建议: 
      

#define 的替换是在「词语」的层面进行的,所以替换结果是类似于「a * = 3」(注意那个空格),当然出问题了




  

相关话题

  Objective-C 的一些函数名为什么都这么长? 
  C++20有哪些让你激动不已的新特性? 
  为什么C语言中计算机认为0是假的,其他数都是真的? 
  C/C++中的数组为什么必须定义之后在一行内立刻赋值,而不能定义数组之后换一行再赋值? 
  C# 和 Java 哪个更像 C++? 
  c#中没有友元类那么这种设计是否不太合理,如何修改才能得到更好的方案? 
  C语言能判断一个变量是int还是float吗? 
  游戏程序员必须要修 C# 吗?我徘徊在先开始 C++ 还是 C# ? 
  C语言中,为什么指向指针的指针的类型是int **?类型的话直接int*不就行了? 
  同样用pow()表示10^2,为什么分别用字面量和变量作参数会返回不同的值? 

前一个讨论
为什么没有显存条?
下一个讨论
JavaScript中对 function 的参数进行重新赋值的影响?





© 2025-04-24 - tinynew.org. All Rights Reserved.
© 2025-04-24 - tinynew.org. 保留所有权利