编程流程:
1.编辑
2.编译:gcc main.c // a.out
3.运行
4.调试
编译过程:
1.预处理也叫预编译(预处理器):
将代码中相关预处理命令执行,最终生成一个只包含c语言代码的文件
2.编译(编译器):
表示对语法进行检查,将这个 c的源代码 生成 汇编代码
3.汇编(汇编器):
表示将 汇编源代码 最终生成 机器代码
4.链接(连接器):
表示将使用到的其它代码链接到一起 生成 最终可执行文件
预处理功能:
效果:做文本替换
1.宏定义
语法: #define 标识符 字符串
#define 宏名 宏值
注意:
1.预处理命令 都是以 # 开头的
2.宏名 命名规则 和之前标识符命名规则一致
3.宏名 一般都大写,以区别与普通变量名
4.预处理 实际上 是将 宏名 用 宏值(预处理阶段的 字符串)原样替换(文本替换)
注意:c语言字符串中出现的 宏名 不会被替换
5.应用:(a. 提高代码的可读性 b.一改全改,方便代码修改 )
6.宏名的 作用域
# undef 宏名
表示取消 宏名 的定义
注意:
只是在预处理阶段 发挥作用
作用范围 从定义处开始到 #undef 结束
eg: #define N 10
含义:表示将来代码中 出现的N 都代表10
则 编写代码时,可以使用N表示数字10
1.1带参数的宏定义(宏函数)
语法:
#define 宏名(参数) 宏值
eg:
#define ADD(a,b) a+b
注意:
1.带参数的宏定义 和函数 有本质的区别
a. 处理阶段不一样
宏定义----预处理阶段
函数 ------编译阶段
b. 使用不一样
宏定义---预处理阶段 就使用结束了
宏的使用本质上 是文本的原样替换
宏的参数 只是进行 文本替换用的 不进行语法检查
函数 -----调用时 进行使用
函数的使用 本质上是函数代码的调用
函数的参数 是有类型的 编译阶段是要进行类型检查的
c. 应用:
一般对于一些短小代码(不超过5行的代码) 考虑写成带参宏
d. 宏的副作用
处理:把能加括号的地方都加括号
e. 注意:
宏定义 必须 写在一行
续航符( \ )
2.文件包含
# include< 文件名 >
#include"文件名"
<> 与 "" 区别:
在于 查找头文件的方式不一样
<> 到系统默认的路径寻找对应的头文件
"" 表示先到当下目录下寻找头文件 如果没有 再到系统默认路径下寻找
3.条件编译
1.
#ifdef 标识符
程序段1
#else
程序段2
#endif
含义:如果 定义了标识符
则预处理程序段1 (就是将程序段1的代码保留)
否则 保留程序段2
用途:
a.调试代码
b.设计头文件
2.
# ifndef 标识符
程序段1
#else
程序段2
#endif
含义:如果 没有定义标识符
则预处理程序段1 (就是将程序段1的代码保留)
否则 保留程序段2
3.
#if 表达式
程序段1
#else
程序段2
#endif
含义:表达式为真 处理程序段1 表达式为假 处理程序段2
指针:
指针基础:
1.指针概念
2.指针变量定义及引用
3.指针传参
指针进阶:
1.指针 + 一维整型数组
2.指针 +一维字符型数组
指针高阶:
1.指针 +二维整型数组
2.指针 +二维字符数组
3.指针的数组
4.指针+ 函数
5.指针 +指针
指针概念:
1. 地址 内存单元的编号
指针 就是 地址
2.指针也是一种数据类型
指针类型
这种数据类型 是专门用来处理 地址 这种数据
指针变量
语法:
基类型 * 指针变量名
(1)基类型 ------数据类型(整型,浮点型,字符型,数据类型,指针类型......)
作用 -------表示该指针类型 所指向的内存空间 存放什么类型的数据
(2) * -----------定义时,表示此时定义的是一个 指针类型 的变量
(3)指针变量名----符合标识符命名规则
eg: int * p; // pointer
int a = 10;--- 表示a所在空间是用来存放 int(整型)类型的数据的
int *p =&a;--- (p指向了a)
&a --- 表示获得a所在空间的首地址
----表示获得了一块 可以存放int型数据的内存空间的地址
指针类型
int * p; int * -----整体叫指针类型
int * 含义----首先表示是 一个指针类型
---表示指向int型数据的指针类型
指针变量的引用:
int a= 10;
int * p= &a; (p指向a) 因为p中保存了a的地址
* ----指针运算符
-----单目运算
------运算对象(只能指针---地址)
*p ----表示访问 p所指向的 基类型的 内存空间
----间接访问
----- 通过a访问的 叫 直接访问
step1:首先拿出p中的地址,到内存中定位
step2:偏移出sizeof(基类型)大小的一块空间
step3:将偏移出的这块空间,当做一个基类型变量来看
*p 运算效果 相当于就是一个基类型的变量
*p 等价于 a