linux终端下,编译C语言程序步骤为:
十余年的锡林郭勒盟网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整锡林郭勒盟建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“锡林郭勒盟网站设计”,“锡林郭勒盟网站推广”以来,每个客户项目都认真落实执行。
采用vi进行源代码编写,编写完成后,:wq存盘退出,如:
vi test.c
在命令行下,运行gcc编译程序,生成执行码,如:
gcc -o test test.c
-o 表示指明生成的执行码名称
运行编译后的执行码
./test
system(执行shell 命令)
相关函数 fork,execve,waitpid,popen
表头文件 #includestdlib.h
定义函数 int system(const char * string);
函数说明 system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
返回值 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。
附加说明 在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。
范例 #includestdlib.h
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shadow
主要使用gcc命令以及以下几个参数:
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o file Place the output into file
环境配置好以后,让我们开始c语言的编译之旅吧~
编写c语言源代码
很多linux命令都可以新建一个文件,比如
$ touch test.c
建立一个空白的文件
$ vim test.c
使用vim(文本编辑器)编辑test.c,如果test.c不存在,则创建
$ echo "123" test.c
通过输出重定向新建一个文件
创建完test.c后,将下面这段Hello World代码写到test.c中(很多方法)
#include stdio.h
int main(){
printf("Hello world\n");
return 0;
}
写完之后可以使用ls命令来查看当前目录下的文件,检查test.c是否存在
$ ls
使用cat命令查看test.c中的内容,检查是否写入成功
$ cat test.c
ls-cat
展开头文件(预处理)
$ gcc -E test.c -o test_pre.c
这个命令把源代码test.c中的头文件展开,并把结果输出到test_pre.c
(可以使用cat或者vim命令查看test_pre.c文件中的内容)
per
test_pre.c中的内容是这样的,可以发现原本几行的代码变成了几百行,而且已经见不到include关键字了,取而代之的是一些变量定义的代码,这些代码就是stdio.h中的内容,和stdio.h中头文件展开后的内容。
编译
$ gcc -S test_pre.c -o test_asm.s
这一条命令将上一步预处理过后的源代码编译成为汇编代码
asm
现在看到的是test_asm.s里面的汇编代码。
什么是汇编?
汇编语言是汇编指令集、伪指令集和使用它们规则的统称,使用具有一定含义的符号为助忆符,用指令助忆符、符号地址等组成的符号指令称为汇编格式指令。
简单的可以理解为汇编语言是一本词典,01100101011010这样的二进制字符串是单词,汇编指令是单词的含义。计算机能读懂二进制字符串,而人能读懂的是翻译过来的汇编指令。
汇编
$ gcc -c test_asm.s -o test_obj.o
这一步将test_asm.s汇编成为目标文件,目标文件中存储的就是010101010这样的字符串了,可以用cat命令试试去读取test_obj.o
obj
可以发现打印出来许多不可见的字符,原因是目标文件已经是二进制格式的了,不同于源代码(文本格式)
有关文件的格式可以看下这里的介绍:
链接
链接器负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。
这个例子中没有附加的目标文件,所以只需要目标文件做被链接的对象。
有关链接器的详细讲解大家可以看下这里:
$ gcc test_obj.o -o hello
gcc本身可以充当链接器,这里使用gcc命令将目标文件test_obj.o链接成了可执行文件hello
ld
运行程序!
至此,源代码已经经历了预处理、编译、汇编、链接四步成为了可执行文件,现在试着运行一下这个程序吧
$ ./hello
hello
小结
首先我们创建了源文件test.c,然后用gcc -E将源文件中的头文件展开,这一步叫做预处理;
之后通过gcc -S将预处理后的源文件编译了汇编代码,这一步叫做编译;
接着使用gcc -c命令将汇编代码转换成了二进制的目标文件,这一步操作叫做汇编;
目标文件不同于源代码,是二进制格式,是源文件编译过程中产生的中间文件,通过链接器可以将多个目标文件链接成为可执行文件,这一步叫做链接。
源文件-(预处理-编译-汇编-链接)-可执行文件
一般大家所说的c语言编译,其实是上述这四步的简称。