make/makefile
背景
会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂
的功能操作makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
1.创建文件makefile
2.vim 操作makefile写入内容
3.vim 操作obj.c写入内容
4.make操作
make操作是一个命令,执行第一个依赖方法
6.查看内容myobj
7.make clean (删除myobj)
总结:make是一个命令,makefile是一个文件。
2.make会根据makefile的内容,完成编译或者清理的工作。
这里的.PHONY怎么理解呢??
先看一段程序
1.make使用两次,他会报myobj可执行程序是最新的,再次编译的时候编译器会拦截不然你在编译,当我们vim修改了obj.c的时候,又可以make了
2.为什么makefile对最新的可执行程序,默认不想重新生成呢?
这样可以提高编译效率,假如说一家大公司一个项目代码很多,编译起码要一两个小时,如果不断的编译的话,编译效率会很低。
3.makefile怎么知道我的程序需要被编译了呢?
对比可执行文件最近修改时间和源文件最近的修改时间,谁更新。如果源文件修改时间更新的话,可以继续编译make,反之,就会体现你可执行程序是最新的了。
所以我们.PHONY:依赖文件列表,这样就不会提醒可执行程序最新了
2.makefile还能怎么玩??
3.还能这么玩?
我们可以用变量代替目标文件,依赖文件列表,并且将依赖方法的功能可以起名一个别称
4.makefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法
我们要生成my.exe,必须要找到my.o的依赖方法,makefile会向下执行找my.o
这里类似于递归,直到翻译都执行完了。
如果顺序是乱的,务必把目标文件my.exe放第一个
Linux第一个小程序-进度条
准备工作
1.bar.h用于函数声明
2.bar.c用于函数定义
3.main.c用于测试
4.makefile 用于文件的编译以及清理
版本1
代码分析
我们要实现一个进度条,首先有个字符数组来充当进度条,先对其进行初始化,全部初始化为反斜杠0,防止打印时候出现乱码,大小为101,最后一个为字符串结尾反斜杠0,然后定义logo变量,用来进度条显示,routh字符常量数组用来模拟进度条后面旋转的.(上面图片里面的求routh数组长度的改为srelen,写错了)
进度条
版本2(模拟下载问题)
代码分析:
doneload函数中定义了一个要下载文件的总大小,一个当前已经下载了的大小,一个下载的速度,循环中,已经下载的大小小于总大小说明还没下完,doneload函数会给bar函数提供一个filesize,和current,可以让bar函数直到当前下载了百分之多少,下载了百分之多少就循环多少次,也就是字符串中+了多少个#,假如说当前是30%,那么count=30,循环30次,字符串lenth中有30个#,然后打印即可,如果下次到31%,cnt又重新开始从0开始。
版本3(多文件下载问题)
多文件下载
代码分析:通过
根据不同文件大小不同,传参文件大小
版本4(进度条加载通讯录里面)
进度条2
contanct.cpp
#include"contanct.h" //#include<windows.h> #include<graphics.h>//包含图形库头文件 //#include<mmsystem.h>//包含多媒体设备接口头文件 //#pragma comment(lib,"winmm.lib")//加载静态库 void DestroyContanct(pp* p) { free(p->arr); p->arr = NULL; p->size = 0; p->sz = 0; printf("销毁成功\n"); } void Addbig(pp* p) { if (p->sz == p->size) { peoinfo* tmp = (peoinfo*)realloc(p->arr, (p->size + 2) * sizeof(peoinfo)); if (tmp != NULL) { p->arr = tmp; } p->size+= 2; printf("增容 + 2\n"); } } void Loadcontact(pp* p) { FILE* fp=fopen("contact.txt", "r"); if (fp == NULL) { perror("Loadcontact:"); return; } peoinfo tmp = { 0 }; while (fread(&tmp,sizeof(peoinfo),1,fp)) { Addbig(p); p->arr[p->sz] = tmp; p->sz++; } fclose(fp); fp = NULL; } void Savecontact(pp* p) { FILE* fp = fopen("contact.txt", "wb"); if (fp == NULL) { perror("Savecontact:"); return; } int i = 0; for (i = 0; i < p->sz; i++) { fwrite(p->arr+i, sizeof(peoinfo), 1, fp); } fclose(fp); fp = NULL; printf("保存成功\n"); } void Initcontanct(pp* p) { /*p->sz = 0; memset(p->arr, 0, sizeof(p->arr));*/ p->sz = 0; p->size = SIZE; p->arr = (peoinfo*)malloc(p->size * sizeof(peoinfo)); if (p->arr == NULL) { perror(" Initcontanct:malloc"); return; } memset(p->arr, 0, p->size * sizeof(peoinfo)); Loadcontact(p); } void Addcontanct(pp* p) { Addbig(p); printf("请输入姓名\n"); scanf("%s", p->arr[p->sz].name); printf("请输入性别\n"); scanf("%s", p->arr[p->sz].sex); printf("请输入年龄\n"); scanf("%d", &(p->arr[p->sz].age)); printf("请输入电话\n"); scanf("%s", p->arr[p->sz].tel); printf("请输入地址\n"); scanf("%s", p->arr[p->sz].addr); p->sz++; printf("录入成功\n"); } void Printcontanct(pp* p) { int i = 0; printf("******************************************************\n"); printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址"); printf("******************************************************\n"); for (i = 0; i < p->sz; i++) { printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr); printf("******************************************************\n"); } } int find(pp* p, char name[]) { int i = 0; for (int i = 0; i < p->sz; i++) { if (!strcmp(p->arr[i].name, name)) return i; } return -1; } void Delcontanct(pp* p) { char name[MAX_NAME]; printf("请输入要删除朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); for (int j = k; j < p->sz - 1; j++) { p->arr[j] = p->arr[j + 1]; } p->sz--; printf("删除成功\n"); } } void findcontanct(pp* p) { char name[MAX_NAME]; if (p->sz == 0) { printf("通讯录为空\n"); return; } printf("请输入要查找朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); printf("******************************************************\n"); printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址"); printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr); printf("******************************************************\n"); } } void modifycontanct(pp* p) { char name[MAX_NAME]; printf("请输入修改朋友的名字\n"); scanf("%s", name); if (find(p, name) == -1) { printf("查无此人\n"); } else { int k = find(p, name); printf("请输入要修改朋友的信息\n"); printf("修改性别->"); scanf("%s", p->arr[k].sex); printf("修改年龄->"); scanf("%d", &(p->arr[k].age)); printf("修改电话->"); scanf("%s", p->arr[k].tel); printf("修改地址->"); scanf("%s", p->arr[k].addr); printf("修改成功\n"); } } int int_cmp_age(const void* p1, const void* p2)//按年龄比较 { return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age; } void Sortcontanct(pp* p) { qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age); printf("按年龄排序成功,快去打印吧\n"); } void bgm() { //打开音乐 mciSendString("open ./music.MP3", 0, 0, 0);//后面参数不用管 //播放音乐 mciSendString("play ./music.MP3", 0, 0, 0);//后面参数不用管 } void bar(double total, double current) {char lenth[105]; char logo = '>'; const char* routh ="-/|\\"; int len = strlen(routh); int cnt = 0; memset(lenth,'\0',105); double rate = (current * 100.0) / total; int count = (int)rate; while (cnt <= count) {lenth[cnt++] = logo; } printf("[%-101s][%.1lf%%][%c]\r", lenth, rate, routh[cnt % len]); fflush(stdout); }
contanct.h
#pragma once #define _CRT_SECURE_NO_WARNINGS #include<windows.h> #include<graphics.h>//包含图形库头文件 #include<mmsystem.h>//包含多媒体设备接口头文件 #include<stdio.h> #include <string.h> #include <stdlib.h> #pragma comment(lib,"winmm.lib")//加载静态库 #define MAX_NAME 20 #define MAX_SEX 6 #define MAX_TEL 12 #define MAX_ADDR 20 #define SIZE 3 enum opion { EXIT, ADD, DEL, SEARCH, MODIFY, SORT, PRINT, SAVE, MUSIC, DESTROY }; typedef struct peoinfo { char name[MAX_NAME]; char sex[MAX_SEX]; int age; char tel[MAX_TEL]; char addr[MAX_ADDR]; }peoinfo; typedef struct pp { struct peoinfo *arr; int sz; int size; }pp; void Initcontanct(pp* p); void Addcontanct(pp* p); void Printcontanct(pp* p); void Delcontanct(pp* p); void findcontanct(pp* p); void modifycontanct(pp* p); void Sortcontanct(pp* p); void Addbig(pp* p); void Loadcontact(pp* p); void Savecontact(pp* p); void bgm(); void DestroyContanct(pp* p); void bar(double total, double current);
test.cpp
#include"contanct.h" #include <string.h> double width = 4; void doneload(double filesize) { double current = 0; while (current <= filesize) { bar(filesize, current); current += width; Sleep(1); } printf("\n"); } void menu() { printf("#######################################\n"); printf("#********* 1.add ***************#\n"); printf("#********* 2.del ***************#\n"); printf("#********* 3.search ***************#\n"); printf("#********* 4.modify ***************#\n"); printf("#********* 5.sort ***************#\n"); printf("#********* 6.print ***************#\n"); printf("#********* 7.save ***************#\n"); printf("#********* 8.music ***************#\n"); printf("#********* 9.Destroy***************#\n"); printf("########## 0.exit ################\n"); } void test() { pp pro; Initcontanct(&pro); int input; do { menu(); scanf_s("%d", &input); doneload(1024); system("cls"); switch (input) { case ADD: Addcontanct(&pro); break; case DEL: Delcontanct(&pro); break; case SEARCH: findcontanct(&pro); break; case MODIFY: modifycontanct(&pro); break; case SORT: Sortcontanct(&pro); break; case PRINT: Printcontanct(&pro); break; case SAVE: Savecontact(&pro); break; case MUSIC: bgm(); break; case DESTROY: DestroyContanct(&pro); break; case EXIT: printf("退出通讯录\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } void main() { test(); }