# include <stdio.h>
# include <stdlib.h>
int main(){
printf(" Hello Word\n");
system("ls");
return 0;
}
程序解释
include
#include 的意思是头文件包含,#include<stdio.h> 代表包含了stdio.h这个头文件, 使用C语言库函数需要提前包含对应的头文件,因为上面的代码使用了printf()函数,需要包含stdio.h头文件
如果想要查看printf函数所需要的哪些头文件 可以使用指令 man 3 printf查看
@ZBMAC-C02F30VXMD6M include % man 3 printf
#include<> 和#include""的区别
- <>表示系统直接按照系统指定的目录检索
- “” 表示系统先在“”指定的路径(没有写路径表示当前路径)查找头文件,如果找不到,再按照系统指定的目录检索
系统头文件在操作系统的位置
linux操作系统下
@ZBMAC-C02F30VXMD6M include % cd /usr/include/
@ZBMAC-C02F30VXMD6M include % ls -l | grep stdio.h
-rw-r--r-- 7 root wheel 16208 1 9 2021 stdio.h
macOS操作系统下
@ZBMAC-C02F30VXMD6M include % cd /Applications/Xcode.app/contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
@ZBMAC-C02F30VXMD6M include % ls -l | grep stdio.h
-rw-r--r-- 7 root wheel 16208 1 9 2021 stdio.h
macOS 上的头文件、库文件都被 XCode 接管了,也就是说不安装 XCode 很多开发都是做不了的。
system函数
system函数是运行程序中执行另外一个外部的程序,参数是可执行程序的名字
这个函数必须包含头文件 stdlib.h
如上面的代码 就是在打印Hello Word 之后 执行了 ls的程序,相当于把当前目录下的所有文件都打印出来 打印的结果如下
hello
hello.c
hello.dSYM
Hello Word
程序编译
C代码编译成为可执行程序需要4个步骤
- 预处理
- 包括宏定义展开,头文件展开,条件编译,同时将代码中的注释删除,在这一步不会检查语法
- 编译
- 这一步主要是检查语法,将预处理后文件编译生成汇编文件
- 汇编
- 将汇编文件生成目标文件(二进制文件)
- 链接
- C语言写的程序是需要依赖各种库的,所以编译之后还需要把库链接到最终的可执行程序中
gcc
gcc(GNU Compiler Collection,GNU编译器套件),是由GNU开发的编程语言编译器,gcc原来作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(Linux,BSD, MacOS)采纳为标准的编译器,当然了,gcc 同样也适用于Windows
编译命令格式
gcc [option1] ... <filename>
g++ [option1] ... <filename>
- 命令,选项和源文件之间使用空格分隔
- 一行命令中可以有零个,一个或多个选项
- 文件名可以包含文件的绝对路径,也可以使用相对路径
- 如果命令中不包含输出可执行文件的文件名,可执行文件的文件名会自动生成一个默认名,Linux平台为a.out,Windows平台为a.exe
常用的选项
| 选项 | 含义 |
|---|---|
| -o file | 指定生成的输出文件名为file |
| -E | 只进行预处理 |
| -S(大写) | 只进行预处理和编译 |
| -c(小写) | 只进行预处理,编译和汇编 |
文件后缀
| 文件后缀 | 含义 |
|---|---|
| .c | c语言文件 |
| .i | 预处理后的c语言文件 |
| .s | 编译后的汇编文件 |
| .o | 编译后目标文件 |
预处理
gcc -E hello.c -o hello.i
该指令生成了预处理后的文件hello.i 打开hello.i 可以发现有1000多行,加了很多东西,这是预先需要的文件和路径以及条件编译都给添加了进来
编译
gcc -S hello.i -o hello.s
这一步是将预处理文件编译成了汇编文件,生成的都是相关的汇编指令,因为涉及的文件比较小 可以粘贴出来
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 15 sdk_version 10, 15, 6
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movl $0, -4(%rbp)
leaq L_.str(%rip), %rdi
movb $0, %al
callq _printf
leaq L_.str.1(%rip), %rdi
movl %eax, -8(%rbp) ## 4-byte Spill
callq _system
xorl %ecx, %ecx
movl %eax, -12(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
## -- End function
.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz " Hello Word\n"
L_.str.1: ## @.str.1
.asciz "ls"
.subsections_via_symbols
汇编
gcc -c hello.s -o hello.o
这一步骤是将汇编文件生成二进制文件
链接
gcc hello.o -o helloword
这一步骤是将二进制文件生成了可执行文件,