龙空技术网

C|理解变量或类型定义作用域中的一些细节

小智雅汇 198

前言:

现时朋友们对“变量标识符声明的规定”大概比较关心,小伙伴们都需要了解一些“变量标识符声明的规定”的相关文章。那么小编在网摘上搜集了一些有关“变量标识符声明的规定””的相关资讯,希望朋友们能喜欢,大家一起来学习一下吧!

变量或类型定义的作用域是指其在空间上的可见性或有效性。局部作用域在于内存的自动分配和回收、空间的有效利用,不用考虑标识符名称是否与作用域以外的标识符是否重名,一定程度上也是函数封装代码和内部数据及独立性的需要。全局变量可以在函数间共享数据,但方便带来的代价就是耦合性和数据的安全风险也提高了。

1 不同关键字以及变量标识符在不同位置的声明和定义产生了作用域的概念,变量标识符保存到了内存中不同的区域(如BSS段、数据段等全局或静态区、栈段、堆段);

2 作用域除了用关键字区分以外,最重要的是在上下文中通过其在代码中的位置进行区分。局部作用域是函数体内用“{}”括起来的语句块,局部作用域的局部变量在其声明和定义处开始有效,“}”是一个局部变量作用域结束的标志。函数体还可以嵌套“{}”语句块,“{}”语句块可以是控制结构的,也可以是直接“{}”形成的语句块,“{}”语句块嵌套时按最近原则进行匹配。自然,全局变量不隶属于任何“{}”,其作用域也是开始于其声明和定义处。

3 函数声明中的参数的标识符对于C编译器来说是可以是省略的,C编译器只关心其类型信息,所以也就无作用域的问题。函数定义中的参数的作用域为其整个函数体。需要注意的是,在函数调用时,如果函数参数列表中含有同一变量的表达式,如fn(a++, a++, a++); 其结果的结合是从右至左的,因为参数压栈后的出栈是一个后进先出的顺序,注意逗号运算符的结合性是从左至右。

4 关键字extern用于声明在此处之后或其他文件中定义的全局变量,自然无法通过extern在同一文件中去声明其定义的局部变量,因为局部变量一超出其作用域便失效了。

5 在局部作用域内,同名局部变量会屏蔽掉同名的全局变量,在C++中,可以使用域操作符“::”来引用同名全局变量;

6 对于函数作用域,有一个返回值的问题。要搞清楚返回的究竟是“值”、“指针”还是“引用”,return 语句返回指向“栈内存”的“指针”或者“引用”是有问题的:

#if(0)#include <iostream>using namespace std;char * Func(void){	char str[] = "abcde";	char *str1 = "fghij"; // str 的内存位于BSS内存段上,可以返回	return str;}void main(){	char* str;	str=Func();	cout<<str[0]<<str[1]<<str[2]<<endl;//abc,应该是在没有覆盖之前还可以访问	cout<<str<<endl; // 乱码值 system("pause");}#endif#if(1)#include <iostream>using namespace std;int* Func(void){	int i = 235;	int *ip = &i; //可以返回int*类型	return ip;}void main(){	int* ip;	ip=Func();	cout<<*ip<<endl; //235 system("pause");}#endif

返回局部变量或表达式,返回的是其值,编译器对于返回的值会做为一个临时结果保存起来。返回堆指针或参数指针都是可以的,堆指针指向的内存不会自动回收,而参数指针也是值返回,指向的是函数体作用域以外的内存空间。

7 作用域通常是说变量、常量的作用域,但其实也包括自定义类型的作用域。自定义类型也可以定义在局部作用域中,但通常的做法是定义在文件的最前面或单文件的main函数前面(或就近原则)。当然,也可以将类型定义(也包括函数声明)放到一个单独的文件中,其它文件需要时可以包括进去,其实质的效果也是相当于放到了文件的最前面。

-End-

标签: #变量标识符声明的规定