• <C> 内存分区


    一.栈区:

    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
    ",*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.引入:在主函数中定义一个a 但是在功能函数中 让a=10

    这样是不可以的 因为作用域不同 不在一个作用域内

    2.全局变量:

    ①定义:在头文件和主函数之间

    例如:

    1 int g_a;

    注:如果在主函数中 直接调用(没有初始化) 输出结果为0(即默认初始化为0)

    全局变量在主函数中是认识的 在功能函数中也是认识的 可以在主函数或者自己定义的函数中对其进行读写

    ②作用域:整个文件

    可见范围:整个文件都可见

    ③生命周期:运行时就有 结束时消亡

    先声明 后使用 外部只可以作声明 不能对其进行操作

    了解:多文件可用 可以跨文件使用 但是需要在其他文件中进行外部引用

    3.静态变量:

    ①定义:

    1 static int i = 1;

    注:静态变量在内存中 只存一份(只能声明一次) 默认初始化为0

    ②作用域:只在声明的作用域内有效

    ③生命周期:程序结束才能被回收

    注:只是此文件可见

    4.总结:全局变量和静态变量就存在全局/静态区

    所以不会随着作用域的结束而被回收 是随着程序走的

    全局/静态区 包括:

    ①数据段:放已经被初始化过的全局变量/静态变量

    ②BSS:放未被初始化的全局变量/静态变量

    这里放一道例题加深对全局变量和静态变量的例题:

     1 #include<stdio.h>
     2 
     3 void AA();
     4 
     5 int a;
     6 
     7 int main()
     8 {
     9     AA(); //输出1
    10     AA(); //输出2
    11     AA(); //输出3
    12 
    13     printf("%d
    ",a); //输出0
    14     a = 10;
    15     printf("%d
    ",a); //输出10
    16 
    17     return 0;
    18 }
    19 
    20 void AA()
    21 {
    22     static int i = 0;
    23     i++;
    24     printf("%d
    ",i);
    25 }

    四.字符常量区

    1.字符串:

    ①定义:以“”结尾的字符数组

    注意:  0  '0' 三者的区别

    在ASCⅡ码表中对应的数字就是0( === 0)

    '0'(字符0)在ASCⅡ码表中对应的值为48

    ②声明字符串的方法:

    第一种:在栈区声明一个字符数组 并且初始化(可改)

    1 char str[5] = {'a','b','c','d',''};
    2 printf("%s
    ",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 != '')
    21     {
    22         printf("%c ",*str);
    23         *str ++;
    24         count ++;
    25     }
    26 
    27     return count;
    28 }
  • 相关阅读:
    An Introduction to C & GUI Programming -----Simon Long 学习笔记 6
    An Introduction to C & GUI Programming -----Simon Long 学习笔记 5
    An Introduction to C & GUI Programming -----Simon Long 学习笔记 4
    An Introduction to C & GUI Programming -----Simon Long 学习笔记 3
    An Introduction to C & GUI Programming -----Simon Long 学习笔记 2
    替罪羊树 (Scapegoat Tree)
    Miller-Rabin 质数检测
    杜教筛
    狄利克雷卷积&莫比乌斯反演
    取整函数的性质
  • 原文地址:https://www.cnblogs.com/Aaaaaalei0612/p/8728649.html
Copyright © 2020-2023  润新知