在写程序时经常会碰到这样一个问题,我们需要重复写很多相同的代码,并且这些代码结构相同。总是想自己把这段代码封装一下然后直接进行调用,但是如果这段代码逻辑并不复杂,并且代码量也不大,不适合进行封装,那么我们就会想到c++中的关键字define。其实明智的你,遇到上面的这些情况估计还会想到另一个东西----template,后面我们也会说一下两者的却别。今天自己看了一下c++ define的相关知识,做个记录。

  1.什么是define: 宏定义,简单的理解就是替换,其实这也是本质。如果熟悉g++编译过程的话,会了解到一个概念叫做预处理,就是在编译之前做个处理。这个过程并不像编译那么复杂,就是简单的递归替换和删除。替换的就是宏定义和include文件,删除注释。注意这里我们谈到一个概念,递归替换,这个其实是很常见的,比如你的程序中include一个.h文件,但是这个.h文件中还引入了另一个.h文件,那么这个时候就需要进行递归替换。这个我们自己查看一下究竟预处理都干了些什么?(为了减少预处理之后的代码我们不引入其他文件)

 这样我们就更好的理解define的作用和预处理的作用了。

  2.define的使用方法:

  • 简单使用:define identifier replacement-list(optional)   这是最基本的使用方法,就像上面我们的例子一下,在预处理的时候将identifier替换成replacement-list(optional)。比如:在开发程序的时候会定义很多错误码,比如使用22表示图片上传成功,如果我们这样进行判断assert(result==22)。看似是没什么问题,那么要是你看了谁的代码是这样写的,你会怎么想?谁写的,这22是什么意思? 这时候就需要我们给22起一个别名,例如: #define Success = 22
  • 带参形式:除了上面的使用方法我们还可以给定参数来进行宏定义,比如:
    #include<iostream>
    #include<string.h>
    //定义了一个宏,将A,B进行连接
    #define Append(A,B) A+B;
    using namespace std;
    int main(int argc, char *argv[])
    {   string test1 = "1";string test2 = "2";//进行宏定义的调用cout<<Append(test1,test2);return 0;
    }

从这个例子我们可以看出宏定义的好处之一:可以在一定程度上忽略宏定义中参数的类型,这一点是不是和template很相似,我们使用template来重写一下上面的这段代码:

#include<iostream>
#include<string.h>
using namespace std;
//定义模板方法
template<class T>
T append(T a,T b){return a+b;
}
int main(int argc, char *argv[])
{string A = "1";string B = "2";//使用模板方法cout<<append(A,B);      return 0;
}
  • 这里我们是不是会觉得在这种情况下面宏定义与template是一致的?其实并不是,我们考虑一下下面的这种情况,假设存在这样一个宏定义#define add(a,b) a+b,并且在代码中调用过程是这样的a*add(a,b)*b;大家可以想想结果是多少?答案是5,而不是我们预期的6,原因很简单,这只是简单的替换,经过预处理之后的结果是a*a+b*b。但是template运算的结果就是6,这就是差别。所以在使用的时候还是应该考虑是选择template还是define。

  • define中代码段的表示: 上面我们说到的宏定义都是简单的一条语句,如果我们需要定义一个稍微复杂一点的语句呢?比如:我们习惯,或者说是个人习惯,喜欢把一些判断语句进行宏定义,比如我们在进行一个功能错误码的校验的时候通常希望能够将代码和log日志分开,使得代码显得不那么凌乱,那么我们将会定义一个稍微复杂一点的宏定义。

#include<iostream>
#include<string.h>
//宏定义一个MaxName
#define MaxName 10
//宏定义   定义了一个判断条件用于识别图片上传之后的返回码 并输出日志条件
#define AssertReturnValue(name,result)do{\if(result==0)\cout<<"图片"<<name<<"上传成功";\
}while(0)
using namespace std;
class Picture
{
public:Picture (const char *path,const char *file){strcpy(this->path,path);strcpy(this->file,file);}~Picture (){}private:char file[MaxName];char path[MaxName];
};
int uploadPicture(const Picture picture)
{cout<<"成功";return 0;
}
int main(int argc, char *argv[])
{Picture picture("100","100");int result = uploadPicture(picture);//调用结果判断宏定义AssertReturnValue("100",result);return 0;
}这里我们应该注意一下,代码段的宏定义的写法。
条件宏定义ifdef:可以在编译的时候通过#define设置编译环境,语法结构
//不同的运行环境,不同的头文件
#ifdef OS_Win
#include <windows.h>
#endif#ifdef OS_Linux
#include <linux.h>
#endif

下面我们将c++ 常用的宏定义罗列一下:

