IOS学习第16天
预处理指令的概述
1.预处理指令
在C语言中,预处理指令都是以 "#"开头
在C语言中只要是"#"开头都是预处理指令
2.C程序完整流程
1>创建源文件 xxx.c,写代码
2>编译
1).先执行源文件中的预处理指令
2).检查语法
3).编译成功
3>链接
1)链接一些库函数,自己的函数
2)为程序添加一些启动代码
3).out的可执行文件
4>运行
1)直接拖到 终端 然后回车
2)./+.out文件名
```
###宏定义
* 基本使用
1.是什么
是一个替换代码的预处理指令
2.有什么用
可以在编译之前进行代码替换.
3.语法
#define 宏名 宏值
“`
* 无参数的宏
#define 宏名 宏值
1.定义 宏的时候
宏值 就是宏值,不做任何计算,也不会检查语法
2.出现宏的表达式 不能直接算,一定要宏替换!!!!
3.宏不是一个变量,绝对不允许 "宏名 = 10",给宏名赋值
4.宏的作用域:
从定义宏的位置开始,一直到文件的最下面
怎么提前结束宏,#undef 宏名[用的很少]
5.字符串中并不会出现宏替换.
- #define和typedef的区别
1.归属的分类不一样,执行的时间不一样
#define 预处理指令,在预编译的执行,在预编译的时候会进行宏展开/宏替换
typedef C代码,运行的时候执行
2.用法上不一样
#define可以代替任意的c代码,并且不会进行任何计算和语法检查
typedef只能给已经存在的类型,起别名
- 带参数的宏
1.有参宏 基本格式
#define M(a,b,c) a+b+1
2.如何使用
int s = M(10,20,30);
注意:
1>在定义宏的时候,宏名以空格作为结束
#define M A 10
宏名是M, A 10 是宏值
2>为带参数的宏 传值的时候是本色传递
"意思就是只要看见宏 不做任何计算 就是替换!!!!!!!!
注意:宏替换的时候 自己乱加括号
练习1:
#define M(a,b) a+b
int main()
{
int s = M(10,20)*2;//(10+20)*2
printf("s = %d\n",s);
}
练习2:
#define M(x,y,z) x*z+y+z
int main()
{
int a=2, b=2, c=4;
printf("%d\n", M(a+b,b+c,c+a));
}
//--> a+b*c+a+b+c+c+a
// 2+8+2+2+4+4+2
条件编译指令
1.什么是条件编译
是一个根据条件来编译代码的一个预处理指令
2.有什么用呢?
根据条件来判断是否编译一段代码
3.语法格式
#if 条件1
代码1
#elif 条件2
代码2
#elif 条件3
代码3
#else
代码4
#endif
注意:判断条件中 不能用到 "变量",基本上只能用宏
4.条件编译指令 和 if的区别 [面试题]
1>归属的分类不一样,执行时间上不一样
条件编译是预处理指令,是在编译之前执行的
if是C代码,是在程序运行的时候执行
2>编译的代码不一样
条件编译 是满足条件的代码会被编译成二进制指令
if 不管慢不满足条件,代码都会被编译成二进制指令,只不过不满足条件的不会执行
```
* 使用条件编译指令防止同1个文件被重复包含
1.实现的效果.
无论1个文件被#include多少次.我只希望他最终只会被包含1次.
2.解决方法:
#ifndef 宏名
#define 宏名
写只要编译一次的代码;
#endif
在其他文件中,无论你包含多少次这个文件,这个文件会真正被包含1次
```
static和extern
- 修饰局部变量
1.如果局部变量被static修饰,叫做静态变量
2.静态变量不再存储在栈区域,存储在常量区/静态区
3.局部变量被static修饰后 有已下特点
void test()
{
static int num = 0;
num++;
printf("num = %d\n",num);
}
静态变量
1>作用域:作用域不变
2>生命周期:会延长,延长到程序结束
3>被static修饰的语句,只会执行一次
4.extern 不能修饰局部变量
"一句话总结
static修饰局部变量表示延长变量生命周期至程序结束,但不改变其作用域
extern不能修饰局部变量
- 修饰全局变量
1.写一个全局变量一般也可以分成两步
1>先写全局变量的声明 int num;
2>再写全局变量的定义并初始化 int num = 10;
2.全局变量可以只有声明,没有定义/实现,系统会将这个全局变量自动初始化为0;
也可以只有定义而没有声明,但是这个时候全局变量的定义最好在文件的最上面
3,当我们分模块/多文件开发的时候,如果要在模块中声明全局变量
1)全局变量的声明要写在.h文件当中
2)全局变量的实现要写在.c文件当中
3)如果全局变量定义在模块当中,这个模块变量快就必须使用static和extern修饰
如果定义在模块中的全局变量,使用extern修饰,这个全局变量就可以跨模块访问
如果定义在模块中的全局变量,使用static修饰,这个全局变量会变成一个内部变量
"一句话总结
修饰全局变量:
static:全局变量变成内部变量
extern:所有文件可共享此变量
- 修饰函数
"一句话总结
static修饰函数:表示函数为内部函数只能被本文件访问.
extern修饰函数:表示函数为外部部函数能被程序的所有文件访问.(不写,默认就是extern修饰的)
- static和extern总结
“`
修饰函数:static修饰的,只能在本模块中访问
extern 可以跨模块访问
修饰全局变量:static修饰的,只能在本模块中访问
extern 可以跨模块访问
修饰局部变量:static修饰的,生命周期变长直到程序结束,但是作用域不变
extern不能修饰局部变量
“`