一、存储类型
在定义一个数据(变量/数组)的时候,除了需要定义数据类型外,还需要定义存储类型。数据类型用于说明变量的长度和存储方式,而存储类型用于说明变量的使用规则
1.存储类型的分类
<1> 自动存储类型
<2> 寄存器存储类型
<3> 全局非static静态存储类型
<4> 全局static静态存储类型
<5> 局部static静态存储类型
<6> 外部存储类型
2.如何定义不同存储类型的变量
定义一种存储类型的变量,需要两个条件:定义位置和定义的形式
存储类型 | 定义位置 | 定义形式 |
---|---|---|
1.自动存储类型 | 代码块内 | int a; |
2.寄存器存储类型 | 代码块内 | register int a; |
3.全局非static静态存储类型 | 代码块外 | int a; |
4.全局static静态存储类型 | 代码块外 | static int a; |
5.局部static静态存储类型 | 代码块内 | static int a; |
6.外部存储类型 | 代码块外 | extern int a; |
3.不同存储类型变量的使用
存储类型 | 在内存中的位置 | 生存期 | 作用域(在程序中使用的区域) |
---|---|---|---|
1.自动存储类型 | 栈 | 定义–>代码块结束 | 代码块 |
2.寄存器存储类型 | 寄存器/栈 | 定义–>代码块结束 | 代码块 |
3.全局非static静态存储类型 | .data/.bss | 定义–>程序结束 | 多文件 |
4.全局static静态存储类型 | .data/.bss | 定义–>程序结束 | 单文件 |
5.局部static静态存储类型 | .data/.bss | 定义–>程序结束 | 代码块 |
6.外部存储类型 | .data/.bss | 定义–>程序结束 | 多文件 |
二、内存管理-----//堆空间申请和释放
堆和栈的区别
栈:
① 有名空间,可以通过空间的名称访问空间中的数据
② 空间比较小
③分配和释放由系统自动完成,对于程序员来说,不可控制
④ 执行效率较高
堆:
① 无名空间,只能通过指针访问堆空间
② 空间较大
③ 分配和释放由程序员完成,所有可以在程序中灵活的控制空间的生存期
④ 执行效率较低
1.申请堆中的空间——malloc()
#include <stdio.h>
void *malloc(size_t size);//申请一块堆空间
//参数----- size:要申请的空间大小
//返回值---- 成功:申请的空间的地址,失败:返回:NULL
//注意:
①申请的空间时连续的
②申请的空间没有初始化
③malloc返回值的地址必须要强制类型转换
④需要判断返回值是否可以使用
例如:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* p;
int i;
p = (int*)malloc(5*sizeof(int));
if(p == NULL){
perror("malloc"); //打印某个函数出错的信息
exit(1); //结束当前程序
}
for(i = 0; i < 5 ;i++)
*(p+i) = i+1;
for(i = 0; i < 5 ;i++)
printf("%d\t",p[i]);
printf("\n");
return 0;
}
2.释放堆空间——free()
#include <stdio.h>
void free(void *ptr);
//参数-----ptr:malloc 返回的地址
//注意:
①不能重复释放同一块空间
②不能释放申请的空间的一部分
③不能给free传NULL,没有意义
例如:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* p;
p = (int*)malloc(5*sizeof(int));
if(p == NULL){
perror("malloc"); //打印某个函数出错的信息
exit(1); //结束当前程序
}
*p = 123;
printf("*p = %d\n",*p);
//p = p+1; //不能释放申请的空间中的一部分
free(p);
//free(p); //不能重复释放同一块内存空间
free(NULL); //没有意义
return 0;
}
//另外两个申请堆空间的函数----不太常用
void *calloc(size_t nmemb, size_t size); //与malloc类似,申请对空间
//参数1 ----- nmemb:申请的数据的个数
//参数2 ----- size: 申请的数据的大小
//返回值----与malloc相同
例如: 在堆中申请有5个元素的int型的数组空间
int p;
p = (int)calloc(5,sizeof(int));
void *realloc(void *ptr, size_t size); //堆已申请的堆空间进行大小进行修改(扩展)
//参数1 ------要修改的对空间的起始地址
//参数2 ------修改之后的堆空间的总大小
//返回值 -----成功:修改后的空间的起始地址,失败:NULL
比如:使用malloc申请了20个字节的空间,发现不够用,此时,可以使用realloc()堆空间进行扩展
int p;
p = (int)malloc(5*sizeof(int)); //申请20个字节的空间
for(i = 0; i < 5; i++)
p[i] = i+1;
//堆上面申请的空间进行扩展
p = (int*)realloc(p,10*sizeof(int)); //扩展为40个字节的空间