一、Xmind整理:
二、上课笔记整理:
1.#----->把带参宏的参数替换成字符串
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(a,b) a>b?a:b
#define STR(n) #n
int main(int argc, const char *argv[])
{
printf("%d\n",MAX(12,3));
printf("%s\n",STR(hello)); //可以输出hello
return 0;
}
2.宏替换
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(a,b) a>b?a:b
#define STR(n) #n
#define N 10
#define M N+10/3
#define NUM N*M+4/M
int main(int argc, const char *argv[])
{
printf("%d\n",MAX(12,3));
printf("%s\n",STR(hello)); //可以输出hello
printf("%d\n",NUM); //106
return 0;
}
3.##----->实现字符串的拼接
#include <stdio.h>
#define unit32_t unsigned int
#define TYPE(a,b) a##b //参数a会和参数b连接到一起
int main(int argc, const char *argv[])
{
unit32_t i; //定义了一个无符号的整形变量i
//TYPE(a,b) --->unit32_t
TYPE(unit,32_t) j; //定义了一个无符号的整形变量j
return 0;
}
4.宏函数练习
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//求最大值的宏函数
#define Max(a,b) {int ret; \
if(a>b) \
printf("%d\n",a); \
else \
printf("%d\n",b);\
}
#define MAX(a,b) ({int ret; \
if(a>b) \
ret=a; \
else \
ret=b;\
ret;\
100000;\
})
int main(int argc, const char *argv[])
{
Max(90,100);
printf("%d\n",MAX(20,10));
return 0;
}
5.使用宏函数,求两数的和,写两种:
a.直接在宏函数中输出结果
b.返回两数相加后的结果,在主函数内使用变量接收,并输出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ADD(a,b) { printf("%d\n",a+b);}
#define Add(a,b) ({ int ret=a+b; ret;})
int main(int argc, const char *argv[])
{
ADD(90,10);
printf("%d\n",Add(100,10));
return 0;
}
6.第一版Makefile
#表示Makefile中的注释
#这是一个Makefile文件
all:fun #仅描述了,all这个目标需要依赖于fun文件
#all为了保证一定能生成一个可执行文件
fun:fun.o main.o
gcc fun.o main.o -o fun
fun.o:fun.c
gcc -c fun.c -o fun.o
main.o:main.c
gcc -c main.c -o main.o
clean:
rm *.o fun
7.第二版Makefile ------>引入变量
变量的赋值方式
=:递归赋值,获取变量最后一次出现的值
+=:追加赋值,把新的值拼接到原有值的后面并且加空格
:=:立即赋值,在哪赋值在哪展开
?=:条件赋值,如果前面没有定义过就赋值否则不赋值
变量的访问:$变量名 ${变量名} $(变量名)
递归赋值
追加赋值
立即赋值
条件赋值
EXE=fun #可执行文件
OBJs+=fun.o #所有中间代码文件,由于项目的文件可能会添加或减少,所以OBJs使用追加赋值
OBJs+=main.o
CC=gcc #CC是一个自动变量,不赋值时make工具会自动推出设备所需的编译器
CFLAGs=-c #gcc的编译参数
all:$(EXE)
$(EXE):${OBJs}
$(CC) $(OBJs) -o $(EXE)
fun.o:fun.c
$(CC) $(CFLAGs) fun.c -o fun.o
main.o:main.c
$(CC) $(CFLAGs) main.c -o main.o
clean:
rm $(OBJs) $(EXE)
8.第三版Makefile
引入自动变量 ----->针对于一条规则来说的
$@:所有目标
$^:所有依赖
$<:第一个依赖
引入通配符
*:rm *.o
%:模式匹配----->目标和依赖之间的唯一匹配关系
%.o:%.c
字符串的模式匹配的流程:
通过xxx.o匹配到xxx.c字符串
由第一条规则展开的OBJs:fun.o main.o
1、先拿到需要的fun.o文件名,通过模式匹配%匹配到fun
2、%拿到fun后,在%.c位置展开,展开为fun.c
模式匹配指的是,使用%,通配掉两个字符串中相同的部分,
如:fun.c和fun.o fun/fun.的位置就可以通过%匹配
EXE=fun #可执行文件
OBJs+=fun.o #所有中间代码文件,由于项目的文件可能会添加或减少,所以OBJs使用追加赋值
OBJs+=main.o
CC=gcc #CC是一个自动变量,不赋值时make工具会自动推出设备所需的编译器
CFLAGs=-c #gcc的编译参数
all:$(EXE)
$(EXE):${OBJs} #指明一条规则的目标和依赖
$(CC) $^ -o $@ #在通过自动变量找到所有的目标和依赖
%.o:%.c
$(CC) $(CFLAGs) $^ -o $@
clean:
rm $(OBJs) $(EXE)
9.第四版Makefile ---->引入函数
EXE=fun #可执行文件
Files=$(wildcard *.c)
OBJs=$(patsubst %.c,%.o,$(Files))
CC=gcc #CC是一个自动变量,不赋值时make工具会自动推出设备所需的编译器
CFLAGs=-c #gcc的编译参数
all:$(EXE)
$(EXE):${OBJs} #指明一条规则的目标和依赖
$(CC) $^ -o $@ #在通过自动变量找到所有的目标和依赖
%.o:%.c
$(CC) $(CFLAGs) $^ -o $@
clean:
rm $(OBJs) $(EXE)
10.伪目标
EXE=fun #可执行文件
Files=$(wildcard *.c)
OBJs=$(patsubst %.c,%.o,$(Files))
CC=gcc #CC是一个自动变量,不赋值时make工具会自动推出设备所需的编译器
CFLAGs=-c #gcc的编译参数
all:$(EXE)
$(EXE):${OBJs} #指明一条规则的目标和依赖
$(CC) $^ -o $@ #在通过自动变量找到所有的目标和依赖
%.o:%.c
$(CC) $(CFLAGs) $^ -o $@
.PHONY:clean #.PHONY表示是一个伪目标
#伪目标的作用,不检查文件时间戳,直接执行规则下的指令
clean:
rm $(OBJs) $(EXE)
11.枚举定义
enum 枚举名
{
枚举项;
};
//定义了一个枚举的数据类型 使用enum 枚举名定义枚举变量
typedef enum 枚举名
{
枚举项;
}新的枚举名; ----->后面可以直接使用新的枚举名定义枚举变量
12.枚举练习
1、假设屋内有三个LED等,分别是LED_1,LED_2,LED_3,
每一个led等分别有两种状态,LED_ON,LED_OFF,
设计程序模拟,灯的初始化,和控制灯状态的函数
(要求:分别初始化三盏灯,每个灯都有两种状态)
写两个函数:
1、led_init(LED ) ---->初始化LED灯的函数,参数是枚举类型
2、led_con(LED,LED_C) ------>控制灯状态的函数,两个参数,分别是LED灯,LED_C灯的状态、
#include <stdio.h>
//定义了一个led灯的枚举类型
typedef enum led
{
LED_1=1,
LED_2,
LED_3,
}LED;
typedef enum led_c
{
LED_OFF,
LED_ON,
}LED_C;
//初始化LED灯的函数
void led_init(LED led)
{
switch(led)
{
case LED_1: //直接使用枚举项对枚举变量判断
printf("初始化了LED_1灯\n");
break;
case LED_2:
printf("初始化了LED_2灯\n");
break;
case LED_3:
printf("初始化了LED_3灯\n");
break;
}
}
//控制灯开关的函数
void led_con(LED led,LED_C c)
{
switch(led)
{
case LED_1: //直接使用枚举项对枚举变量判断
switch(c)
{
case LED_ON:
printf("打开了LED_1灯\n");
break;
case LED_OFF:
printf("关闭了LED_1灯\n");
break;
}
break;
case LED_2:
switch(c)
{
case LED_ON:
printf("打开了LED_2灯\n");
break;
case LED_OFF:
printf("关闭了LED_2灯\n");
break;
}
break;
case LED_3:
switch(c)
{
case LED_ON:
printf("打开了LED_3灯\n");
break;
case LED_OFF:
printf("关闭了LED_3灯\n");
break;
}
}
}
int main(int argc, const char *argv[])
{
LED led = LED_2;
//调用初始化函数时,直接使用枚举项进行传参
led_init(LED_1);
led_init(LED_2);
led_init(LED_3);
//调用控制函数时,通过枚举变量传参,led是哪一个枚举项,就控制哪一盏灯的状态
led_con(led,LED_ON);
led_con(led,LED_OFF);
return 0;
}