时间:2020-12-13 10:51:51 | 栏目:C代码 | 点击:次
Pascal之父Nicklaus Wirth曾经提出一个公式,展示出了程序的本质:程序=算法+数据结构。后人又给出一个公式与之遥相呼应:软件=程序+文档。这两个公式可以简洁明了的为我们展示程序和软件的组成。
程序的运行过程可以理解为算法对数据的加工过程,程序的运行的结果,就是算法加工数据产生的结果数据。算法描述的是对数据加工的步骤,对应于程序中的函数。数据结构描述的是数据在计算机中的组织结构,对应于程序中的数据类型。程序中数据对应的就是无处不在变量。对于我们编程人员,面对的无非就是函数,数据类型和变量。因此,C++谈及作用域与生命周期针对的就是这三大程序的组成要素:函数、数据类型和变量。下面将一一讲述。
1.作用域与生命周期的区别
作用域与生命周期是两个完全不同的概念。在英文中,作用域用“scope”表示,生命周期则用“duration”表示。作用域是一个静态概念,只在编译源程序的时候用到。一个标识符的作用域指在源文件中该标识符能够独立地合法出现的区域。生命周期则是一个运行时(Runtime)概念,它是指一个变量在整个程序从载入到结束运行的过程中存在的时间周期。由于函数和数据类型是静态的概念,它们没有生命周期的说法,它们从编译、程序的运行到结束整个过程是一直存在的。
C++中作用域的级别由高到低,主要有文件域(全局作用域)、名字空间域、类域、函数作用域和代码块作用域,其中函数作用域和代码块作用域又统称为局部域。
2.函数的作用域
函数分为类的成员函数和全局函数。
类的成员函数:
举例如下:
//main.cpp class test { private: int i; public: void show() { cout<<"i:"<<i<<endl; } }; int main(int argc,char* argv[]) { test t; t.show() }
全局函数:
举例如下:
//function.cpp void printHello() { cout<<"hello world"<<endl; } //main.cpp void printHello(); int main(int argc,char* argv[]) { printHello(); }
3.数据类型的作用域
C++中的数据类型分为基本数据类型和非基本数据类型,非基本数据类型中又分为复合数据类型和构造数据类型。关于C++中的数据类型,详见本人另一篇blog: C++数据类型。
基本数据类型:
基本数据类型包括整型(int)、实型(float和double)、字符型(char)、布尔型(bool)和无值型(void)。
复合数据类型:
复合数据类型包括:数组(type[])、指针(type*)、引用(type&)、枚举(enum)。
如果复合数据类型是构造数据类型参与的复合,其作用域与构造数据类型一致。enum枚举类型的作用域与构造类型相同。
构造数据类型:
举例如下:
//main.cpp namespace dd { class test { private: int i; public: void show() { cout<<"i:"<<i<<endl; } }; } using namespace dd;//引用命名空间域中的构造类型test,否则无法使用 int main(int argc,char* argv[]) { test t; t.show(); }
4.变量的作用域与生命周期
我们面对的变量主要分为全局变量、全局静态变量、局部变量和局部静态变量。下面一一讲述他们的作用域与生命周期。
全局变量:
举例如下:
//define.cpp int g_iValue = 1; //main.cpp extern int g_iValue; int main() { cout << g_iValue; return 0; }
全局静态变量:
举例如下:
//define.cpp const int iValue=8; //main.cpp int iValue; static const int iValue_2; static int iValue_3; int main(int argc,char* argv[]) { cout<<"iValue:"<<iValue<<endl; return 0; }
局部变量:
举例如下:
void print() { int a=0; cout<<a<<endl; }
局部静态变量:
举例如下:
void function() { static int iREFCounter = 0; }
5.扩展知识点
5.1变量存储类型说明符
C语言中提供了四种存储类型说明符auto,register,extern和static,四种存储类型有两种存储期:自动存储期和静态存储期。其中auto和register对应自动存储期,被修饰的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。静态存储期的变量从程序载入运行到程序结束一直存在。
5.2static使用建议
(1)若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
(2)若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
(3)设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,可被其他函数共享;
(4)如果我们需要一个可重入的函数,那么我们一定要避免函数中使用static变量。这样的函数被称为带“内部存储器”功能的函数;
(5)函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为野指针。