数据结构学习
存储结构
static类型
-
static修饰未初始化的全局变量时,默认结果为0;
-
static修饰局部变量时,起延长生命周期的作用;(注意:生命周期不等同于作用域,局部变量使用static修饰后依旧是局部变量)
全局变量:生命周期和作用域都是从定义开始到文件结束;
局部变量:未用static修饰时,生命周期和作用域都是从定义开始到本函数结束; -
在使用多文件编译中:static修饰函数只能在当前文件中调用,不可以跨文件调用;
-
static修饰其他文件的全局变量,不可以使用extern引用;
-
static修饰指针不可以指向auto类型的地址;
原因:计算机先为静态变量分配空间,后再分配auto类型变量的空间;不可以使用指针指向不存在的变量地址,会造成野指针;
extern
- 是C和C++中的一个关键字,用于声明一个全局变量或者函数,但不定义它们,它告诉编译器该变量或函数在其他文件中定义,提示编译器不要在当前文件中分配内存空间或者生成代码。
- 作用:引用外部变量;
const(不是存储类型,用于修饰变量)
- 作用:修饰的变量不发生改变;
- const修饰的全局变量,值不发生改变,变量的空间在静态区的.ro(只读)段
- const修饰的局部变量,值不变,变量的空间在栈区;
- const和指针
const int *p *在const的右边,修饰的是值,所以值不可以改变,地址可以发生改变;
int const *p同理;
int *const p *在const的左边,修饰的是地址,所以地址不可以改变,值可以发生改变;
const int *const p 第一个const修饰的是值,第二个const修饰的是地址,所以值和地址都不可以发生改变;
int const * const p 第一个const修饰的值,第二个const修饰的地址,所以值和地址都不可以发生改变;
auto自动类型
- 当默认不写存储类型时,默认就是auto类型;
- auto不可以直接修饰全局变量【auto int a】,定义全局变量时,默认是auto类型,但是不能是auto修饰,空间在静态区,从定义开始到整个文件结束(可以使用extern引用);
- auto修饰局部变量时,空间在栈区,从丁一开始到本函数有效
- 不可以返回一个局部变量的地址;
register存储类型
- register是寄存器存储类型;
- 作用:表示这是一个寄存器变量;
- 运行速度:寄存器>cache(高速缓存)>内存
- 特点:不可以进行寻址操作
volatile类型
- volatile不是存储类型
- 作用:防止内存优化,保持内存的可见性
虚拟内存空间
- 栈的思想:先进后出,后进先出;先定义变量后分配空间,导致栈的地址分配值从大地址到小地址
- 堆区:满足队列思想,先进先出,后进后出,先定义变量先分配空间,导致堆区的地址分配从小地址到大地址。
- 栈区和堆区没有明确的边界点,当栈区地址和堆区地址临界,那就是边界。
动态申请和释放空间
- 动态申请:
头文件:#include <stdlib.h>
格式:void *malloc(size_t size);
参数:size_t size 表示堆区申请空间字节大小
返回值:void *,如果申请成功则返回堆区空间首地址,如果申请失败则返回NULL,记得保存堆区首地址;
使用格式:
申请单个空间:int *p=(int *)malloc(sizeof (int));
申请连续空间:int *p=(int *)malloc(sizeof (int)*n); - 动态释放:
头文件:#include <stdlib.h>
格式:void *malloc(size_t size);
参数:size_t size 表示堆区申请空间字节大小
返回值:void *,如果申请成功则返回堆区空间首地址,如果申请失败则返回NULL,记得保存堆区首地址;
使用格式:
int *p=(int *)malloc(sizeof (int)*n);
free§;
p=NULL;//防止野指针 - 野指针:
(1)未初始化的指针直接使用,称为野指针
(2)返回一个局部变量的地址,称为野指针
(3)通过指针越界访问数组
(4)指针指向堆区空间,释放指针,此时称为野指针宏
宏定义
格式:#define 宏名 宏体
宏:不可以修改,是常量,只做替换,不做计算,不做正确性检查宏函数
#if 宏条件
c语句1
#else
c语句2
#endif
如果宏条件成立则执行C语句1,否则执行C语句2
多用于注释
#ifndef 宏名
c语句1
#endif
如果宏名未定义,则执行C语句1
#ifdef 宏名
C语句;
#endif
如果宏名已经定义,则执行C语句1
多文件编译
头文件:预处理命令、函数声明、全局变量
主函数:存储主函数
自定义函数
typedef
- 作用:类型重定义,起别名
- 格式:typedef 数据类型 别名
别名:满足命名规范
typedef是关键字,是C语句要加分号
typedef和#define之间的区别
#define size_4 int —> typedef int size_4
- typedef属于C语句,宏不属于C语句
- typedef在编译阶段,宏在预处理阶段
- typedef是类型重定义,宏属于替换
- typedef可以适用于任何复杂的数据类型,但是宏只能适用于基本类型的替换