C语言-存储类,链接,内存管理

作用域:
代码块作用域(局部变量):从该变量被定义的地方到该代码块花括号末尾
函数作用域:从变量声明处一直到函数原型的末尾
文件作用域(全局变量):在函数之外定义的变量,该变量的作用范围是从定义处到该定义文件的末尾。
链接
一个C变量具有下列链接之一:外部链接(external linkage)
内部链接(internal linkage) ,空链接(no linkage)
具有代码块作用域和函数作用域的变量有空连接,意味着变量只能在他们的作用域只能使用,具有文件作用域(全局变量)的变量具有内部和外部链接,具有内部链接(static)可以在该变量定义的文件中使用,具有外包部链接,可以在该工程的其他文件中使用

存储时期
静态存储时期:在程序执行期间一直都存在,所有内部链接,外部链接都具有静态存储时期。
动态存储时期:只在函数调用期间给变量分配内存,局部变量,函数作用域变量都是动态存储时期

自动变量:
如果在内层代码定义了一个具有外层代码块变量同一名字的变量,将会发生什么?在内层代码块定义的名字是内层代码块所使用的变量,我们称之为内层定义覆盖了外部定义,当运行离开了内层代码块时,外部变量重新恢复作用。

int main()
{
    int x = 30;
    printf("x=%d\n",x); //30
    {
        int x = 40;     //重新定义了一个X覆盖了第一个X
        printf("x=%d\n",x); //40
    }
    while(x++<33)   //这里的X是第一个x=30的x自加 
    {
        int x = 100;  //每次经历循环int x =100重新覆盖
        x++;
        printf("x=%d\n",x); //输出三个x=101;
    }
    printf("x=%d\n",x);  //输出第一个定义的X自加后的数据34
    return 0;
}

自动变量的初始化:
除非显示的初始化自动变量,否则不会被初始化

int main(void)
{
    int a;  //a的初值是先前占用分配给它空间的任意值,这个值不是0
    int b=5; //b初始化为5
}

寄存器变量
用register来声明局部变量时,该变量称为寄存器变量,寄存器变量存放在CPU的寄存器中,使用时不需要访问内存,直接读写,提高效率

register int a; //声明一个寄存器变量
void macho(register int a) //形参为寄存器变量

使用register声明的变量是有限的,可能cpu没有足够大的寄存器来容纳double类型

静态变量(static variable)作用域

int main()
{
    int c = 5;
    while (c--)
    {
    int x = 30;
    static int a = 1;
    a++;
    x++;
    printf("a = %d,x = %d \n",a,x);
    }
    return 0;
}
输出结果
a = 2,x = 31
a = 3,x = 31
a = 4,x = 31
a = 5,x = 31
a = 6,x = 31

这里的int x 每次重新执行程序都被重新初始化
静态变量 static int a 每次执行的值都被计算机记录到CPU中,下一次执行不重新初始化,调用上一次的执行之后的值

具有内部链接的静态变量:
通过使用static来进行外部变量的定义,来创建一个具有内部链接的静态变量

int a = 1;
static int b = 2;
    
int main()
{
   extern int a;
   extern int b;
}

这里定义了两个变量 a是全局变量,在其他文件中可以调用,b是静态全局变量,只可以在该定义的文件中调用,在其他文件中不可以调用,main中再次声明了两个全局变量,但是并不会改变该变量的作用域。

存储类与函数

int fun();  //外部函数,其他文件可以调用
static int sum(); //静态内部函数,其他文件不可以调用

分配内存
系统自动内存分配:
int a[100] ; //定义了一个int类型的数组,系统分配的内存大小为100*4字节

自定义分配内存
#include <stdlib.h> //为malloc和free提供原型
mallco()接收一个参数,所需的内存字节数。malloc在内存中找到一块大小合适的块,内存匿名,malloc分配了内存,但是没有指定名字,但是可以返回内存块的第一个字节的地址,把该地址赋值给一个指针变量,可以通过指针变量来访问该内存块。如果mallco找不到大小合适的内存空间,将会返回一个空指针。

double * ptd;
ptd = (double *) malloc(30 * sizeof(double));

该段代码分配了一个30个double类型的字节空间,并将ptd指向该空间所在的位置,ptd指向的是内存块的第一个元素,ptd[0]可以访问第一个元素,ptd[1]可以用来访问第二个元素。

创建一个动态内存空间的数组:

double item[n];
double *ptd;
ptd = (double *) malloc(n * sizeof(double));

内存释放函数 free();
对应的每次malloc函数的调用都需要释放内存,我们的内存空间是有限的,如果不释放内存,每次都开辟内存,可能造成内存溢出,内存泄漏。
函数free()的参数是先前malloc返回的地址,它释放先前分配的内存。malloc和free共同管理着一个内存池,每次调用malloc来分配内存,调用free来释放内存,使内存可以再次被利用,free的参数指向malloc分配的内存块 free(ptd);

函数calloc()

long * newmem;
newmem = (long *) calloc(100,sizeof(long));

calloc和malloc一样都可以用来分配内存空间,该函数有两个参数,一个是所需内存单元的数量,一个是每个单元以字节计的大小,之所以第二个参数不用数字代替是为了移植方便,其他系统中相同类型的数据字节大小可能不同,该代码建立了100个4字节单元,总共400个字节来存储。
free也可以与calloc函数配套使用释放内存空间。

动态内存分配与变长数组

int test()
{
int n;
int *p;
scanf("%d",&n);
p = (int *)malloc(n * sizeof(int));
int n[n];
}

该代码定义了变长数组n[n],和动态分配内存指针p,变长数组的内存时自动分配的,test函数结束时候,不用使用free,变长数组占用的内存自动释放,而malloc分配的动态内存需要调用free函数释放

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值