一、c语言的结构
1、程序
一个程序由一个或者多个源程序文件组成
2、源文件
- 预处理指令
- 全局申明
- 函数定义
3、函数
函数是c语言的重要组成部分
一个c语言程序是由一个或者多个函数组成的,其中必须包含并且只能有一个main函数。
1、函数首部:也就是函数的第一行
int max(int x, int y)
如果没有参数,可以写void或者空
2、函数体:
最外层花括号{}是函数体的范围。
- 申明部分 变量的定义
- 执行部分 函数中所进行的操作
可以是一个空函数,没申明部分,也没执行部分。
二、c语言的运行过程
编辑->编译->连接->执行
编译:
1、预编译
将.c中的头文件展开、宏展开
gcc -E a.c -o a.i
生成的文件时.i文件
2、编译
将预处理后的.i文件生.s汇编文件
gcc -S a.i -o a.s
3、汇编
将.s汇编文件生成.o目标文件
gcc -c a.s -o a.so
预处理
include
#include<>用<>包含的头文件,在系统指定的路径下找头文件。
#inlcude “” 用“”包含的头文件,现在当前目录下找头文件,找不到再到系统指定路径下找。
注意:此阶段不进行语法检查。
define
定义宏用define。
宏时在预编译的时候进行替换。
作用范围:从定义开始到文件末尾,或者#undef结束的时候。
1、不带参宏
#defind PI 3.14
在预编译的时候,如果代码中所有使用了PI的地方,就用3.14取替换。
好处:只要修改宏i你的定义,代码中的所有地方都被替换。
#undef PI 宏定义作用范围终止
2、带参宏
#define S(a,b) a*b
S(1,2) => 1*2;
S(1+2, 3) => 1+2*3;
选择性编译
1、#ifdef #else #endif
//如果定义过宏NUM,就执行片段1,否则片段2
#ifdef NUM
...
#else
...
#endif
2、#ifndef #else #endif
和第一个相反
3、#if #else #endif
//1为真,则执行1,如果写成#if 0.0为假,执行2
#if 1
//代码块1
#else
//2
#endif
三、数据类型
基本类型和枚举类型变量的值都是数值,统称为算数类型。
算数类型和指针类型统称为纯量类型。
数组类型和结构题类型统称为组合类型。
若干个相同或者不同类型的数据构成的集合,称为构造类型
3.1、整型数据
0开头表示八进制。
0x开头表示16进制。
3.1.1、int
32位系统下4个字节,16位系统占用2个字节。由编译系统决定。
存储方式:用整数的补码形式存放。
正数的补码:数的二进制形式
负数的补码:负数绝对值的二进制形式,然后取反,再加1
3.1.2、short int (short)
int位4字节,short int位2字节
3.1.3、long int (long)
int位4字节,long int位4字节
3.1.4、long long int (long long)
int位4字节,long int位8字节
3.2 字符类型
字符是按其代码(整数)形式存储的。
A=65
a = 97
3.3 浮点类型
c语言中,实数是以指数形式存储的。
123e3表示12310^3
123e-3表示12310^-3
默认为double类型,f结尾的是float类型(12.3f)
3.4、类型转换
3.4.1 加减乘除
1、加减乘除中两个数有一个位float或double类型,结果都是double。
2、int与float或者double类型运算,先把int类型和float转为double,然后再运算。
3、字符(char)型数据与整型数据运算,就是把ASCII代码与整型数据运算。
4、当表达式中有有符号数,也有无符号数,都会变成无符号数参加运算,结果也是无符号数。
3.4.2 强制类型转换
(double) a 将a转换为double类型
(int)(x+y) 将x+y的值转换为int类型
3.4.3 自动转换
占用内存字数的小的类型向占用内存字节数多的类型自动转换,保证精度不降低。
3.4.5 赋值语句
赋值语句中,等号右边自动转换为等号左边的类型。
四、格式化输出字符
%d 十进制有符号整数
%x 16进制表示的整数
%f float类型浮点数
%e 指数形式浮点数
%s 字符串
%p 指针的zhi
%u 十进制无符号整数
%o 八进制表示的整数
%lf double类型浮点数
%c 单个字符
特殊用法:
%3d 不足3位, 前面用空格补齐
%03d 不足3位,前面用0补齐
%-3d 不足三位,后面用空格补齐
%5.2f 一共5位,小数点后面只保留2位,整数位不足用空格补齐,小数位用0
五、存储相关关键字
register、static、const、auto、extern
5.1 register
寄存器的意思,用register修饰的变量是寄存器变量。
即:再编译的时候告诉编译器这个变量是寄存器变量,尽量将其存储空间分配在寄存器中。
1、定义的变量不一定真的存放在寄存器中。
2、cpu取数据的时候去寄存器中拿数据比内存中拿数据快。
3、因为寄存器比较宝贵,不能定义寄存器数组。
4、register只能修饰字符型和整型,不能修饰浮点型。
5、因为register修饰的变量可能存放在寄存器中,所以不能对寄存器变量取地址。
register int a;
int *p;
p = &a;//错误的。a可能没有地址。
5.2 static
static可以修饰全局变量、局部变量、函数
5.3 const
const是常量的意思,用const修饰的变量是只读的,不能修改他的值。
const可以修饰指针。
5.4 auto
auto int a 和 int a是等价的,现在基本不用
5.5 extern
是外部的意思。一般用于函数或全局变量的声明。
六、其他关键字
sizeof typedef volatile
6.1 sizeof
用来测变量、数组的占用存储空间的大小。
6.2 typedef
重命名,作用是给一个已有的类型重新起个类型名。
typedef int INT16;
INT16 a;等价于int a;
6.3 volatile
cpu使用volatile变量的时候,重新去内存中取,保证用的是最新的值。
命名规则:c语言中标识符由字母数字和下划线构成。且只能以字母或吓坏西安开头。