当前位置: 首页 > news >正文

良品铺子网站制作上海建设工程造价协会官网

良品铺子网站制作,上海建设工程造价协会官网,小型企业网站建设方案,流量主小程序怎么赚钱目录 前言#xff1a; 1. 预定义符号 2. #define定义常量 3. #define定义宏 4. 带有副作用的宏参数 5. 宏替换的规则 6. 宏和函数的对比 7. #和## 8. 命名约定 9. #undef 10. 命令行定义 11. 条件编译 12. 头文件的包含 13. 其他预处理指令 总结#x… 目录 前言 1. 预定义符号 2. #define定义常量 3. #define定义宏 4. 带有副作用的宏参数 5.  宏替换的规则 6. 宏和函数的对比 7. #和## 8.  命名约定 9.  #undef 10.  命令行定义 11.  条件编译 12.  头文件的包含 13.  其他预处理指令 总结。 前言 本篇介绍c/c的预处理过程c和c在预处理阶段基本相同。 1. 预定义符号 c语言定义了一些预处理的符号这些是可以直接使用的并且这些符号也是在预处理期间完成的。 __FILE__ //进⾏编译的源⽂件 __LINE__ //⽂件当前的⾏号 __DATE__ //⽂件被编译的⽇期 __TIME__ //⽂件被编译的时间 __STDC__ //如果编译器遵循ANSI C其值为1否则未定义 2. #define定义常量 例如我们定义100为一个MAX后面使用MAX都会在预处理阶段替换为100。 #define MAX 100如果我们觉得定义的东西太长了也可以分行写在结尾加上反斜杠\即可 #define DEBUG_PRINT printf(file:%s\tline:%d\t \date:%s\ttime:%s\n ,\__FILE__,__LINE__ , \__DATE__,__TIME__ )现在来考虑一个问题 在定义常量的时候要不要加上引号 #define MAX 1000; #define MAX 1000 其实通过#define的性质就可以知道它在预处理阶段做的只是替换工作如果将代码放到下面的情况下就会出错 if(condition)max MAX; elsemax 0; 这样if后面就是两条语句了而由于if如果不加大括号匹配的只有一条语句所以这样else就没法匹配了就出错了。 3. #define定义宏 #define机制包括了一个规定允许把参数替换到文本中这种实现通常称为宏macro或定义宏define macro。 语法为 #define name( parameter-list ) stuff 注意参数列表的括号必须要与name之间没有空格不然参数列表就被识别为右边的内容了。 例如我们现在实现一个宏来实现乘法 #define SQUARE( x ) x * x 可这样能表达我们想要的意思吗 我们要注意宏仅仅是替换所以在打印下面的情况下就会出错 int a 5;printf(%d\n, SQUARE(a 1));//结果是11我们想表达的是51*51而结果却是11这就是因为宏仅仅是替换只是替换为了a1*a1所以我们加上扩号就能达到预期的效果了。 #define SQUARE(x) (x)*(x)可这就完了吗来看下面的代码我们使用宏了实现一个相加 #define DOUBLE(x) (x) (x) 看着我们好像加上了括号好像就不会出现问题了但是如果是下面的场景 int a 5; printf(%d\n ,10 * DOUBLE(a));//结果是55而我们预期的是100 这是因为预处理阶段宏被替换成了10*(5)(5)所以我们还需要再加上一个括号   1 #define DOUBLE( x) ( ( x ) ( x ) ) 所以我们得出结论 所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。 4. 带有副作用的宏参数 #define MAX(a, b) ( (a) (b) ? (a) : (b) )int x 5;int y 8;int z MAX(x, y);printf(x%d y%d z%d\n, x, y, z);这样带有自增自减的是具有副作用的再给宏传参就出错了。 结果是 x6,y10,z9尽管最后执行的是z(y)后置--改变的是自己返回的是一个没有改变的值所以这里z是9这样的结果不仅对xyz进行了永久性的改变而且比较是也不是预期的结果。 所以当宏参数在宏的定义时出现超过了一次就像上面的案例如果参数带有副作用也就是自增自减类的此时使用宏就可能出错。 5.  宏替换的规则 在程序中扩展#define定义符号和宏时需要涉及几个步骤。 1. 在调用宏时首先对参数进行检查看看是否包含任何由#define定义的符号。如果是它们首先被替换。 2. 替换文本随后被插入到程序中原来文本的位置。对于宏参数名被他们的值所替换。 3. 最后再次对结果文件进行扫描看看它是否包含任何由#define定义的符号。如果是就重复上述处理过程。 注意 1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏不能出现递归。 #define string1 string #define string 1abcdprintf(%s\n, string);printf(%s\n, string1);2. 当预处理器搜索#define定义的符号的时候字符串常量的内容并不被搜索也就是说定义的符号不能是字符串常量。 6. 宏和函数的对比 宏通常用来执行简单的计算。比如在两个数中找出一个较大的时写成下面的宏更有优势 #define MAX(a, b) ((a)(b)?(a):(b)) 为什么不用函数来实现呢 1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜⼀筹。 2. 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏可以适用于整形、长整型、浮点型等可以用于 来比较的类型。宏的参数是类型无关。 但是相比函数宏也有它的劣势 1. 每次使用宏的时候一份宏定义的代码将插入到程序中。除非宏比较短否则可能大幅度增加程序的长度。 2. 宏是没法调试的。 3. 宏由于类型无关也就不够严谨。 4. 宏可能会带来运算符优先级的问题导致程容易出现错。 但其实宏也可以做到函数做不到的事情例如宏的参数可以出现类型但是函数做不到 #define MALLOC(num, type)\(type*)malloc(num*sizeof(type))//使⽤MALLOC(10, int);//类型作为参数 //预处理器替换之后(int*)malloc(10*sizeof(int)); 宏和函数的对比 7. #和## #运算符是将宏的一个参数转换为字符串字面量它运行出现在带参数的宏的替换列表中。 #define PRINT(n) printf(the value of #n is %d, n); 如果定义有一个a为10现在使用宏传a过去就打印出来the value of a is 10 注意这里#n要加上一个引号不然就被识别为printf打印的内容了就直接打印出来一个#n而不是预处理得到的了。 就理解为如果#n要在printf里识别为字符串就要加上。而直接这样使用就不用 #define PRINT(n) #nint a10; printf(%s\n,PRINT(a));//结果是a ##运算符 //宏定义 #define GENERIC_MAX(type) \ type type##_max(type x, type y)\ { \return (xy?x:y); \ }GENERIC_MAX(int) //替换到宏体内后int##_max ⽣成了新的符号 int_max做函数名 GENERIC_MAX(float) //替换到宏体内后float##_max ⽣成了新的符号 float_max做函数名int main() {//调⽤函数int m int_max(2, 3);printf(%d\n, m);float fm float_max(3.5f, 4.5f);printf(%f\n, fm);return 0; } 实际用的很少不再过多解释。 8.  命名约定 一般来说函数和宏的使用语法是很相似的所以语言本身没法帮我们区分二者。 所以命名习惯就是 宏名全部大写函数名不要全部大写。 9.  #undef 用于移除一个宏定义。 #undef NAME //如果现存的⼀个名字需要被重新定义那么它的旧名字⾸先要被移除。 10.  命令行定义 许多C 的编译器提供了⼀种能力 允许在命令行中定义符号。用于启动编译过程。 例如当我们根据同⼀个源文件要编译出⼀个程序的不同版本的时候这个特性有点用处。假定某个程序中声明了⼀个某个长度的数组如果机器内存有限我们需要⼀个很小的数组但是另外一个机器内存大些我们需要一个数组能够大些。 #include stdio.h int main() {int array [ARRAY_SIZE];int i 0;for(i 0; i ARRAY_SIZE; i ){array[i] i;}for(i 0; i ARRAY_SIZE; i ){printf(%d ,array[i]);}printf(\n );return 0; } //linux 环境演⽰ gcc -D ARRAY_SIZE10 programe.c11.  条件编译 在编译⼀个程序的时候我们如果要将⼀条语句⼀组语句编译或者放弃是很⽅便的。因为我们有条件编译指令。 调试性的代码删除可惜保留⼜碍事所以我们可以选择性的编译 #include stdio.h #define __DEBUG__ int main() {int i 0;int arr[10] { 0 };for (i 0; i 10; i){arr[i] i; #ifdef __DEBUG__printf(%d\n, arr[i]);//为了观察数组是否赋值成功。 #endif //__DEBUG__}return 0; } 如果我们不定义__DEBUG__这个宏就什么也不会输出。 常见的条件编译指令 1. #if 常量表达式//... #endif //常量表达式由预处理器求值。 如 #define __DEBUG__ 1 #if __DEBUG__//.. #endif 2.多个分⽀的条件编译 #if 常量表达式//... #elif 常量表达式//... #else//... #endif 3.判断是否被定义 #if defined(symbol) #ifdef symbol #if !defined(symbol) #ifndef symbol 4.嵌套指令 #if defined(OS_UNIX)#ifdef OPTION1unix_version_option1(); #endif#ifdef OPTION2unix_version_option2();#endif #elif defined(OS_MSDOS)#ifdef OPTION2msdos_version_option2();#endif #endif12.  头文件的包含 首先查找策略 先在源⽂件所在⽬录下查找如果该头⽂件未找到编译器就像查找库函数头⽂件⼀样在 标准位置标准路径查找头⽂件。如果找不到就提⽰编译错误。 linux下标准头文件的路径 /usr/include windows下按照自己的安装路径去找 C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include 然后就是库文件的包含 1 #include filename.h 查找头文件直接去标准路径下去查找如果找不到就提示编译错误。 当然库文件也可以使用的形式包含答案是可以的但是这样不容易区分是库文件还是本地文件查找的效率会低尖括号是到系统路径下查找头文件双引号是先在当前目录下查找头文件如果没有找到就再到系统的路径下去找。  嵌套文件的包含 #include的替换方式就是预处理器先删除这条指令并用包含文件的内容替换但如果一个头文件被包含了10次那实际就被编译了10次如果重复包含对编译的压力就会比较大因为.h的文件会将内容拷贝10分到.c文件中去这样预处理后代码量就会激增。如果有工程比较大用公共使用的头文件被大家都能使用又不做处理工程量会非常大。 如何解决使用条件编译 可以在每个头文件中的开头写 #ifndef __TEST_H__ #define __TEST_H__//头⽂件的内容#endif //__TEST_H__写在头文件结尾 也就是如果.h文件第一次被包含此时__TEST_H__还没有被定义所以执行#ifdef与#endif之间的代码再次包含时条件为假因为以及有__TEST_H__的定义了所以直接走到#endif也就是什么也不执行。  或者 #pragma once 13.  其他预处理指令 #error #pragma #line ...... 具体可以用到的时候再查。 注 推荐《⾼质量C/C编程指南》中附录的考试试卷很重要。 笔试题 1. 头⽂件中的 ifndef/define/endif是⼲什么⽤的? 2. #include filename.h 和 #include filename.h 有什么区别? 总结 对于一些预处理阶段的一些不常用的可以选择性学习但要知道重点关注面试题相关的。
http://www.hkea.cn/news/14436332/

