吴江建设局网站打不开建设工程检测网
吴江建设局网站打不开,建设工程检测网,wordpress开启cdn,网页设计与制作教程第二版答案0. Overview C的预处理指令格式为#name#xff0c;均以#开头#xff0c;#和指令名之间不可有空白字符#xff0c;#前可以有空字符#xff0c;但为增强可读性#xff0c;一般应从第一列开始 #name不能由宏展开得来#xff0c;name也不能由宏展开得来#xff0c;如 // Wro…0. Overview C的预处理指令格式为#name均以#开头#和指令名之间不可有空白字符#前可以有空字符但为增强可读性一般应从第一列开始 #name不能由宏展开得来name也不能由宏展开得来如 // Wrong 1
#define INC #include
INC stdio.h
// Wrong 2
#define INC include
#INC stdio.h 预处理指令只能占一行但是在写代码时可以用\分隔多行但处理时仍会将这多行合为一行。有些指令带参数参数需与指令由空白字符分隔 预处理指令主要提供下列功能 引入头文件宏展开条件编译line control#line感觉一般人用不着诊断diagnostics可在编译器检查程序发出errors或warnings1. 头文件 用#include来包含头文件该指令的参数形式有两种 #include file 用于系统头文件。Preprocessor将在a standard list of system directories下搜寻文件file可以用编译器的-I选项来将目录添加到这个list#include file 用于程序自身的头文件。Preprocessor的搜寻顺序如下 a. 先在包含该文件的当前目录搜寻文件file b. 然后在quote directories中搜寻可以用编译器的-iquote选项来将目录添加到quote directories中 c. 最后再在用于搜寻file的目录下搜寻即 1. 中的顺序所以用#include stdio.h只要你不覆盖这个头文件的话也不会出现问题总能找着#include的参数无论是用还是括起来都如同一个字符串里面的注释不会被识别宏也不会展开。但是不同于字符串的是backslash不再有转义作用而是一个单纯的字符\ 在这一行文件名参数后面除了注释外不能有任何其他内容 只包含一次 Once-Only Headers 如果一个头文件被include两次编译器就会处理两次因此可能会出错如重定义等等标准做法是用所谓的wrapper #ifndef将头文件的内容包起来如 /* File foo. */
#ifndef FILE_FOO_SEEN
#define FILE_FOO_SEENthe entire file#endif /* !FILE_FOO_SEEN */ 代码片段中的宏FILE_FOO_SEEN叫做controlling macro或者guard macro在用户程序头文件中该宏的名字不能以_开头在系统头文件中该宏的名字需要以__双下划线开头以免与用户程序头文件冲突。在任意类型的头文件中该宏的名字应该包含头文件文件名再加上额外的文字以避免与其他头文件冲突 2. 宏 Macros 宏是赋予名字的一段代码每次使用时都将名字替换成宏内容。宏分为两种它们在使用时有很大的不同 Object-like macros使用时像用data objects一样Function-like macros使用时像函数调用一样2.1 对象形式的宏 Object-like macros Object-like macro就是一个简单的标志符表示一个代码片段在使用时由这个代码片段来替换用法 #define NAME macro_body 宏body又叫expansion或replacement list是一个token序列 按照惯例宏的名字一般用大写字母 #define macro_body也只占一行并且macro_body后面不能有其他内容除空白字符或注释外在写代码时也可以用\分隔多行但预处理时仍会将它们合为一行 C preprocessor顺序地扫描源程序因此宏定义只从定义处开始生效 宏展开是递归进行的preprocessor将一个宏展开后会接着处理展开后的结果如果这里面有其他的宏会继续展开下去。但是如果结果里面再次出现刚刚展开的这个宏的话将不会展开第二次以免出现无限递归的情况 #define TABLESIZE BUFSIZE
#define BUFSIZE 1024
TABLESIZE
// - 先展开为 BUFSIZE
// - 再展开为 1024 注意虽然宏会展开多次但是每次的展开过程只是单纯地用body替换name如上面的例子中在展开TABLESIZE时只是单纯地用BUFSIZE来替换它接下来preprocessor才检查替换结果是不是另一个宏 2.2 函数形式的宏 Function-like macros 如其名这种宏使用起来像函数调用一样。用法 #define name() body 注意小括号()必须和宏的名字连在一起否则会被当成object-like宏来展开同时在使用时也必须用name()的形式此时name和()间可以有空格2.3中同只用name的话不会被展开 2.3 宏参数 Function-like宏像函数一样可以接受参数用法 #define name(params_list) 其中params_list是参数列表参数必须是有效的C标志符由,分隔参数列表中可以出现空格但是空格没有实际作用 在“调用”函数形式的宏时将实参列表写在宏name后面的小括号里由,分隔函数形式宏的“调用”不限制在一行内可以写成多行但是参数数量必须和定义时的数量相匹配。可以实参可以是空但是数量也必须匹配直白讲即逗号数量必须一致如 min(, b) → (( ) (b) ? ( ) : (b))
min(a, ) → ((a ) ( ) ? (a ) : ( ))
min(,) → (( ) ( ) ? ( ) : ( ))
min((,),) → (((,)) ( ) ? ((,)) : ( ))min() error→ macro min requires 2 arguments, but only 1 given
min(,,) error→ macro min passed 3 arguments, but takes just 2 如 #define min(X, Y) ((X) (Y) ? (X) : (Y))x min(a, b); → x ((a) (b) ? (a) : (b));y min(1, 2); → y ((1) (2) ? (1) : (2));z min(a 28, *p); → z ((a 28) (*p) ? (a 28) : (*p)); 在展开时会去除各个实参的leading、trailing whitespace实参的token序列中的whitespace会减成一个空格。在每个实参中小括号必须平衡小括号中的逗号不会结束这个参数即小括号中的逗号不是实参分隔符但中括号和大括号不要求平衡而且它们中的逗号会作为实参分隔符截断这个参数 宏定义中若参数出现在字符串中在展开时不会展开成相应实参如 #define foo(x) x, x
foo(bar) → bar, x 2.4 字符串化 Stringizing 有时可能需要讲宏参数转换成字符串常量但是在 2.3 的最后提到字符串中的参数不会被实参替换为了解决这个问题可以用预处理操作符#来进行转换。当参数有一个前导#时preprocessor会将其替换为实参再转换成字符串常量但是这个过程发生后被转换成的字符串中如果还有宏则不会继续展开如果还想继续展开则需要写成多级宏的形式如 #define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)→ foo
xstr (foo)→ xstr (4)→ str (4)→ 4 2.5 拼接 预处理操作符##用于在宏body中将两个tokens拼在一起如A ## B将展开为AB要求展开后必须是一个有效的C标志符如一个标志符和数字拼接两个数字间的拼接一些复合操作符如的拼接等等有些拼接是无效的如x和。 拼接常见的应用场景为宏参数间的拼接如 #define COMMAND(NAME) { #NAME, NAME ## _command }struct command commands[]
{COMMAND (quit),COMMAND (help),…
}; 2.6 取消宏定义 #undef name用于取消宏定义name可以是object-like宏的名字或者是function-like宏的名字不用加小括号以及参数列表 3. 条件编译 3.1 条件编译常用场景 根据机器架构或操作系统的不同使用不同的代码将原文件编译成两个不同的程序其中一个版本可能会用于输出一些data进行debugging等等使用#if 0来将排除一段代码但将其保留在源文件中用作注释3.2 条件编译语法 ifdefifndef #ifdef MACROcontrolled text#endif /* MACRO */ if #if expressioncontrolled text#endif /* expression */ expression是一个integer类型的C表达式可以包含 整形常量字符常量数学运算表达式和逻辑运算表达式遵循短路求值宏在计算宏所代表的表达式前将先展开所有的宏defined预处理指令所有不是宏的标志符都视为数字0函数形式的宏但没有调用实参列表也视为0defined 用在#if和#elif表达式中用于测试一个名字是否被定义成了一个宏defined name和defiend ( name )作用相同如果name定义为了一个宏则表达式值为1否则为0因此#if defined MACRO等价于#ifdef MACRO 在测试多个宏是否存在时defined比较有用如 #if defined (__vax__) || defined (__ns16000__) else 可以用在#if、#ifdef、#ifndef中 elif elif不需要一个#endif和其匹配 4. 诊断信息 #error导致preprocessor产生一个fatal error#error所在行的剩余tokens组成错误信息#warning导致preprocessor产生一个warning并继续预处理#warning所在行的剩余tokens组成错误信息两者都不对其参数进行宏展开 参考 GNU - The C Preprocessor: Macros转载于:https://www.cnblogs.com/jerrywossion/p/11071192.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92081.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!