意义:解决多文件编译模块化的问题
格式:
main:(目标)main.0 (依赖)
(一个TAB)gcc main.o -o main (命令)
makefile文件名必须为makefile或者Makefile,其余文件名要使用make -f 文件名命令告诉系统去哪找makefile文件
gcc命令:
gcc -c 编译到目标代码,不进行链接 (gcc -c 文件.c 生成 文件.o)
gcc -o <文件> 输出到<文件> (gcc -o 目标文件名.o 文件.o)
建立一个小项目,有main.c student.c class.c三个文件,
main.c:
class.c:
student.c:
class.h:
student.h:
此项目实现的功能很简单就是打印10个学生序号
可以使用脚本语言.sh完成
build.sh:
这时,我们使用这个脚本,就能成功编译和链接:
但是,如果文件特别多,在只改动一个文件的情况下,我们不希望全部文件编译,只编译改动文件,这就需要用到Makefile
Makefile:
这时,我们只改动student.c文件,并查看时间戳,makefile执行也是根据时间戳的更改来完成,如果目标晚于依赖文件的时间戳,则执行对应语句:
执行make可以看到,只执行了与student.c文件有关的语句,其余的语句则没有重新编译,大大提高了编译效率
硬盘中的文件,就是静态文件。文件都是以多个块和多个扇区组成的。一般情况,一个扇区(512字节),64个扇区组成一个块。在硬盘中,对文件管理有一个特定规则(文件管理表+真实的内容):文件管理表,这个表中是以文件为单位提供了各个文件的所有信息 (每一个文件信息表就对应一个结构体,这个结构体就称之为inode,也叫i节点,这个文件的包含的多少块、多少扇区),而我们通过查找这个表就可以找到我们所需要文件的内容。
我们找文件,通过(文件名字)找的。第一步:在文件管理表中,找到这个文件的名字,第二部,访问这个文件。U盘格式化:1、快速格式化,清除了你的文件管理表,文件系统就找不到你所需要的文件名字 ,你的真实内容还在硬盘里,可以部分恢复 2、彻底格式化,这个就是把文件真实内容也清除掉了,u盘不能通过软件技术恢复了,必须借助国家安全机构(通过物理机制,通过硬件的记忆恢复)。
联系:生活中,处理小文件的一个手段,文件压缩。把扇区的空余字节都利用起来,减少了占用硬盘上的空间。硬盘喜欢大文件。
一个程序的运行就是一个进程,而我们打开的文件就属于这个进程。而操作系统对于每一个进程都有一个结构体进行管理,这个管理当前进程所有信息的结构体,我们就叫做(进程信息表)。这个表中有一个指针指向我们的文件管理表,这个文件管理表就包含了本进程打开的所有文件,通过查找文件管理表的index(文件描述符fd,相当于这个结构体数组的下标),就得到了我们的文件所有信息的结构体(Vnode,V节点),而这个结构体的指针就是文件指针。
#include
#include
int main(void)
{
//输出型参数
// time_t time(time_t *t)
//method 1:
#if 0
time_t tm;
time(&tm);
printf("value of seconds:%lld\n", tm);
#endif
//返回值
//method 2:
time_t t;
// int a = 3, *p = &a;
t = time(NULL);
printf("value of seconds:%lld\n", t);
char *p_time = ctime(&t);
printf("%s", p_time);
#if 0
struct tm
{
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};
#endif
struct tm *p_tm = localtime(&t);
//不判断
printf("%d-%d-%d %d:%d:%d\n", p_tm->tm_year, p_tm->tm_mon, p_tm->tm_mday, p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec);
return 0;
}
#include
#include
#include
#include
#include
#include
int main(void)
{
int fd = -1;
close(2);
//打开一个文件
fd = open("2.txt", O_RDWR);
if (fd < 0)
{
perror("open");
exit(0);
}
else
printf("fd = %d.\n", fd);
#if 0
int fd = -1;
//打开一个文件
fd = open("1.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
{
perror("open");
exit(0);
}
else
printf("fd = %d.\n", fd);
//关闭终端输出
close(1);
//复制了一个新的fd_new文件描述符,指向1.txt
int fd_new = dup(fd); // 就完成了标准输出的文件重定位,此行开始所有的终端输出都会写在文件里(1.txt)
if (fd_new < 0)
{
perror("dup");
exit(0);
}
else
//== 写文件
printf("fd_new = %d.\n", fd_new);
//对1.txt写操作
//两个文件描述符,各自操作自己的那份文件,但是两者的读写操作互相影响文件指针,== 多次open加了O_APPEND标志。
while (1)
{
write(fd, "ab", 2);
sleep(1);
write(fd_new, "cd", 2);
sleep(1);
}
#endif
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(void)
{
//打开一个目录
DIR *p_dir = NULL;
struct dirent *p = NULL;
struct stat st;
p_dir = opendir("./");
//可重入函数和不可重入函数?回去查
while (p = readdir(p_dir))
{
//跳过隐藏文件
if (*p->d_name == '.')
continue;
memset(&st, 0, sizeof(st));
stat(p->d_name, &st);
//类型
switch (st.st_mode & S_IFMT)
{
case S_IFSOCK:
printf("s"); break;
case S_IFREG:
printf("-"); break;
case S_IFLNK:
printf("l"); break;
case S_IFBLK:
printf("b"); break;
case S_IFDIR:
printf("d"); break;
case S_IFCHR:
printf("c"); break;
case S_IFIFO:
printf("p"); break;
default:
printf("?"); break;
}
//文件权限
if (st.st_mode & S_IRUSR) // 真或者假
{
printf("r");
}
else
printf("-");
if (st.st_mode & S_IWUSR)
{
printf("w");
}
else
printf("-");
if (st.st_mode & S_IXUSR)
{
printf("x");
}
else
printf("-");
if (st.st_mode & S_IRGRP) // 真或者假
{
printf("r");
}
else
printf("-");
if (st.st_mode & S_IWGRP)
{
printf("w");
}
else
printf("-");
if (st.st_mode & S_IXGRP)
{
printf("x");
}
else
printf("-");
if (st.st_mode & S_IROTH) // 真或者假
{
printf("r");
}
else
printf("-");
if (st.st_mode & S_IWOTH)
{
printf("w");
}
else
printf("-");
if (st.st_mode & S_IXOTH)
{
printf("x");
}
else
printf("-");
//hard连接数
printf(" %d", st.st_nlink);
//获得use的用户名
struct passwd *p_uid = NULL;
p_uid = getpwuid(st.st_uid);
if (NULL == p_uid)
{
perror("getpwuid");
exit(0);
}
//获得group的用户名
struct group *p_gid = NULL;
p_gid = getgrgid(st.st_gid);
if (NULL == p_gid)
{
perror("getgrgid");
exit(0);
}
printf(" %s %s", p_uid->pw_name, p_gid->gr_name);
printf(" %d\n", st.st_size);
}
return 0;
}