wordpress站点app开发,安阳网站设计公司,阿里云虚拟主机装WordPress,平面设计有哪些网站1、预处理符号
C语言设置了一些可以直接使用的预处理符号
__FILE__//进行编译的源文件
__LINE__//文件当前的行号
__DATE__//文件被编译的日期
__TIME__//文件被编译的时间
__STOC__//如果编译器遵循ANSI C 其值是1#xff0c;否则未定义
一个例子#xff1a;
printf(否则未定义
一个例子
printf(file:%s line:%d\n,__FILE__,__LINE__);
2、#define定义常量
#define name stuff
举个例子
#define MAX 1000
#define reg register //为register这个关键字创建一个简短的名字
#define do_forever for(;;)
#define CASE break;case //这样可以在写case语句的时候自动补上break
//如果定义的stuff过长可以分成几行写除了最后一行外每一行的后面都要加一个反斜杠续写序
#define DEBUG_PRINT printf(file:%s\tline:%d\t \date:%s\ttime:%s\n,\__FILE__,__LINE__, \__DATE__,__TIME__)
并且需要注意的是在define定义标识符的时候最好不要在最后加上
否则容易导致错误
3、#define定义宏
#define 机制还有一个规定允许把参数替换到文本当中这种实现通常称为宏或者是定义宏
下面是宏的声明方式
#define name(parament-list) stuff
其中的parament-list是一个有逗号隔开的符号表他们可能出现在stuff当中
需要特别注意的是参数列表的左括号必须与name紧邻如果两者之间有任何的空白字符参数列表就会被解释为stuff的一部分
一个例子
#define SQUARE(x) x*x
这个宏接受一个参数x。如果在上述声明之后把SQUARE(5)置于程序当中预处理器就会用下面这个表达式替换下面的表达式 5*5
这个宏还是有一定的问题的请看下面的代码
int a 5;
printf(%d\n,SQUARE(a1));
我们感觉这个代码的最终结果是36实则不然运行出来的结果是11
其实这个代码可以等效为
printf(%d\n,a1*a1);
所以这个宏定义需要加上小括号
#define SQUARE(x) (x)*(x)
4、带有副作用的宏参数
当宏参数在宏的定义中出现超过一次的时候如果参数带有副作用在使用宏的时候就可能出现危险。副作用就是表达式求值的时候出现的永久性效果
x1;//不带副作用
x;//带有副作用
5、宏替换的规则
1、在调用宏的时候首先对参数进行检查看看是否包含任何由#define定义的符号。如果是他们首先被替换
2、替换文本随着被插入到程序中原来文本的位置。对于宏参数名被他们的值所替换
3、最后再次对结果文件进行扫描看看它是否包含任何由#define定义的符号。如果是就重复上述过程。
需要注意的是宏参数和#define定义中可以出现其他#define定义的符号。但是对于宏不能出现递归当预处理器搜索#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、#和##
#运算符
#运算符将宏的一个参数转换为字符串字面量。他仅允许出现在带参数的宏的替换列表中。
#运算符所执行的操作可以理解为 “字符串化”。
当我们有一个变量int a 10;的时候我们想打印出the value of a is 10.
可以这样写
#define PRINT(n) printf(the value of#nis %d,n);
这个东东调用的过程是
PRINT(a);//当我们把a替换到宏的体内的时候就出现了#a而#a就是转化为“a”这个字符串代码就会被解析为
printf(the value of a is %d,n);
打印出来就是
the value of a is 10
##运算符
##可以把位于它两边的符号合成一个符号它允许宏定义从分离的文本片段创建标识符
这样的链接必须产生一个合法的标识符。否则其结果就是未定义的
举个例子
int int_max(int x,int y)
{return xy?x:y;
}float float_max(float x,float y)
{return xy?x:y;
}
也可以将上面的代码转化为宏定义写的代码
#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作为函数名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.c
11、条件编译
选择性编译使调试性的代码是否参与编译举个例子
#includestdio.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;
}
下面是常见的条件编译指令
#if 常量表达式
//...
#endif
//常量表达式由预处理求值
如
#define __DEBUG__ 1
#if __DEBUG__
//...
#endif2.多个分支的条件编译
#if 常量表达式
//...
#elif 常量表达式
//...
#else
//...
#endif3.判断是否被定义
#if defined(symbol)
#ifdef symbol#if !defined(symbol)
#ifndef symbol4.嵌套指令
#if defined(symbol)#ifdef OPTION1unix_version_option1();#endif#ifdef OPTION2unix_version_option2();#endif
#elif defined(OS_MSDOS)#ifdef OPTION2msdos_version_option2();#endif
#endif
为了避免头⽂件的重复引⼊。可以使用条件编译
#ifndef __TEST_H__
#define __TEST_H__
//头⽂件的内容
#endif //__TEST_H__