C语言的存储类别,链接和内存管理

本文详细介绍了C语言中的变量作用域,包括块作用域、函数作用域、文件作用域等,以及变量的链接属性,如外部链接、内部链接。同时,解释了存储期的概念,如静态存储期和自动存储期,并讨论了存储类别,包括自动变量、静态变量和寄存器变量。此外,文章还深入探讨了动态内存管理,包括malloc、free、calloc函数的使用,以及动态内存分配中常见的错误和注意事项。

目录

1.1作用域

1.2链接

1.3存储期

1.4存储类别

1.4.1自动变量

1.4.2寄存器变量

1.4.3块作用域的静态变量

1.4.4外部链接的静态变量

1.4.5内部链接的静态变量

1.4.6存储类别说明符

1.5动态内存管理

1.5.1出现原因

栈内存

数据段与代码段

堆内存

1.5.2动态内存函数介绍

5.2.1malloc

5.2.2free

5.2.3calloc

11.5.3动态内存错误

5.3.1对NULL指针的解引用操作

5.3.2对动态开辟空间的越界访问

5.3.3对非动态开辟内存使用free释放

5.3.4使用free释放一块动态开辟内存的一部分

5.3.5对同一块动态内存多次释放

5.3.6动态开辟内存忘记释放(内存泄漏)


1.1作用域

作用域描述程序中可访问标识符的区域。一个C变量的作用域可以是块作用域、函数作用域、函数原型作用域或文件作用域

块作用域:块是用一对花括号括起来的代码区域,块作用域变量的可见范围是从定义处到包含该定义的块的末尾。

以前,具有块作用域的变量都必须声明在块的开头。C99 标准放宽了这 一限制,允许在块中的任意位置声明变量。C99把块的概念扩展到包括for循环、while循环、 do while循环和if语句所控制的代码,即使这些代码没有用花括号括起来, 也算是块的一部分。

函数作用域:它只适用于语句标签,语句标签用于go语句。一个函数中的所有语句标签必须唯一。着即使一 个标签首次出现在函数的内层块中,它的作用域也延伸至整个函数。如果在两个块中使用相同的标签会很混乱,标签的函数作用域防止了这样的事情发 生。

函数原型作用域:只适用于在函数原型中声明的参数。唯一可能出现的冲突就是在同一个原型中,不止一次地使用同一个名字。函数原型作用域的范围是从形参定义处到原型声明结束。这意味着,编 译器在处理函数原型中的形参时只关心它的类型,而形参名(如果有的话) 通常无关紧要。而且,即使有形参名,也不必与函数定义中的形参名相匹 配。

文件作用域:任何在代码块之外声明的标识符都具有文件作用域。但是在同文件中编写的通过include指令包含到其他文件中的声明,就好像直接写在那些文件中一样,它们的作用域不限于头文件的文件尾。具有文件作用域的变量,从它的定义处到该定义所在文件的末尾均可见。由于这样的变量可用于多个函数,所以文件作用域变量也称为全局变量。

1.2链接

C 变量有 3 种链接属性:外部链接、内部链接或无链接。具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量。这意味着这些变量属于定义它们的块、函数或原型私有。具有文件作用域的变量可以是外部链接或内部链接。外部链接变量可以在多文件程序中使用,内部链接变量只能在一个翻译单元中使用。

怎样修改链接属性?

关键字externstatic用于在声明修改标识符的链接属性

如果某个声明在正常情况下具有外部链接属性,在它前面加上static关键字可以使它的链接属性变为内部链接。

注:static只对外部链接的声明才有改变链接属性的效果。

extern关键字为一个标识符指定为外部链接属性,这样就可以访问在其他任何位置定义的这个实体

注: 当extern关键字用于源文件中一个标识符的第一次声明,它指定该标识符具有外部链接属性。但是,如果他用于该标识符的第2次或以后的声明,它并不会更改由第1声明所指定的链接属性

1.3存储期

作用域和链接描述了标识符的可见性。存储期描述了通过这些标识符访问的对象的生存期。C对象有4种存储期:静态存储期、线程存储期、自动存储期、动态分配存储期

静态存储期如果对象具有静态存储期,那么它在程序的执行期间一直存在。

文件作用域变量具有静态存储期。注意,对于文件作用域变量,关键字 static表明了其链接属性,而非存储期。以 static声明的文件作用域变量具有内部链接。但是无论是内部链接还是外部链接,所有的文件作用域变量都具有静态存储期。

线程存储期线程存储期用于并发程序设计,程序执行可被划分多个线程。具有线程存储期的对象,从被声明时到线程结束一直存在。以关键字_Thread_local声明一个对象时,每个线程都获得该变量的私有备份。

自动存储期:块作用区域的变量通常都具有自动存储期。当程序进入定义这些变量的块时,为这些变量分配内存;当退出这个块时,释放刚才为变量分配的内存。

动态分配存储期后面介绍

1.4存储类别

C提供了多种不同的模型或存储类别在内存中储存数据。目前所有编程示例中使用的数据都储存在内存中。从硬件方面来看,被储存的每个值都占用一定的物理内存,C 语言把这样的一块内存称为 对象)。对象可以储存一个或多个值。一个对象可能并未储存实际的值,但是它在储存适当的值时一定具有相应的大小(面向对象编程中的对象指的是类对象,其定义包括数据和允许对数据进行的操作,C不是面向对象编程语言,是面向过程编程语言)。

可以用存储期描述对象,所谓存储期是指对象在内存中保留了多长时间。标识符用于访问对象,可以用作用域和链接描述标识符,标识符的作用域和链接表明了程序的哪些部分可以使用它。不同的存储类别具有不同的存储期、作用域和链接。标识符可以在源代码的多文件中共享、可用于特定文件的任意函数中、可仅限于特定函 数中使用,甚至只在函数中的某部分使用。对象可存在于程序的执行期,也可以仅存在于它所在函数的执行期。对于并发编程,对象可以在特定线程的执行期存在。可以通过函数调用的方式显式分配和释放内存。

除动态分配存储期的5种存储类别如下:

5种存储类被
存储类别 存储期 作用域 链接 声明方式
自动 自动 块内
寄存器 自动 块内,使用关键register
静态外部链接 静态 文件 外部 所有函数外
静态内部链接 静态 文件 内部 所有函数外,使用关键字static
静态无链接 静态 块内,使用该关键字static

1.4.1自动变量

默认情况下,声明在块或函数头中的任何变量都属于自动存储类别。

属于自动存储类别的变量具有自动存储期、块作用域且无链接

块作用域和无链接意味着只有在变量定义所在的块中才能通过变量名访问该变量(当然,参数用于传递变量的值和地址给另一个函数,但是这是间接的方法)。另一个函数可以使用同名的变量,但是该变量存储在不同内存位置的另一个变量。

变量具有自动存储期意味着,程序在进入该声明所在的块时变量存在,程序在退出该块时变量消失。原来该变量占用的内存位置现在可做他用。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值