预处理指令 宏定义 条件编译指令 static和extern关键字

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)如果全局变量定义在模块当中,这个模块变量快就必须使用staticextern修饰
如果定义在模块中的全局变量,使用extern修饰,这个全局变量就可以跨模块访问
如果定义在模块中的全局变量,使用static修饰,这个全局变量会变成一个内部变量

"一句话总结
修饰全局变量:
static:全局变量变成内部变量
extern:所有文件可共享此变量
  • 修饰函数
"一句话总结
static修饰函数:表示函数为内部函数只能被本文件访问.
extern修饰函数:表示函数为外部部函数能被程序的所有文件访问.(不写,默认就是extern修饰的)
  • static和extern总结

“`
修饰函数:static修饰的,只能在本模块中访问
extern 可以跨模块访问

修饰全局变量:static修饰的,只能在本模块中访问
extern 可以跨模块访问

修饰局部变量:static修饰的,生命周期变长直到程序结束,但是作用域不变
extern不能修饰局部变量
“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值