C语言复习笔记
C语言拾遗
目录
1我的第一个程序
#include <stdio.h>
int main(){ //main函数是程序的入口,一个程序有且只能有一个main函数
// printf("hello world\n");
// for(int i=0;i<255;i++){
// printf("%c %d\n",i,i);
// }
printf("%d\n",sizeof(int));
printf("%d\n",sizeof(float));
printf("%d\n",sizeof(double));
return 0;
}
2关键字
2.1 数据类型的关键字 类型名+变量名
void 一般是函数的参数或者返回值
char ch ='a'; char ch = 2;ascii码
int short int(64位 8 32位 4 16位 2) char
struct 结构体关键字
union 共用体关键字
enum 枚举类型关键字
signed 有符号
unsigned 无符号
void空类型关键字
void 一般用来修饰函数的参数或者返回值
2.2 存储相关的关键字
register寄存器关键字
用register修饰变量,尽量分配在寄存器
不能用取地址得到地址
不能定义数组
拿取更快
char short int 不能用float
register int a;
int *p;
p=&a;
静态变量 static
const
常量,会在指针详细讲解
auto
extern是外部的意思,一般用于函数或者全局变量的声明
2.3 控制语句相关的关键字
if else break continue for while do switch case
goto default
2.4 其他关键字
sizeof它是关键字 不只是函数
typedef重命名
volatile可改变 volatile重新去内存中去取,保证每次取得是最新得值
3 命名风格
linux 小写风格
驼峰风格 StuNum
区别大驼峰和小驼峰
4 数据类型
4.1基本类型
整型
十进制 正常数字开头
八进制 数字0开头
十六进制 0x开头
实型
十进制 0.0 0.12
123e3 123e10 123e-3
不以f结尾都是double
以f结尾都是float
-37 38 4字节 7位有效
-307 308 8字节 16位有效
字符型
直接常量 'a''1''\n''\t''\\''%%'
一个字节 ascii码存放
字符串
字符串常量,每一个字符串在最后一个字符的结尾都会有一个'\n'
%d 整型 %x16进制整数 %f %e指数形式 %p %u无符号
%p 指针指向的值
%3d 用空格去占位
%03d 用0去占位
%.2f
4.2构造类型
数组 结构体 共用体 枚举
4.3自动转换原则
- 由小类型转向大类型,以保证精度不缺失
- char int short int 一起运算全部转换位int进行运算
- 表达式中出现了实数,全部转化为double类型最终全部为
- 当表达式中无实数的时候,既有有符号又有有符号的数,所有有符号会转化为无符号进行运算,%d又会正常
- 在赋值语句中等号右边自动转化为等号左边的类型
- 自动类型转化都是临时性的,并不影响原本的值
4.3 强制类型转换
(类型说明符)(表达式)
把表达式的结果强制转换为类型说明符所表示的类型
5 运算符
5.1 算数运算符
用算数运算符将运算对象连接起来,符合c语言语法规则的式子,称为c算数表达式
- 双目运算符 参加运算的操作数只有一个
- 单目运算符
- 三目运算符
算数运算符 复合运算符
关系运算符 用于判断条件 是否满足循环语句
5.2 逻辑运算符
&& 两个条件同时为真,这个结果才能为真
|| 两个结果有一个为真,结果才为真
!
5.3 位运算
原码 反码 补码
正数在内存中以原码存放
负数是补码存放 取反加一
按位与& 必须都为1 结果才为1
按位或 |有一个1,就为1,同时为0,结果就是0
^ 相同为1 相反为0
~ 取反
逻辑右移 低位溢出 高位补0
算术右移动 低位溢出 高位补符号位 负数符号位为1
左移 高位溢出 低位补0
5.4逗号运算符(),()
逗号表达式的结果是逗号后边的表达式的结果
int num =(5,6);
6 数组
数组 若干个相同类型的变量在内存中有序存储的集合
int a[10];
数组的分类 按元素类型分 可以按照维数分
二维数组可以只初始化一部分
int b[2][2] ={{1,2},{1,2}};
可以只初始化一部分,但不能中间不初始化
逐个初始化int a[2][2]={1,2,3,4};
字符数组的引用
char c1[]={'h','e','l','l','o'};
char c2[]="hello";字符串初始化会多一个结束标志
char str[15];//最多存14个字符
scanf_s("%s",str,15);
int a[]={1,2,3};//不给出元素个数
字符串方式赋值会多占一个'\0'
7 函数
7.1分类
库函数 自定义函数 系统调用函数
有参函数 无参函数 在函数体里必须有return
如果函数把返回值类型省略了,默认返回整型
有返回值 和无返回值函数
所有函数的定义不能嵌套
给函数起名的时候,不能重复嵌套定义,见名知意
7.2 声明
直接声明法
间接声明法 包含头文件
自己定义的头文件需要用简介声明法
extern int max(int a,int b);
有返回值 num=fun();
无返回值 func();
8内存
static 静态变量 静态全局或者静态局部变量
内存分为 物理内存和虚拟内存 操作系统会给4G虚拟内存从0x00开始
操作系统会把虚拟内存映射到真实内存
堆区 动态申请的内存
栈区 局部变量 函数内部声明的
8.1静态全局区
未初始化 static 全局变量没有初始化
初始化的 全局或者静态赋过初值的
文字常量区 存放常量
代码区 存放我们的代码
8.2普通全局变量
在函数体外定义的变量——没有加static修饰
其他文件用的时候需要声明 extern int num;
静态全局变量限制了它的使用范围,只能用在一个.c里面
所以可以用static在不同函数中用同一名字的全局变量
但这些同名变量不是一个变量
8.3普通局部变量
函数或者复合语句中定义的变量
复合语句就是一个大括号内的语句
8.4静态局部变量
作用范围不变的,但是生命周期改变
第一次调用会开辟空间,并赋初值,第二次调用时就不开辟,不赋初值
普通局部变量不会赋初值随机的,静态局部变量,如果不赋初值,初值为0
但是studio会比较严格不允许使用未赋值的普通局部变量
同一作用范围内,不允许重名
作用范围不同可以重名,这里的范围是它能作用的整个范围不同是可以重名的,而不是在同一范围都有作用就不能重名的意思
局部范围内 就近原则
重新调用static修饰的局部变量时,不会刷新他的值吗?
形参也是局部变量
8.5 外部函数和内部函数
咱定义的普通函数都是外部函数,程序哪里都可以调用
也就是说普通函数通过包含头文件就可以使用啦
返回值前加static就会变为内部函数就只可以在一个.c中使用
同一个文件之间还是可以正常调用的
9 C语言的编译过程
9.1 分步编译
预处理 动态库 静态库
-
预编译 -E -o
将.c中的头文件展开,宏展开
生成的文件是.i文件
2.编译 -S -o
将.i生成.s
3.汇编 -c -o
将.s汇编生成.o文件
4.链接 -o
将.o文件 hello_elf
可以用esc去记忆呀
9.2预处理
#include<> 系统会在指定位置寻找文件
#include"" 现在当前目录去找 再去系统指定路径去找
#include可以包含.c 但会导致.c重复展开 重复定义
9.3宏定义
#define定义宏
9.3.1不带参
#define PI 3.14
一次修改多处变动 建议宏名改为大写
从定义的地方 到文件的末尾
#undef PI结束宏的作用范围
#define 3.1415926 可以接着定义宏
9.3.2带参宏
#define S(a,b) a*b 没有类型名
S(3+5,7); 3+5*7 = 38宏的副作用
可以通过添加括号来避免的宏的副作用 S(a,b) (a) *(b)
带参宏 浪费空间 节省时间 因为会多次展开 但没有压栈出栈
9.3.3选择性编译
#define AAA
#ifdef AAA
代码一
#else
代码二
#endif
if else都会编译的
但#ifdef 只会编译一部分
#ifndef AAA //if not define
#else
#endif
一般防止头文件重复包含
#ifndef FUN_H
#define FUN_H
要包含的头文件
extern int h(int a,int b);
#endif
#if 1
语句一
#else
语句二
#endif
9.4 动态编译
使用动态库进行编译
gcc hello.c -o hello
静态库 动态库
gcc -static hello.c -o hello
大小差别很大
静态库会把静态库文件打包编译到可执行程序中
动态库不会把动态库文件打包编译到可执行程序中
制作静态库
把.c制作 gcc -c mylib.c -o mylib.h
ar rc libtestlib.a mylib.o
libtestlib.a
gcc mytest.c libtestlib.a -o mytest
把头文件和库文件移动到/home/edu
-L /home/edu -ltestlib -I/home/edu
放到系统指定位置 /user/include
制作动态库
gcc -shared mylib.c -o libtestlib.so
gcc mytest.c libtestlib.so -o mytest
把动态库放在环境变量
把头文件和库文件 放在/opt处