上一篇: C语言入门篇之轮回法器(十六)(指针第五卷)
逐梦编程,让中华屹立世界之巅。
简单的事情重复做,重复的事情用心做,用心的事情坚持做;
文章目录
- 前言
- 一、内存管理具体介绍
- 1.作用域
- 2.生命周期的定义
- 3.局部变量
- 4.静态局部变量
- 5.全局变量
- 6.静态全局变量
- 7.上述所有总结
- 二、程序内存分布(图解示例)
- 二、静态函数
- 四、memset函数(内存设置)
- 五、memcpy函数(内存拷贝)
- 六、memcmp函数(内存比较)
- 七、动态内存分配
- 1.malloc函数(向堆区申请空间)
- 2.free函数(释放申请空间的内存)
- 总结
- 新壁纸
前言
就一个C语言程序而言,内存空间主要是由五个部分组成划分: 代码段(text)、数据段(data)、未初始化数据段(bss),堆(heap) 和 栈(stack) ,其中代码段,数据段和BSS段是编译的时候由编译器分配的,而堆和栈是程序运行的时候由系统默认分配的。
一、内存管理具体介绍
1.作用域
变量起作用的范围;
2.生命周期的定义
什么时候开辟空间(出生),释放空间(死亡),这个过程叫生命周期;
3.局部变量
作用域: 在定义变量的{}之内有效;
生命周期:程序运行至变量定义处开辟空间,所在的函数结束之后释放空间;
未初始化时候的值:随机数;
4.静态局部变量
作用域: 在定义变量的{}之内有效;
生命周期:执行main函数之前就已经开辟空间,程序结束之后才释放空间;
未初始化时候的值:0;
5.全局变量
作用域: 整个程序,所有文件;
生命周期:执行main函数之前就已经开辟空间,程序结束之后才释放空间;
未初始化时候的值:0;
6.静态全局变量
作用域: 当前文件;
生命周期:执行main函数之前就已经开辟空间,程序结束之后才释放空间;
未初始化时候的值:0;
7.上述所有总结
作用域:
局部变量(普通局部和静态局部)在{}范围之内 ;
普通全局变量作用域在整个工程 ;
静态全局作用当前文件;
生命周期: 只有普通局部是运行至变量定义处时开辟,函数结束释放,其他变量都是执行main函数之前就已经开辟空间,程序结束之后才释放空间;
初始化的值: 只有普通局部未初始化的值为随机,其他为0;
二、程序内存分布(图解示例)
二、静态函数
静态函数就是在函数定义时加上static修饰的函数,静态函数只可以被当前文件函数调用;
写法示例:
static void fun(){} ;
普通的函数没有加任何修饰,就是全局函数,整个工程可以调用;
四、memset函数(内存设置)
头文件添加:
#include <string.h>
函数原型:
void *memset(void *s, int c, size_t n);
功能:将s的内存区域的前n个字节以参数c填入;
参数:
s:需要操作内存s的首地址;
c:填充的字符,c虽然参数为int,但必须是unsigned char , 范围为0~255
n:指定需要设置的大小;
返回值:s的首地址;
代码示例:
/*-----------------------------------【程序说明】----------------------------
* 项目命题: C语言入门篇
* 代码所属: 瑶池酒剑仙(枫之剑客)
* 作者: 阿甘
* 开发时间: 2021/12/11
* IDE 版 本: Visual Studio 2015
* 项目版本: 1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://blog.csdn.net/gzplyx/article/details/128296570
int main()
{
int a =10;
//a = 0; -> memset()
memset(&a,0,sizeof(a));
char buf[10] = "";
strcpy(buf,"hello");
printf("%s\n",buf);
memset(buf,0,sizeof(buf));
printf("%s\n", buf);
//将前9个字符置为'a'
memset(buf,'a',sizeof(buf)-1);
printf("%s\n", buf);
system("pause");
return 0;
}
五、memcpy函数(内存拷贝)
头文件添加:
#include <string.h>
函数原型:
void *memcpy(void *dest, const void *src, size_t n);
功能:拷贝src所指的内存内容的前n个字节到dest所值的内存地址上;
参数:
dest:目的内存首地址
src:源内存首地址,注意:dest和src所指的内存空间不可重叠,可能会导致程序报错
n:需要拷贝的字节数
返回值:dest的首地址;
代码示例:
/*-----------------------------------【程序说明】----------------------------
* 项目命题: C语言入门篇
* 代码所属: 瑶池酒剑仙(枫之剑客)
* 作者: 阿甘
* 开发时间: 2021/12/11
* IDE 版 本: Visual Studio 2015
* 项目版本: 1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://blog.csdn.net/gzplyx/article/details/128296570
int main()
{
//将数组a中前5个元素拷贝至数组b中
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int b[10] = { 0 };
//a = b;
memcpy(b,a,sizeof(int)*5);
for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++)
{
printf("%d ",b[i]);
}
system("pause");
return 0;
}
六、memcmp函数(内存比较)
头文件添加:
#include <string.h>
函数原型:
int memcmp(const void *s1, const void *s2, size_t n);
功能:比较s1和s2所指向内存区域的前n个字节
参数:
s1:内存首地址1
s2:内存首地址2
n:需比较的前n个字节
返回值:
相等:=0
大于:>0
小于:<0
代码示例:
/*-----------------------------------【程序说明】----------------------------
* 项目命题: C语言入门篇
* 代码所属: 瑶池酒剑仙(枫之剑客)
* 作者: 阿甘
* 开发时间: 2021/12/11
* IDE 版 本: Visual Studio 2015
* 项目版本: 1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://blog.csdn.net/gzplyx/article/details/128296570
int main()
{
char num1[] = { 1,0,3,4,5,6,7 };
char num2[] = { 1,0,3,6,5,6,7 };
char str1[] = "dbakf\0afnafa";
char str2[] = "dbakf\0bfnafa";
//memcmp遇到\0字符并不会结束,全部拷贝
printf("%d\n", memcmp(str1, str2, sizeof(str1)));
//strncmp遇到\0字符会结束,部分拷贝
printf("%d\n", strncmp(str1, str2, sizeof(str1)));
system("pause");
return 0;
}
七、动态内存分配
1.malloc函数(向堆区申请空间)
头文件添加:
#include <stdlib.h>
函数原型:
void *malloc(size_t size);
功能:在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明符指定的类型。分配的内存空间内容不确定,一般使用memset初始化。
参数:
size:需要分配内存大小(单位:字节)
返回值:
成功:分配空间的起始地址
失败:NULL
2.free函数(释放申请空间的内存)
头文件添加:
#include <stdlib.h>
函数原型:
void free(void *ptr);
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,指向被释放区域的首地址。对同一内存空间多次释放会出错。
参数:
ptr:需要释放空间的首地址,被释放区应是由malloc函数所分配的区域。
返回值:无
代码示例:
/*-----------------------------------【程序说明】----------------------------
* 项目命题: C语言入门篇
* 代码所属: 瑶池酒剑仙(枫之剑客)
* 作者: 阿甘
* 开发时间: 2021/12/11
* IDE 版 本: Visual Studio 2015
* 项目版本: 1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://blog.csdn.net/gzplyx/article/details/128296570
int main()
{
//申请一个字符数组,有1024元素
char *p =(char *) malloc(1024);
memset(p,0,1024);
strcpy(p,"helloworld");
free(p+1);
//free(p); malloc申请的空间不可以释放两次,申请一次,释放一次
//printf("%s\n",p);
system("pause");
return 0;
}
总结
以上就是今天要讲的内容,今天讲的内容比较多,需要各位好好消化,可能有些朋友会觉得奇怪,为什么动态分配内存讲的比较简洁,没有进行过多的解释,
在这里博主希望大家以实战为主,理论为辅的核心思想来做编程,这样前期进步会快很多,在有了一定的基础之后,再去深入研究理论可谓事半功倍,不然就算讲了一大堆,可能也是一头雾水,给自己徒添烦恼而已。
让复杂的编程简单化;
文末了,喜欢的小伙伴帮忙点个赞收藏下,谢谢大家的支持!