三,编译器
负责将人们可以看懂的记录着代码的文件,翻译成计算机可以看懂的二进制文件,由预处理器,编译器,链接器组成。
gcc是由GUN社区为了编译Linux内核代码而开发的一款免费的编译器
gcc常用的编译参数:
-E 只显示预处理的结果到终端
-std=gun99 设置C99语法标准
-c 只编译不链接
-o 指定编译结果的名字 -o name
-S 只生成汇编代码
-I 指定头文件的加载路径
-Wall 尽可能多的产生警告
-Werror 把警告当作错误处理
-l 指定要加载的代码库文件 -lm 使用数学库
四,C代码变成可执行文件的详细过程:
1,预处理 把源文件翻译成预处理文件
gcc -E code.c 显示预处理结果到终端
gcc -E code.c -o code.i 生成以.i结尾的预处理文件
2,编译 把预处理文件翻译成汇编文件
gcc -S code.i 生成以.s结尾的汇编文件
3,汇编 把汇编文件翻译成二进制的目标文件
gcc -c code.s 生成以.o结尾的目标文件
4,链接 把若干个目标文件合并成最终的一个可执行文件
gcc a.o b.o c.o ... 默认生成a.out的可执行文件
五,C语言的文件类型:
.c 源文件
.h 头文件
.h.gch 头文件的编译结果文件,它会被优先使用
.i 预处理文件
.s 汇编文件
.o 目标文件
.a 静态库文件
.so 共享库文件
六,存储空间的单位:
Bit 比特 一个二进制位,只能存储0和1,计算机中存储数据的最小单位
Byte 字节 八个二进制位,计算机存储器描述存储存储容量的基本单位
KB = 1024字节
MB = 1024KB
GB = 1024MB
TB = 1024GB
七,数据类型:
为什么要对数据进行分类?
1,现实生活中的数据本身就自带类别属性
2,对数据进行分类可以节约存储空间,提升运行速度
C语言中数据分类为两大类: 自建(程序员自己设计的类型:结构,联合,类)和内建(C语言自带的类型)
tap:运算符 sizeof 可以计算类型,变量的字节数
整型:
signed 有符号 11010111 二进制数的第一位代表正负0为正1为负
signed char 1字节 -128 - 127
signed short 2字节 -32768 - 32766
signed int 4字节 正负20亿左右
signed long 4/8字节
signed long long 8字节 正负9开头的19位数整数
unsigned 无符号
unsigned char 0 - 256
unsigned short 0 - 65535
unsigned int 0 - 40亿左右
unsigned long
unsigned long long 0 - 1开头的20位整数
tap: signed 不加表示存在,由于定义无符号整型时比较麻烦,C标准库把这些类型重定义成一些简单的类型名
需要导入头文件<stdint.h>
uint8_t uint16_t uint32_t uint64_t 无符号整型
int8_t int16_t int32_t int64_t 符号整型
浮点型:有小数部分的类型
float 4 单精度
double 8 双精度
long double 12/16
tap:小数点后6位有效; 采用一定的算法对真实的浮点型数据奥二进制数据进行转换,这个过程比存储,读取整型要慢得多
编程时尽量使用整型
double num;
if(num < 0.0000001 && num > -0.0000001);表示 double 类型等于0
模拟型:
字符型: char
字符就是符号和图案,在内存中储存的依然是整数,需要显示出字符时,会根据ASCII表中对应的关系显示出对应的字符或者图案
'0' 48 'A' 65 'a' 97 '空字符\0' 0
布尔型: bool
先有C语言后有布尔型,所以C语言中没有真正的布尔型,在头文件stdbool.h中对布尔型进行了模拟
非零值为真 true 0为假 false
八,变量与常量
变量:程序运行期间数值可以可以发生变化的,相当于一个储存数据的盒子
定义:类型名 变量名;
int num;
取名规则:
1,由字母,数字,下划线组成
2,不能以数字开头
3,不能与C语言32个关键字重名
4,见名知意(功能,类型,作用范围... )
使用:
赋值: 变量名 = 10;
参与运算: 2+(变量名*10);
tap:C语言中变量的初始值是随机的,为了安全起见,一般在定义时初始化为0。
变量的输入与输出:
int printf(const char *format,...)
功能:输出数据
format:"双引号包含的提示信息+占位符"
... :变量名列表
返回值 :输出字符的个数
类型占位符:C语言中通过类型占位符传递变量的类型
signed
%hhd %hd %d %ld %lld
unsigned %hhu %hu %u %lu %llu
float %f
double %lf
long double %Lf
char %c
int scanf(const char *format,...);
功能:输入数据
format:"双引号包含的占位符"
... :变量地址列表
返回值:成功输入的变量的个数
tap:scanf需要提供变量的地址
&变量名 == 变量地址
常量:程序运行期间数值不能改变的叫做常量
100 默认int类型
100l long
100ll long long
100u unsigned int
100lu unsigned long
3.14 默认double类型
3.14f float
3.14l long double
九,格式化输入输出:
%nd 显示n个字符宽度,不够则补充空格,右对齐
%-nd 显示n个字符宽度,不够则补充空格,左对齐
%0nd 显示n个字符宽度,不够则补充 0 ,右对齐
%n.mf 显示n个字符宽度,不够则补充空格,m表示小数点后m位(四舍五入),右对齐
%g 不显示小数点后多余的 0
十,运算符
自变运算符: ++/-- 使变量的值自动加一或减一
前自变: ++num/--num 立即生效
后自变: num++/num-- 下一行代码才生效
tab:不要再一行代码内多次使用自变运算符
算数运算符:+ - * / %
整数/整数 结果是整数,没有小数点,只保留整数部分
10/3 = 3
10%3 = 1
/ %除数不为0 若为0 则 浮点数例外,(核心已转储),运行报错,一旦产生则程序立即停止,后面不再执行
关系运算符:> < >= <= == !=
比较结果 0 (不成立) 1 (成立)比较的结果可以继续参与后续的运算
int n = -100
if(10 < n <100) 结果恒为真 数学上不成立 C语言中恒为真
tap: == 建议常量放左边
逻辑运算符: && || !
先把运算对象转换成逻辑值,0 转换为假,非 0 转换为真
A && B 一假为假
A || B 一真为真
!A 求反
&& || 短路特性:
当左边部分的逻辑值可以确定整个表达式的结果时,右边部分就不执行计算
三目运算符:运算的对象有三个部分
A ? B : C
判断A的值是否为真,为真执行B,否则执行C
赋值运算符:
a = 10;
a+= 10; a = a+10;
a-= 10; a = a-10;
a*= 10; a = a*10;
...
位运算符: & | ~ ^ << >>
十一,分支语句
if(表达式)//单分支
{
//表达式为真(非0),则执行此处代码
}
if(表达式)//双分支
{
//表达式为真(非0),则执行此处代码
}
else
{
//表达式为假(为0),则执行此处代码
}
if(表达式)//多分支
{
//表达式为真(非0),则执行此处代码
}
else if(表达式2)
{
//表达式2为真(非0),则执行此处代码
}
...
...
else if(表达式n)//单分支
{
//表达式n为真(非0),则执行此处代码
}
else
{
//如果以上都为假,则执行此处代码
}
switch(n) //n可以是数值,表达式,运算结果必须是整数
{
case val: //如果val的值 == n 则打开执行开关
//val必须是常量
...
break; //关闭执行开关,结束swich
//如果每个case后都有break,那就形成了分支结构
...
case val n:
default://所有case都没执行时,则最后打开default,放在任何位置都会最后打开
...
break;
}
tap:switch不能与continue配合。case a ... b : 可以表示一个连续的范围[a,b],但是只有GUN编译器可以使用。
数据类型相关:(32个关键词)
内建类型:
char short int long void float double 7
自建类型:
struct union enum sizeof 4
类型限定符:
auto const static volatile register typedef extern signed unsigned 9
流程控制相关:
分支:
if else switch case default 5
循环:
for while do 3
跳转:
break continue goto return 4