2020/3/22+2020/3/24
C语言
C语言(gcc)编译过程
源文件hello.c
-
预处理 hello.i(预处理文件)
-
编译 hello.s(汇编文件)
-
汇编 hello.o(目标文件)
-
链接 hello.exe(可执行文件)
预处理
-
参数:-E
-
生成的文件: xxx.i预处理文件
-
使用命令:gcc-E xxx.c -o xxx.i
-
工具:预处理器(包含在gcc编译集合工具中)
-
完成的工作:
-
头文件展开。
- 展开<stdio.h>文件内容,和源码一起,放到xxx.i文件中。
- 不检查语法错误,可以在这个阶段展开任意文件。
- 测试命令:gcc -E hello.c -o hello.i -I(大i)。(当前目录)
-
宏定义的替换。
- 将宏名,替换为宏值。
- 【解释】:define PI 3.14
- define 创建宏
- PI:宏名
- 3.14:宏值
-
替换注释。
- 把单行、多行注释替换成空行
-
展开条件编译。
-
ifdef 宏名······endif(如果定义“宏名”,进入条件)
-
根据条件展开代码
-
#include<stdio.h> #define PI 3.14 int main() { //展开条件编译。 #ifdef PI printf("5555 "); #endif }
-
-
编译
-
参数:-S
-
生成的文件: xxx.s预处理文件
-
使用命令:gcc -S xxx.i -o xxx.s
-
工具:编译器(包含在gcc编译集合工具中)
-
完成的工作:
- 逐行检查语法错误!【重点】——编译过程整个gcc编译4步骤最耗时的部分
- 将C语言程序翻译成汇编指令,生成汇编文件
汇编
-
参数:-c
-
生成的文件: xxx.o 目标文件(二进制)
-
使用命令:gcc -c xxx.s -o xxx.o
-
工具:汇编器(包含在gcc编译集合工具中)
-
完成的工作:
- 翻译:将汇编指令翻译成对应的二进制指令
链接
-
参数:无(-o不是链接阶段参数,是用来指定文件名)
-
生成的文件: xxx.exe 可执行文件(二进制)
-
使用命令:gcc -c xxx.o -o xxx.exe
-
工具:链接器(包含在gcc编译集合工具中)
-
完成的工作:
- 库引入。
- 合并多目标文件。
- 合并启动例程。
printf函数的格式化输出
d 以十进制形式输出带符号整数(正数不输出符号)
o 以八进制形式输出无符号整数(不输出前缀0)
x,X 以十六进制形式输出无符号整数(不输出前缀Ox)
u 以十进制形式输出无符号整数
f 以小数形式输出单、双精度实数
e,E 以指数形式输出单、双精度实数
g,G 以%f或%e中较短的输出宽度输出单、双精度实数
c 输出单个字符
s 输出字符串
程序调试
-
前提:程序,没有语法问题。
- 检查:程序出现的逻辑错误
-
核心思想:
- 让程序一行一行地执行
-
VS添加行号:
- 工具——选项——文本编辑器——代码语言——行号
-
程序调试流程:
-
添加断点:可以添加多个。
- 鼠标点击行号左侧灰色区域
- F9快捷键
-
调试,必须在Debug模式下。Release模式无效。
-
F5启动调试。
-
断点停止位置还未执行代码
-
开始调试
- 逐语句执行。逐语句执行下一行(F11):遇见函数,进入自定义函数内部,逐条跟踪执行。
- 逐过程执行。逐过程执行下一行(F10):遇见函数,不进入函数内部,逐条跟踪执行。
- 逐断点执行。代码中有多个断点,直接跳转到下一个断点。——点击“继续”
- 跳出函数。跳出当前函数。(shift+F10)
-
变量
变量3要素:
- 变量名:用来程序中使用
- 变量类型:开辟内存空间大小
- 变量值:储存的实际数据
变量定义
-
定义语法:类型名 变量名 = 变量值(一般定义法)(int m=666)
-
会开辟内存空间给变量。变量声明不会开辟内存空间。
变量声明
-
语法:
- int a; 没有变量值的定义,叫做声明。
- extern int a;添加 extern 关键字
-
特性:
- 变量必须有定义。
- 编译器,在使用变量之前,必须看到变量定义。如果没有看到,编译器会自动找寻一个变量声明。提升成 定义。
- 如果变量声明前,添加了extern关键字,无法提升!
常量
- 不会变化、不能被修改的数据
- define PI 3.14 ——【宏定义】定义常量
- const int a = 10 : const关键字:只读变量
标识符
变量和常量的总称
硬性要求
- 标识符不能是关键字、函数名。
- 标识符只能由字母、数字、下划线组成。
- 不能以数字开头。
- 大小写严格区分。
- 通常使用大写定义常量。
- 通常使用小写定义变量。
命名规范
- 大驼峰法:int HelloWorld;多个单词组成变量名,每个单词首字母大写。
- 小驼峰法:int helloworld;多个单词组成变量名,每个单词首字母小写。
- 小写+下划线(C语言专用)
sizeof关键字
- sizeof不是函数
- 使用方法:
- sizeof(变量名) ——返回变量大小,单位整数字节。
- sizeof(类型名) ——返回数据类型大小,单位整数字节。
- sizeof(变量名) ——语法C语言支持改写法,不推荐使用。
整型
有符号整型:
整型名 | 名称 | 格式匹配符 | 占用的大小 | 最小值 | 最大值 |
---|---|---|---|---|---|
int | 整型 | %d | 4字节 | -2147483648 | 2147483647 |
short | 短整型 | %hd | 2字节 | -65536 | 65535 |
long | 长整型 | %ld | Windows:32/64位 :4字节 Linux:32位:4字节 64位:8字节 | -2147483648 | 2147483647 |
long long | 长长整型 | %lld | 8字节 | -9223372036854775808 | 9223372036854775807 |
无符号类型:
整型名 | 名称 | 格式匹配符 | 占用的大小 | 最小值 | 最大值 |
---|---|---|---|---|---|
unsigned int | 无符号整型 | %d | 4字节 | 2147483647*2+1 | |
unsigned short | 无符号短整型 | %hd | 2字节 | 0 | 65535*2+1 |
unsigned long | 无符号长整型 | %ld | Windows:32/64位 :4字节 Linux:32位:4字节 64位:8字节 | 0 | 2147483647*2+1 |
unsigned long long | 无符号长长整型 | %lld | 8字节 | 0 | 9223372036854775807*2+1 |
char类型
-
字符型
-
单位:一个字节(8 bit 位)。
-
格式匹配符:
- 有符号:%hhd
- 无符号:%hhu
-
取值范围:
- 有符号:-128 ~ 127
- 无符号:0 ~ 255
#include <stdio.h>
#include <limits.h>
int main()
{
//获取无符号数取值范围
printf("char 无符号 min = 0, max = %hhu
",UCHAR_MAX);
//获取有符号数取值范围
printf("char 无符号 min = %hhd, max = %hhd
",CHAR_MIN,CHAR_MAX);
//获取 char 占用的字节数
printf("char 大小 = %u
",sizeof(char));
//获取 usigned char 占用的字节数
printf("unsigned char 大小 = %u
",sizeof(unsigned char));
return 0;
}
-
ANSII码
-
转义字符
-
‘ ’:转义字符
-
' / ':转义字符
- 将普通字符转化为特殊意义。‘ ’、' '。
- 将特殊字符,还原成本身意义。
-
实型(浮点型)【了解】
基础信息
- 显示小数
- float:单精度浮点型。 %f 大小:4字节。(可以用sizeof( )求取)【】
- float x = 4.35:4.35被默认为double类型
- float x = 4.35f:4.35被默认为float类型
- double:双精度浮点型。 %lf 大小:8字节。
取值范围
#include <stdio.h>
#include <float.h>
int main()
{
printf("float 范围:%f ~ %f
",FLT_MIN,FLT_MAX);
printf("double 范围:%lf ~ %lf
",DBL_MIN,DBL_MAX);
}
精度问题
-
float类型:
- 精度6 ~ 7位
- 整数部分+小数部分<=6位,准确;
- 整数部分+小数部分==7位,不一定准确;
- 整数部分+小数部分>7位,不准确。
- 精度6 ~ 7位
-
double类型:
- 精度15 ~ 16位
- 整数部分+小数部分<=15位,准确;
- 整数部分+小数部分==16位,不一定准确;
- 整数部分+小数部分 > 16位,不准确。
- 精度15 ~ 16位
-
不同平台(操作系统),对应float、double类型实现的精度有可能不同。以上是Windows下的特性。
-
float 和 double 不存在无符号类型。
bool类型
-
C语言原来没有bool类型。C99新增bool类型,C++自带bool类型。
-
用处:
-
表示:
-
好、坏
-
真、假
-
对、错
-
是、否
-
-
取值:
- true——真——1
- false——假——0
-
-
C语言使用bool的条件:
- 编译器需要支持C99的标准
- 导入头文件"stdbool.h"
-
bool类型的大小。
- 1字节。 sizeof()求取
-
bool没有专用的格式匹配符。打印时,使用%d来打印。
- true——真——1
- false——假——0
编码和存储
无符号数
unsigned int a = 12;//占用4字节,32个bit位存储
空间:00000000 00000000 00000000 00000000
存储:00000000 00000000 00000000 00001100
unsigned short b = 15;//占用2字节,16个bit位存储
空间:00000000 00000000
存储:00000000 00001111
有符号存储
-
需要拿出一个二进制位,专门存储符号。标识正、负。
- 选用最高位为符号位。
- 正:0
- 负:1
-
有符号正数:
//采用“源码存储” int a = 5; 空间:0 0000000 00000000 00000000 00000000 存储:0 0000000 00000000 00000000 00000101
-
有符号负数:
- 有符号的负数,采用“补码存储”
- 源码:数值的二进制直接存储
- 反码:符号位不变,将其余数值取反
- 补码:反码+1
- 有符号的负数,采用“补码存储”
int b = -33;
空间:0 0000000 00000000 00000000 00000000
源码:1 0000000 00000000 00000000 00100001
反码:1 1111111 11111111 11111111 11011110
补码:1 1111111 11111111 11111111 11011111
-
小结:
-
int——4字节——32 bit位
- 有符号:31个数值位。取值范围-2147483648 ~ +2147483647
- 无符号:32个数值位。取值范围0 ~ 4294967295
-
short——2字节——16bit位
- 有符号:15个数值位。
- 无符号:16个数值位。
-
-
因此,知道数据类型占用的内存的大小,就能算出该类型无符号位、有符号位对应的取值范围。