C语言 day5
编译过程
预处理:头文件包含、宏替换、条件编译、删除注释、 不做语法检查
编译:将预处理后的文件 生成 汇编文件 做语法检查
汇编:将汇编文件 编译成二进制文件
链接:将众多的二进制文件+库+启动代码 生成可执行文件
总结:更多的时候是一步到位 编译:gcc 源文件 -o 可执行文件
预处理
- 头文件包含 #include
- 宏定义 #define
- 条件编译 #if #endif…
- 一些特殊作用的预定义宏
头文件包含(了解)
#include<aaa.h>
表示从系统的指定目录下寻找aaa.h(用于包含系统的头文件)
#include"aaa.h"
表示从当前目录下寻找 如果没找到再去到系统指定目录下寻找(用于包含用户自定义的头文件)
宏定义#define
宏只在当前源文件有效
终止宏的作用范围可以用#undef N
- 不带参数的宏 直接替换 替换的过程叫做
宏展开
- 带参数的宏(宏函数)
- 格式: #define 宏名(参数1,,参数2…) 字符串(宏的参数不带类型 他不是函数只是一个宏)
- 调用:宏名(参数)
- 与普通函数的区别:
- 宏函数调用多少次就展开多少次,执行代码的时候没有函数调用的过程,也不需要函数的出入栈,所以带参数的宏 浪费空间 节省时间
- 带参数的函数 代码只有一份,存在代码段,调用的时候去代码段读取函数指令,调用的时候要压栈(保存调用函数前的相关信息),调用完出栈(恢复调用函数前的相关信息),所以函数浪费了时间 节省了空间。
案例:
1 |
|
案例:请计算结果
1 |
|
条件编译
防止头文件重复包含
方法一:每个头文件前加#pragma once 编译器决定
方法二:c/c++标准制定
1 |
|
总结:
#pragma once 编译器决定 强调文件名
#ifndef c/c++标准制定 强调的宏名 而不是文件
原码 反码 补码
注意:无符号数,正数 反码 原码 补码相等
重要:负数在计算机中存储的是补码(所有数据存储的都是补码只不过非负数反码、补码、原码都相同)
计算机为啥要补码?
总结:
- 补码的意义将减法运算变加法运算
- 统一了0的编码
+0 = 0000 0000=0000 0000(反码)=0000 0000(补码)
-0 = 1000 000 = 1111 1111(反码)= 0000 0000(补码)