一.栈区:
1.局部变量的生活在栈区(不管函数还是主函数内)
2.生命周期:
①定义变量的时候开始(开辟内存空间)
②所在作用域结束的时候消亡(被系统回收)
注:存在回收不及时的问题
二.堆区
1.动态申请空间
注:在不用的时候 需要手动释放 不会随着作用域的结束释放掉
2.两个相关函数:
①调用函数必须使用的头文件:#include<stdlib.h>
②申请空间:malloc();
例如:
1 int* p = (int*)malloc(4);
需要注意的是:虽然申请了四个字节 但是返回的是申请空间的首地址
返给我们的是一个void类型的指针(即void* 泛型指针) 或空
malloc申请的空间是连续的 动态创建
例题:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int main() 5 { 6 int* p = (int *)malloc(2*sizeof(int)); 7 p[0] = 1; 8 p[1] = 2; 9 printf("%d %d\n",*p,*(p+1)); 10 return 0; 11 }
结果为1 2
③释放空间:free();
注:放的是申请空间的首地址
例题:在上面例题的代码的第8行下面 如果加上一句free(p+1); 结果是会报错的
因为它回收了不属于自己的内存空间 不仅回收了p[1]的空间 它后面的4个字节也会被回收
这里需要注意的是:free释放也只能释放一次 也可以free(NULL); 但是这是没意义的
1 free(p); 2 p = NULL;
注:free完了一定要跟着p = NULL;
④生命周期:
malloc出生(分配空间)
free消亡(空间回收)
三.全局/静态区
1.数据段
2.BBS
(这里不做过多的说明 后面讲到会补充)
四.字符常量区
1.字符串:
①定义:以“\0”结尾的字符数组
注意:\0 0 ‘0‘ 三者的区别
\0在ASCⅡ码表中对应的数字就是0(\0 === 0)
‘0‘(字符0)在ASCⅡ码表中对应的值为48
②声明字符串的方法:
第一种:在栈区声明一个字符数组 并且初始化(可改)
1 char str[5] = {‘a‘,‘b‘,‘c‘,‘d‘,‘\0‘}; 2 printf("%s\n",str); //输出的时候放的是首元素的地址
第二种:在栈区声明一个字符数组 从字符常量区中拷贝一份复制(可改)
1 char str1[5] = "abcd";
第三种:在栈区声明一个char型指针 指向字符常量区的字符串(不可改)
1 char* str2 = "abcd";
2.字符常量区:
“ “里面的字符串都存在字符常量区中
字符常量区包含代码区(也就是说 我们打的代码都存在这里)
例题:输出函数练习
1 #include<stdio.h> 2 3 int MyPrint(char* str); 4 5 int main() 6 { 7 char* str = "abcd"; 8 MyPrint(str); 9 10 return 0; 11 } 12 13 int MyPrint(char* str) 14 { 15 int count = 0; 16 if(*str == NULL) 17 { 18 return -1; 19 } 20 while(*str != ‘\0‘) 21 { 22 printf("%c ",*str); 23 *str ++; 24 count ++; 25 } 26 27 return count; 28 }