编程流程:编辑--->编译--->运行--->调试
编译的过程
(1)预处理:预编译,将代码中相关的预处理命令执行生成一个只包含C语言代码的文件。
(2)编译:对语法进行检查
(3)汇编:将汇编源代码生成机器语言
(4)链接:将使用到的其他代码链接到一起生成可执行文件
预处理命令
“预处理”,即根据预处理命令对程序作相应的处理(例如,若程序中用#define 命令定义了一个符号常量 A,则在预处理时将程序中所有的 A都 置换为指定的字符串。若程序中用#include 命令包含一个文件"stdio. h", 则在预处理 时将 stdio. h 文件中的实际内容代替该命令)。
C 提供的预处理功能主要有以下 3种: 1. 宏定义 2. 文件包含 3. 条件编译
1、宏定义
不带参数的宏定义
语法: #define 标识符 字符串
#define 宏名 宏值
#define N 10
(含义:表示将来代码中出现的N都代表10,编译代码时,可以使用N表示数字10;)
注意:
①预处理命令都是以 # 开头的
②宏名命名规则和之前标识符命名规则一致(宏名一般都写成大写,以区别普通变量名)
③预处理实际上是将宏名用宏值(预处理阶段的字符串)原样替换(文本替换)
④应用:a.提高代码可读性
b.一改全改,方便代码修改
⑤宏的作用域:只是在预处理阶段发挥作用
作用范围:从定义处开始到宏名取消
#undef 宏名 ----- 取消宏名的定义
编辑一个含宏定义的 main.c 文件:
#include<stdio.h>
#define N 10
int main(void)
{
int a[N] = {1,2,3,4,5};
int i;
for(i = 0;i < N;++i)
{
printf("%d ",a[i]);
}
putchar('\n');
return 0;
}
通过使用gcc -E main.c -o main.i预处理命令可在 main.i 查看文本替换:
797 int main(void)
798 {
799 int a[10] = {1,2,3,4,5};
800
801 int i;
802
803 for(i = 0;i < 10;++i)
804 {
805 printf("%d ",a[i]);
806 }
807 putchar('\n');
808
809 return 0;
810 }
带参宏定义
语法:#define 宏名(参数) 宏值
#define ADD(a,b) a+b
使用示例代码:
#include<stdio.h>
#define ADD(a,b) a+b
int main(void)
{
int x = 3;
int y = 4;
printf("x+y=%d\n",ADD(x,y)); //预处理中会直接用x,y替换带参宏定义中的a,b
return 0;
}
注意:
①带参宏和函数的本质区别
a.处理阶段不一样
宏定义 ------ 预处理阶段
函数 ----- 编译阶段
b.使用不一样
宏 ----- 预处理阶段就使用结束了,宏的使用本质上是文本替换,不进行语法检查
函数 ----- 调用时,进行使用;函数使用本质上是函数代码的调用,函数的参数是有类型 的,编译阶段是要进行类型检查。
c.应用
一般对于一些短小代码(不超过5行代码),考虑写成带参宏
d. 宏的副作用
处理:把能加括号的地方都加括号
例如:
#define MUL(a,b) a*b
printf("a * b = %d\n",MUL(1+2,3+4));//文本替换后为1+2*3+4
结果为:a * b = 11
( 为考虑运算优先级的结合性在宏定义中加上括号 ((a)*(b)) ,加括号后运行结果为 21)
e. 宏定义必须在一行
2、头文件
#include<文件名>
#include"文件名
<>与" " 区别
①查找的路径不同
<> 到系统默认的路径寻找对应头文件;" " 表示先到当下目录下寻找头文件,如果没有,再到系统默认路径下寻找。
3、条件编译
如果标识符被定义了,则预处理(保留)程序段 1,否则保留程序段 2
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
如果没有定义标识符,则预处理程序段 1,否则预处理程序段 2
#ifndef 标识符
程序段 1
#else
程序段 2
#endif
表示式为真处理程序段 1,表达式为假处理程序段 2
#if 表达式
程序段 1
#else
程序段 2
#endif
#ifndef _ADD_H
#define _ADD_H
指针基础
1、指针概念
地址——内存单元的编号
指针就是地址,指针类型 —— 处理指针(地址)数据
指针也是一种数据类型,专门用来处理地址这种数据
2、指针变量定义及引用
指针变量定义
基类型 *指针变量名
(1)基类型:整型、浮点型、字符型、数据类型、指针类型(数据类型、结构体类型)
(2).* :定义时,表示此时定义的是一个指针类型的变量
(3) .指针变量名:符合标识符命名规则
指针类型 int *p //int整体叫指针类型
指针变量的引用
int a = 10;
int *p = &a;