C语言中符号的存储类、链接属性和生命周期

C语言中符号的存储类
代码段:程序执行的代码,其实就是函数,它的生命周期是永久的(永久的意思就是在程序被执行时诞生,在程序终止时消亡),不过一般代码的生命周期我们并不关注。有时候放在代码段的不只是代码,还有const类型的常量,还有字符串常量(const类型的常量、字符串常量有时候放在只读数据段,有时候放在代码段,取决于平台)。linux中代码段又叫文本段(.text)。
数据段:显式初始化为非0的全局变量和static局部变量存在数据段
bss段:显式初始化为0或者未显式初始化的全局变量和static局部变量存在bss段(static局部变量可以在数据段/bss段上)。
:C语言不会自动向堆中存放东西,堆内存空间是客观存在的,是由操作系统维护的。堆内存在使用的时候malloc/alloc/realloc申请然后使用然后free释放。堆内存在malloc之前和free之后不能再去访问。
这里要注意:用malloc函数向系统堆管理器申请内存时返回值是一个指针,这个指针指向申请的那段内存。由于malloc刚申请的这段内存时尚未用来存储数据并且也无法预知这段内存将来被存放什么类型的数据,所以就返回一个void *类型,在malloc之后可以给这段内存读写任意类型的数据。(void类型平时使用时一般都是用void *指针,而不是仅仅使用void。void类型的最终归宿,就是被强制类型转换成一个具体类型)
:普通局部变量分配在栈上,这也是函数不能返回普通局部变量的地址(指针)作为返回值得原因,另外函数调用传参过程也会用到栈。
只读数据段:const修饰的常量有可能是存在只读数据段的,但是不一定,因为const常量的实现方法在不同平台是不一样的。

C语言中的符号有三种链接属性
外连接的意思就是外部链接属性,也就是说可以在整个程序范围内(可以跨文件)进行链接,譬如普通的函数和无static修饰的全局变量属于外连接。
内链接的意思就是(c文件内部)内部链接属性,也就是说这家伙可以在当前c文件内部范围内进行链接(言下之意就是不能在当前c文件外面的其他c文件中进行访问、链接)。static修饰的函数/全局变量属于内链接。
无连接的意思就是这个符号本身不参与链接,它跟链接没关系。所有的局部变量(auto的、static的)都是无连接的。
由链接属性引起的函数/变量同名问题
(1)因为普通的函数和无static修饰的全局变量具有外部链接属性,就是说每一个函数和全局变量将来在整个程序中所有的c文件都能被访问,因此在一个项目中的所有c文件中不能出现同名的函数/同名的全局变量。
(2)可以将明显不会在其他c文件中引用(只在当前c文件中引用)的函数/全局变量,使用static修饰使其成为内链接属性,这样在将来连接时即使2个c文件中有重名的函数/全局变量,只要其中一个或2个为内链接属性就没事。
(3)另外写程序尽量避免使用全局变量,尤其是非static类型的全局变量。能确定不会被其他文件引用的全局变量一定要static修饰。
(4)这种解决方案在一定程度上解决了问题。但是,留下了很多麻烦,这就导致了用C语言作大型项目的开发语言难度很大。写到这里笔者也不得不感慨Linux内核的伟大,再次向那些大神致敬!

综上得出的一些小结论
存储类决定生命周期,作用域决定链接属性;
静态局部变量在存储类和生命周期方面和全局变量一样,区别是:静态局部变量作用域是代码块作用域(和普通局部变量是一样的)、链接属性是无连接;全局变量作用域是文件作用域(和函数是一样的)、链接属性方面是外连接。

另外在C语言中extern主要用来声明全局变量,声明的目的主要是在当前.c文件中定义全局变量而在另一个.c文件中使用该变量。

猜你喜欢

转载自blog.csdn.net/weixin_42325069/article/details/84134923