相关文章:

  • 个人可以备案网站的内容装修3d效果图怎么制作
  • 福州企业制作网站线上推广是什么意思
  • 南京 网站建设淘宝指数查询官网手机版
  • 泰州哪家网做网站广西桂林旅游必去十大景点
  • 服务提供网站北京朝阳区天气预报
  • 网站优化策略网站搭建推广优化
  • 网站后台表格搭建网站的大致流程
  • 河南网站优化要多少钱网络销售网站外包
  • 电子商务网站开发教程课后习题企业网站制作与维护
  • 西安网站建设企业佛山网站建设专业公司
  • 公司网站建设怎么协调内容与保密宁波城乡建设局网站
  • wap建站工具网页微博怎么下载视频
  • php网站模板开源虫部落导航网站怎么做
  • 网站设计概述500字企业自助建站程序
  • 山东经济建设网站河南省精品旅游线路发布
  • 遵义新蓝外国语学校网站建设3322做网站
  • 企业建站系统免费竞价如何屏蔽恶意点击
  • 北京市建设工程质监站网站免费咨询心理情感专家
  • 自己的网站怎样做优化wordpress主题授权系统
  • 门户网站建设招标书云主机建网站软件
  • 岳阳网站推广国内专业seo公司
  • 做行程好的网站wordpress子主题插件
  • 莱西市城乡建设局网站招标网站哪个比较好
  • git做网站根目录票务网站开发端口
  • 行业网站建设网站快照优化公司
  • 高端网站建设与发展wordpress本地网站上传
  • 网站建设一般要多钱品牌推广图片
  • 长治市建设厅官方网站制作免费网站的平台
  • ps软件下载官方网站长春做网站选长春万网
  • 建站前期准备新乡市建设路小学网站