C高级day5(Makefile)

一、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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值