linux下的C语言开发(makefile编写详解)

对于程序设计员来说,makefile是我们绕不过去的一个坎。可能对于习惯Visual C++的用户来说,是否会编写makefile无所谓。毕竟工具本身已经帮我们做好了全部的编译流程。但是在Linux上面,一切变得不一样了,没有人会为你做这一切。编代码要靠你,测试要靠你,最后自动化编译设计也要靠你自己。

Makefile 介绍首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。我们的规则是:1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。

代码示例:

由于这个程序比较短,我们可以这样编译

gcc -c main.c gcc -c mytool1.c gcc -c mytool2.c gcc -o main main.o mytool1.o mytool2.o 这样的话我们也可以产生main程序,而且也不是很麻烦。但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?也许你会说,这个很容易解决啊,我写一个 SHELL脚本,让它帮我去完成不就可以了。是的对于这个程序来说,是可以起到作用的。但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译?  为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make。我们只要执行以下make,就可以把上面的问题解决掉。在我们执行make之前,我们要先编写一个非常重要的文件–Makefile。对于上面的那个程序来说,可能的一个Makefile的文件是:

这是上面那个程序的Makefile文件:

有了这个Makefile文件,不论我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件它连理都不想去理的。那么Makefile是如何编写的?在Makefile中#开始的行都是注释行。Makefile中最重要的是描述文件的依赖关系的说明。

一般的格式是:  

target:components  

TAB rule

第一行表示的是依赖关系。第二行是规则。

例如上面的那个Makefile文件的前两行。

main:main.o mytool1.o mytool2.o  

表示我们的目标(target)main的依赖对象(components)是main.o mytool1.omytool2.o。 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令。就象我们的上面那个Makefile第二行所说的一样要执行 gcc-o main main.o mytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键。

如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。

Makefile有三个非常有用的变量。分别是$@,$^,lt;代表的意

义分别是:  

$@ 目标文件

$^ 所有的依赖文件

lt; 第一个依赖文件  如果我们

使用上面三个变量,那么我们可以简化我们的Makefile文件为:# 简化后的Makefile 

gcc -c lt;经过简化后,我们的Makefile是简单了一点,不过人们有时候还想简单一点。

这里我们学习一个Makefile的缺省规则 

.c.o: 

 gcc -c lt;

这个规则表示所有的 .o文件都是依赖与相应的.c文件的。例如mytool.o依赖于mytool.c,这样Makefile还可以变为:

好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile的规则,可以查看相应的文档。

最后,总结下make 执行过程

1)make 在当前目录下找 \”Makefile\”或\”makefile\”的文件

2)如果找到,则会找文件中第一个目标文件(target)。如上例子中main

3)如果 main 命令的执行,依赖后面命令执行所产生的文件,则先执行后面命令

4)当main 命令需要的文件生成完毕,则执行main 命令

注:需要C/C++ Linux服务器开发学习资料私信“资料”(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

大话C语言:文件操作

文件操作需要经过以下几个步骤:

  • 文件打开:C语言中,使用fopen函数来打开文件。该函数接受两个参数:文件路径和打开模式(如\”r\”表示只读,\”w\”表示写入,\”a\”表示追加等)。如果文件打开成功,fopen返回一个非空的文件指针;否则返回NULL。
  • 文件读写:C语言提供了多种函数用于文件的读写操作,如fgetc、fgets用于从文件中读取字符或字符串,fputc、fputs用于向文件中写入字符或字符串。此外,还有fread和fwrite函数用于读写二进制数据。
  • 文件定位:C语言中的fseek函数用于移动文件位置指针到指定位置,从而实现对文件的定位。通过定位,程序可以从文件的任意位置开始读写数据。
  • 文件关闭:使用完文件后,应该使用fclose函数关闭文件。关闭文件可以释放系统资源,确保数据的完整性。

文件操作

fopen是C语言标准库中的一个函数,用于打开文件,并返回一个指向该文件的指针,这个指针被称为文件指针。语法格式:

文件打开

fclose是用于关闭一个先前由fopen或类似函数打开的文件。语法格式:

代码示例:

注意,使用fclose时,应当总是检查其返回值以确保文件已经正确关闭。未正确关闭文件可能导致数据丢失或资源泄漏。在调用fclose之前,通常建议先清空文件缓冲区,以确保所有数据都被写入文件。

文件关闭

fgetc 是 C 语言标准库中的一个函数,用于从指定的文件流中读取一个字符。语法格式:

在使用 fgetc 时,通常需要检查返回值是否为 EOF,以确定是否已到达文件末尾或发生了错误。可以使用 feof(stream) 函数来检查是否到达文件末尾,使用 ferror(stream) 函数来检查是否发生错误。

代码示例:

fgets 是 C 语言中的一个标准库函数,用于从指定的文件流中读取一行数据,直到遇到换行符(\’\\n\’)、文件结束符(EOF)或读取了指定数量的字符为止(不包括末尾的换行符)。语法格式:

代码示例:

注意,

  • fgets 会将读取的字符串(包括末尾的空字符)存储在 str 指向的数组中。如果读取的字符串中包含换行符,它也会被存储在数组中。
  • fgets 会在读取到换行符、EOF 或读取了 n-1 个字符后停止(留一个位置给空字符)。这意味着如果一行中的字符数超过了 n-1,fgets 只会读取部分行。
  • 如果需要连续读取多行数据,并且每行数据的长度可能超过 n-1,你需要在一个循环中多次调用 fgets,每次处理完一行数据后再读取下一行。

fread是C语言标准库中的一个函数,用于从文件中读取数据。它可以将指定数量的数据项从文件中读取到内存中。语法格式:

代码示例:

注意,

  • fread函数主要用于读取二进制文件,但也可以用于读取文本文件。在读取文本文件时,需要确保正确处理换行符等文本特定的字符。
  • 使用fread时,应当检查返回值以确保正确读取了期望数量的数据项。如果返回值小于count,可能表示文件末尾已经到达,或者发生了其他错误。

fwrite是C语言标准库中的一个文件操作函数,主要用于将数据写入到文件中。其详细定义如下:

代码示例:

文件写入

fseek是C语言标准库中的一个函数,用于设置文件指针的位置。语法格式:

代码示例:

注意,在调用fseek之前,必须确保已经使用fopen打开了文件,并且传入了正确的文件指针。此外,fseek仅改变文件指针的位置,并不实际读取或写入任何数据。

文件定位

rewind是C语言标准库中的一个函数,用于将文件内部的位置指针重新指向一个流(数据流/文件)的开头置。语法格式:

代码示例:

ftell函数是C语言中的一个标准库函数,它的主要功能是返回当前文件指针的位置,即文件位置指针当前位置相对于文件首的偏移字节数。语法格式:

代码示例:

—E N D—

喜欢的记得关注哦!

您的支持是我们前进的动力!

点赞关注一下

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。