笨蛋C++016 - 变量定义与生存周期

247 阅读5分钟

C/C++有两个非常重要的属性。作用域与生命周期。这两个属性代表从时间和空间两个角度来同时描述一个变量。

作用域

作用域就是一个变量可以被引用的范围。常见的作用域可以分为6种:

  • 全局变量:具有全局作用域。全局作用域在一个源文件中进行定义。就可以作用于所有的源文件。其中不包含变量定义的源文件需要使用extern再次声明这个全局变量。
  • 静态全局作用域:具有文件作用域。它与全局变量的区别在于程序中如果包含多个文件的话。它作用于定义它的文件里。不能作用到其他文件里面去。就是说:被static关键字修饰过的变量具有文件的作用域。这样就算两个不同的文件
  • 局部变量:具有局部作用域。它是自动对象,在程序运行期间不是一直存在。而是只在函数执行期间存在。函数的一次调用执行结束之后。变量被撤销。其中占用的内存被收回。局部变量对于函数外部的程序来说是不可见的。当然内部情况更加复杂。实际是以{}作为作用域的。
  • 静态局部变量:具有局部作用域。它只初始化一次。自从第一次初始化直到程序运行结束之后都一直存在。它和全局变量的区别在于全局变量对于所有的函数而言都是可见的。而静态局部变量只对定义自己的函数体始终可见。只有定义该变量的函数内部可以使用和修改该变量。

变量的生命周期

  • 全局变量:全局变量在整个程序运行过程中会一直存在。都随时可以访问。当程序结束的时候。对应的变量会自动销毁。内存会被系统回收。
  • 局部变量:局部变量的生命周期仅限于函数被调用期间。当函数调用结束的时候。该变量会自动销毁
  • 静态局部变量:实际上静态局部变量的作用域仅限于函数内部。它的作用域与局部变量相同。但是实际上该变量在程序运行期间都是一直存在的。生命周期贯穿于程序运行始终。局部静态变量只能初始化一次。

变量的存储区域

  • 静态变量一般存储于数据段。包括data段、bss段、rodata段、其中data段存放已经初始化的静态变量和全局变量。bss存储未初始化的静态变量与全局变量。这里的静态变量包括全局变量。局部变量、静态局部变量。
  • 局部变量一般存储在堆区或者栈区

面试题

请您简单概括下C++中存在哪些作用域,这些作用域分别有什么区别

答:C++中存在全局作用域、类作用域、语句作用域、文件作用域、局部作用域、命名空间作用域这6种作用域。

  • 全局作用域:只需要在一个文件中进行声明,就可以作用到所有的文件当中去。其他文件使用这个变量就需要通过extern关键字进行声明了。
  • 文件作用域:又称为静态全局作用域。它只能作用于定义他的那个文件里面。不能作用到其他文件里面去。也就是说,被static关键字修饰的全局变量,只能在修饰他的那个文件里面使用,就算在其他文件中定义了这个变量。那么他们使用的也是两块不同的内存空间
  • 局部变量:具有局部作用域,它是自动对象auto。程序运行期间不是一直都是存在的,他只在函数执行的时候存在,函数执行一次之后就会被自动撤销。所占用的内存也被收回。局部变量对于外部程序来说是不可见的。实际上是以{}来作为作用域的
  • 静态局部变量:它只被初始化一次。这一次对于程序来说直到程序结束之后它都一直存在。它和全局变量的区别在于全局变量对所有函数都是可见的。但是静态局部变量只对定义自己的函数可见。

请您简单描述下C++不同的变量定义之后在内存中的存放位置吧

答:不同生命周期的变量,在内存中的存放位置是不同的。程序的内存分别分为代码区.text,全局数据区.data,.bss,.rodata、堆区heap,栈区stack.不同的内存区域,对应不同的生命周期。

  • 静态变量一般存储在数据段,包括data段、bss段、rodata段。其中data段存储已经初始化的静态变量和全局变量。bss段存储未初始化的静态变量与全局变量。这里的静态变量包括全局变量、局部变量、静态局部变量。

  • 局部变量一般存储在栈区或者堆区。