#空指令,无任何效果
#include包含一个源代码文件
#define定义宏
#undef取消已定义的宏
#if如果给定条件为真,则编译下面代码
#ifdef如果宏已经定义,则编译下面代码
#ifndef如果宏没有定义,则编译下面代码
#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个#if……#else条件编译块
#error停止编译并显示错误信息

c++define的用法相关推荐

  1. typedef和#define的用法与区别

    typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...

  2. C语言中#define的用法(转)

    转自:http://www.dingge.com/main/article.asp?id=10 今天整理了一些#define的用法,与大家共享! 1.简单的define定义 #define MAXTI ...

  3. php中define的参数_php中define的用法有哪些

    php中define的用法:1.[define()]函数定义一个常量:2.定义常量名称及值,代码为[define(name,value,case_insensitive)]:3.定义一个大小写敏感的常 ...

  4. #define c# 报错_c语言中#define的用法

    c语言中#define的用法 C语言中,可以用 #define 定义一个标识符来表示一个常量.其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了. 预编译又叫预处理.预编译 ...

  5. C++中 #define的用法

    C++中 #define的用法 转自:http://blog.csdn.net/lyl_98/article/details/900158 今天整理了一些#define的用法,与大家共享! 1.简单的 ...

  6. #define的用法

    #define的用法 #define的用法 #define 又称宏定义.用法:通过#define命令用一个指定的标识符代表一个字符串,这个标识符称为宏名.将程序中出现的与宏名相同的标识符替换字符串的过 ...

  7. C++ define的用法

    #define是预处理指令,说到这里,我们有必要说一下C++常见的预处理指令: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给 ...

  8. C语言#define的用法,C语言宏定义

    #define 叫做宏定义命令,它也是C语言预处理命令的一种.所谓宏定义,就是用一个标识符来表示一个字符串,如果在后面的代码中出现了该标识符,那么就全部替换成指定的字符串. 我们先通过一个例子来看一下 ...

  9. c语言define需要分号骂,C语言中define的用法

    C语言中define的用法 2016-01-06 15:00  来源: 博客园 define是C语言中的预处理命令,它用于宏定义,可以提高源代码的可读性,为编程提供方便. 预处理命令以"#& ...

  10. C语言define高级用法大全

    今天在看代码时,突然发现很多define的用法看不懂,故在此总结一下,顺便吐槽一下,C语言的宏复杂起来真的很难看懂. 不信的去看下这个的源码:[C语言开源库]lw_oopc:轻量级的C语言面向对象编程 ...

最新文章

  1. 【C语言】算数操作符 移位操作符 以及 sizeof单目操作符讲解
  2. 人民日报钟声:以和平合作守护世界安全
  3. TypeScript void 和 undefined 的区别
  4. css 选择href属性值,巧用CSS属性值正则匹配选择器(小技巧)
  5. NetBios 的结构体详解(网络控制块NCB)
  6. 服務端的EIT造形+Socket代碼
  7. SQL 導入導出大全
  8. junit mockito_Mockito存根异常– JUnit,TestNG
  9. addEventListener和attachEvent二者绑定的执行函数中的this不相同【转载】
  10. 人脸识别常用数据集大全
  11. 计算机毕业设计之 [含论文+答辩PPT+任务书+中期检查表+源码等]S2SH动漫论坛[包运行成功]
  12. html小写罗马字符怎么写,如何在 LATEX 中插入大小写的罗马字符
  13. 小米便签源码分析——data包
  14. msvcp140.dll丢失的解决方法_msvcp140.dll丢失怎样修复win10
  15. 群晖域名注册_小白瞎折腾 篇九:玩转群晖NAS:域名注册技巧,及SSL证书获取...
  16. gin结合endless实现热更新
  17. #import msxml3.dll 导致 LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  18. dell进入u盘启动模式_如何调整戴尔电脑硬盘模式设置U盘第一启动
  19. #优质代码# Map按Value降序排序,Value相同时按Key排序
  20. Git分支 查看branch 创建 切换checkout 合并merge(先切回主分支) 删除branch -d 推送push

热门文章

  1. php双写绕过,PHP preg_系列漏洞小结
  2. FNDLOAD命令整合
  3. 抠图:基于单个原色通道
  4. Windows系统下CMD命令
  5. ubuntu 安装多版本cuda,及切换版本方法及常见问题记录
  6. JavaScript如何输入输出之如何使用JavaScript优雅编程
  7. ERP编制物料清单 金蝶
  8. 图片自适应父元素大小,并左右上下居中的css方法
  9. Java-栈的基本操作
  10. 可控制导航下拉方向的jQuery下拉菜单代码