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
c
#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
c
#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
c
#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();
}