c/c++ #define中#和##运算符的使用

本文详细介绍了C语言预处理器中的高级特性,包括如何在#define宏定义中使用参数、#运算符实现字符串化以及##运算符的功能与应用。通过具体实例展示了这些特性的使用方法。

1.在#define中使用参数

  函数调用和宏调用之间的重要差异,程序运行时,函数调用把参数的值传递给函数。而编译前,宏调用把参数的语言符号传递给程序。

2.#运算符:利用宏参数创建字符串

  如果x是一个宏参数,那么#x可以把参数名转换为相应的字符串,该过程称为字符串化。

#include <stdio.h>

#define POUT(x) printf("---" #x "---\n")

int main()
{
    POUT(Test_Define_# .);    
    return 0;
}
---Test_Define_# .---

3.##运算符:预处理器的粘合剂

  这个运算符把两个语言符号组合成单个语言符合。

#include <iostream>

#define INT(x) nTmp##x

int main()
{
    int INT(1) = 0;
    std::cout<<INT(1)<<std::endl;
    return 0;
}
0
//#include<iostream> //using namespace std; ////别名替换 ////#define A B // //#define 整数 int //整数 a{ 100 };//可以是中文字母,但是不能是数字、符号等。示例:12325。#$%(); // //#define _hhh_ int b=250;//define 在替换上会有点无脑,这里以后只要是输入 _hhh_ 都会替换成 int b; // //#define VERSION "2.0.1"//好处是我在“用的地方多了,在这改内容,可以直接作用到输出这个变量名内” //#define SCREEN_WIDTH 1980//声明常量,这个表达情况在C语言中用得比较多 //const int screen_width{ 1980 };//这个是在C++用得比较多,也是常量声明 // ////#define int float ////#define true false//用得太广泛,连true都可以变改,这里的话,容易不安全,在define的常量申明替换,容易不安全 // //#define X //相当于X不存在了,去作为一种替换 //#define UNICON //定义UNICON的用法 // //#define _in_ //#define _out_ //这两个的意义都是关于标识, int ave(_in_ int a,_out_ int& b),告诉别人这个是输入,输出,没有太大意义 ////#define functionptr //定义一个指针int ave(_in_ int a,functionptr int& b)这里也是修饰符号的作用 // ///*int ave( _in_; int f, _out_ int& g) //{ //return a+b //};*/ // // //#define TEXT //int main() { // // // cout <<a<< " "<<endl; // // _hhh_{ 250; }//发现个问题 // cout << b<< " " << endl; // // cout << VERSION<<" "<<endl; // cout << SCREEN_WIDTH << " " << endl; // cout << screen_width; // // int X a{ 2500 };//当中的X相当于不存在 等同于 int a{2500} // // int TEXT A{ 250 }; // #undef TEXT // //int TEXT A{ 250 };//第三种用法就是undef会关停这个TEXT,但是不影响其他的 //} //定义复杂表达的宏 #include<iostream> using namespace std; #define SUM(X,Y) X+Y*3; #define RELEASE(x) delete[]x,x=nullptr; #define BIGGER(X,Y)((X)>(Y)?(X):(Y)) #define SHOW1(X)std::cout<<#X//用这个输出直接就是字符串 #define SHOW(X,Y) void X##Y(){std::cout<<#X;}//声明函数使用 //发现这里的define的应用,表达时不是表达式 SHOW(text,22)//这里是直接声明了个函数 int main() { cout << SUM(100, 200)" ";//这个不是函数,是直接表示计算 //cout << SUM(100, 200) << " " << endl;//这里这种表达需要表达式,怎么回事 int* a = new int[50]; RELEASE(a)" ";//可以很好的全局应用 //delete[]a; //a = nullptr; std::cout << BIGGER(100, 200)<<" "; SHOW1(1234687454565)" "; text22(); } 当中的两组代码,的注释理解都对吗,请帮助分析总结,因为我是个新手学员,搞不懂,请麻烦解释分析,帮助我理解底层逻辑,让我对deffine的理解通俗易懂,帮助我彻底理解整个他的内容
07-22
C++中,`#define` 是预处理指令之一,用于定义宏(macro),它在编译前的预处理阶段被处理。宏可以用于定义常量、函数式宏、字符串化操作、连接操作符等,其核心机制是**文本替换**。这种替换是直接的、机械的,不涉及类型检查或语法分析,因此需要开发者格外小心使用### 宏定义常量 宏可以用来定义常量,这种方式在C++中仍然被广泛使用,尤其是在需要跨平台兼容或配置选项时。 ```cpp #define PI 3.14159 ``` 在预处理阶段,所有出现 `PI` 的地方都会被替换为 `3.14159`。这种方式定义的常量没有类型信息,也不受命名空间限制,容易造成命名冲突。 ### 宏替换与函数式宏 宏可以带参数,模拟函数的行为,称为函数式宏。例如: ```cpp #define SQUARE(x) ((x) * (x)) ``` 当使用 `SQUARE(5)` 时,预处理器会将其替换为 `((5) * (5))`。注意括号的使用,防止因运算符优先级问题导致错误。例如,若写成 `#define SQUARE(x) x * x`,在 `SQUARE(2 + 3)` 中会被替换为 `2 + 3 * 2 + 3`,结果为 `11` 而非预期的 `25` [^3]。 宏替换过程是递归的:在替换过程中,如果替换文本中又出现了其他宏定义的标识符,它们也会被继续替换,直到没有宏定义为止 [^4]。 ### 字符串化操作符 `#` 字符串化操作符 `#` 可用于将宏参数转换为字符串字面量: ```cpp #define STR(x) #x ``` 使用 `STR(Hello)` 会替换为 `"Hello"`。这个特性在调试输出或日志记录中非常有用。 ### 连接操作符 `##` 连接操作符 `##` 用于将两个标记(token)连接在一起,形成一个新的标记: ```cpp #define CONCAT(a, b) a##b ``` 使用 `CONCAT(var, 1)` 会替换为 `var1`,这在生成变量名或函数名时非常有用。 ### 宏定义的底层逻辑 宏定义的处理过程发生在编译之前,由预处理器负责。其处理流程大致如下: 1. **参数替换**:首先替换宏参数为实际传入的值。 2. **嵌套宏替换**:替换过程中如果发现新的宏定义标识符,会继续替换,直到所有宏都被展开。 3. **最终文本插入**:替换后的文本插入到原代码位置,形成最终的源代码供编译器处理 [^3]。 需要注意的是,宏定义不遵循C++的作用域规则,也不进行类型检查,因此容易引入难以调试的错误。 ### 示例代码 以下是一个综合示例,展示宏定义在实际代码中的效果: ```cpp #include <iostream> #define PI 3.14159 #define SQUARE(x) ((x) * (x)) #define STR(x) #x #define CONCAT(a, b) a##b int main() { std::cout << "PI = " << PI << std::endl; std::cout << "SQUARE(5) = " << SQUARE(5) << std::endl; std::cout << "Stringified: " << STR(Hello World) << std::endl; int var1 = 100; std::cout << "Concatenated variable: " << CONCAT(var, 1) << std::endl; return 0; } ``` ### 注释是否正确? 宏定义的注释应特别注意,因为宏本身不会被编译器解析,注释应清晰说明宏的功能、参数含义以及潜在的副作用。例如: ```cpp // 定义一个宏用于计算平方,注意参数应加括号避免优先级问题 #define SQUARE(x) ((x) * (x)) ``` 这样的注释有助于其他开发者理解宏的设计意图使用方式。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值