Linux+C 语言零基础 Day2|拆解 GCC 四层编译流程,吃透 C 语言全部基础数据类型
目录
- 前言
- 模块 1:深挖 gcc 编译四大流程,代码的四层 “变形记”
- 1.1 预处理 gcc -E
- 1.2 编译 gcc -S
- 1.3 汇编 gcc -c
- 1.4 链接 gcc (最终生成可执行文件)
- 模块 2:C 语言底层必学基础,写代码的底层逻辑
- 2.1 程序是如何在计算机中运行的?
- 2.2 计算机存储单位换算(全二进制计数)
- 2.3 进制转换速记技巧
- 2.4 C 语言基础数据类型:电脑里不同尺寸的收纳盒
- 2.5 常量与变量
- 总结
前言
哈喽各位零基础小伙伴!昨天(Day1)我们搞定了 Linux 虚拟机操作、终端基础命令、vi 编辑器,还成功用 gcc 跑通了 Hello World 程序,当时天真以为敲一句gcc test.c就能直接出可执行文件,编译原理到此结束。
结果第二天上课直接被狠狠 “补课”—— 原来一行 gcc 命令背后藏着四道完整工序,同时还要啃完 C 语言最底层的核心基础:程序运行逻辑、存储单位、进制转换、全套基础数据类型、常量与变量。
本文整理了课堂完整笔记,全程用生活化比喻拆解晦涩底层知识,避开新手容易踩的坑,没有复杂难懂的专业黑话,适合刚入门 Linux+C 的小白收藏复盘!
模块 1:深挖 gcc 编译四大流程,代码的四层 “变形记”
把 C 代码变成电脑能看懂的程序,gcc 不会一步到位,而是分预处理→编译→汇编→链接四步,我用「做蛋糕」给大家类比,超好记:
预处理:拆原料包、整理食材(处理 #开头指令)
编译:把文字配方翻译成烘焙操作手册(生成汇编代码)
汇编:把手册做成蛋糕胚(二进制目标文件)
链接:蛋糕胚 + 奶油配件组装成完整成品(可执行程序)
1.1 预处理 gcc -E
命令:gcc filename.c -o filename.i
核心工作:专门处理代码中所有#开头指令
展开#include头文件,把 stdio.h 等库内容全部塞进代码;
替换#define宏定义,纯文本替换,不会计算;
裁剪#if/#ifdef/#else条件编译无效代码;
删除全部注释内容。
1.2 编译 gcc -S
命令:gcc filename.c -o filename.s
把处理完的 C 语言代码,翻译成汇编语言文本文件,检查语法错误,代码有拼写 / 语法问题会在这里直接报错。
1.3 汇编 gcc -c
命令:gcc filename.c -o filename.o
将汇编代码转为纯二进制机器码,生成目标文件.o,此时文件电脑能识别,但还无法独立运行。
1.4 链接 gcc (最终生成可执行文件)
命令:gcc filename.c -o filename
把.o目标文件、系统库文件整合拼接,生成我们能直接运行的程序;不加-o指定名称,默认生成a.out。
运行程序命令:./程序名
模块 2:C 语言底层必学基础,写代码的底层逻辑
2.1 程序是如何在计算机中运行的?
我们写的.c源码、编译好的可执行程序,全都存放在硬盘(外存);执行程序瞬间,系统会把二进制程序加载进内存,CPU 读取内存指令执行;程序运行结束,系统回收内存空间,数据清空。
2.2 计算机存储单位换算(全二进制计数)
计算机只识别 0 和 1,最小单位是 bit(位):
1 Byte(字节)= 8 bit
1 KB = 1024 Byte
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
2.3 进制转换速记技巧
二进制:逢二进一(0、1);
八进制:逢八进一;
十进制:日常数字;
十六进制:0-9、a-f;
任意进制转十进制:每一位数字 × 当前位权值,全部相加;
十进制转其他进制:数字反复除以目标进制,余数倒序排列;
二进制快捷转换:3 位二进制对应 1 位八进制,4 位二进制对应 1 位十六进制。
2.4 C 语言基础数据类型:电脑里不同尺寸的收纳盒
数据类型就像收纳盒,大小不同,能存放的数据范围、格式完全不一样,分为基本数据类型(系统自带)和构造类型(自定义)。
(1)整型(存放整数)
short 短整型:占 2 字节
signed short(默认):范围 -32768 ~ 32767
unsigned short:范围 0 ~ 65535
int 整型:占 4 字节
signed int:-21 亿~21 亿
unsigned int:0 ~ 42 亿
long 长整型:占 8 字节
signed long:超大正负整数
unsigned long:0 ~ 2⁶⁴-1
(2)浮点型(存放小数)
float 单精度:4 字节,1 位符号 + 8 位指数 + 23 位尾数,仅 6~8 位有效数字;
double 双精度:8 字节,精度更高,12~16 位有效数字,代码中小数默认 double 类型。
(3)char 字符型
最小收纳盒,仅 1 字节
本质存储 ASCII 码数字,不是直接存文字:
unsigned char:0~255
signed char:-128~127
例:字符’A’对应 ASCII 码 65,单引号只能包裹单个字符。
(4)bool 布尔逻辑类型
只有两个值:true (1)、false (0);
C 语言规则:非 0 数字全为真,0 为假。
(5)void 空类型
无固定存储空间,多用于函数参数、指针,代表 “无数据”。
2.5 常量与变量
常量:程序运行全程不能修改的值
整型常量:123、0123(八进制)、0x1a(十六进制)、100U/100L;
浮点常量:3.14、3.14f、1e5;
字符常量:单引号包裹单个字符 ‘0’、'\n’转义字符;
字符串常量:双引号包裹,末尾自动隐藏结束符\0;“a” ≠ ‘a’;
宏定义常量:#define M 50,仅纯文本替换,写宏建议全部加括号,避免计算 bug。
变量:运行过程中数值可以随时修改
定义后分配内存空间,赋值后可重复修改,是程序存储临时数据的核心。
总结
今日核心知识点复盘
gcc 编译四阶段:预处理 (-E)→编译 (-S)→汇编 (-c)→链接,每个阶段有专属命令与产物;
程序运行流程:外存存放代码,运行载入内存,结束回收内存;
存储单位、进制转换是底层基础,看懂数据存储必备;
五大基础数据类型对应不同内存大小,选错类型会出现数据溢出、浪费空间;
常量不可修改,变量支持重复赋值;宏定义只是文本替换,不是运算。
新手踩坑提醒
Linux 文件名区分大小写,尽量不用空格,用下划线替代;
宏定义一定要给表达式加括号,否则四则运算会出错;
字符串自带\0结束符,不要混淆字符’a’和字符串"a";
小数默认是 double,写 float 小数末尾要加 f;
无符号数字不能存负数,否则会出现溢出乱码。
