理解变量标识符的作用域和可见性,以及变量生存期。
(1)标识符的作用域和可见性
作用域:作用域是一个标识符在源程序中有效的区域。
可见性:程序运行到某一点,能够引用到的标识符,就是该处可见的标识符。
(2)变量生存期:
变量的生存期就是指变量从创建到销毁的时间范围。变量按照生存期分“静态生存期”和“动态生存期”。静态生存期:如果变量的生存期与程序的运行期相同,则称该变量具有“静态生存期”; 动态生存期:变量生存期始于创建声明点,结束于作用域结束处。
注意:源程序声明(定义)变量原则:满足需要的情况下,缩短标识符作用域,缩短变量生存期。
/*
*变量练习
*
*理解标识符的作用域和可见性,以及变量生存期。
*
*作用域:作用域是一个标识符在源程序中有效的区域。
*可见性:程序运行到某一点,能够引用到的标识符,就是该处可见的标识符。
*
*
*变量生存期:变量的生存期就是指变量从创建到销毁的时间范围。
*
*变量按照生存期分“静态生存期”和“动态生存期”。
*静态生存期:如果变量的生存期与程序的运行期相同,则称该变量具有“静态生存期”;
*动态生存期:变量生存期始于创建声明点,结束于作用域结束处。
*/
int value;//对于全局变量,编译器会在编译期自动初始化为零
void func()
{
int value2 = 2;//局部变量
printf("%d\n", value2);
}
int main()
{
value4 = 0;//局部变量。
{
int value3 = 3;//局部变量。
//该条变量定义语句定义的变量作用域为:自其定义语句起到当前大括号结束为止。
//我们称这类局部变量具有“块作用域”,也称为“块变量”
printf("%d\n", value3);
printf("%d\n", value4);
}
//func();
//printf("%d\n", value2);//编译器error:value2没有被定义
//printf("%d\n", value3);//编译器error: value3没有被定义。
return 0
}
可执行程序需要运行时,操作系统须要完成内存资源分配,将可执行程序按照预先划好的段落调入计算机内存,然后将控制权交给可执行程序。
任何应用程序,或许在文件系统中是完整的一个文件,但当程序执行的时候都是被处理为好多个段落。段落划分是事先由编译器完成的。主要包括“代码段”、“栈”和“堆”三大段。
“代码段”。代码段包含有所有的程序指令,在运行时代码段中的内容不可以被修改。
“堆”。堆实现了由应用程序来管理变量的创建和销毁,例如应用程序的malloc调用带来的变量创建与销毁就是在堆中完成的。
“栈”。栈是一个用来管理某些变量的段落,例如所有的局部变量都将在这个段被创建和销毁。
举例:假设源程序如下
int main()
{
int integer;
fun(integer);
return 0;
}
fun(int a)
{
int i;
fun1();
}
fun1()
{
char c;
return 0;
}
那么,程序需要执行时,计算机分配好内存资源后,进一步将可执行程序按照预先划好的段落(代码段、堆、栈)调入计算机内存,然后将控制权交给可执行程序,进入main函数,进入main后“栈”在程序运行期会完成以下工作:
(1)在栈中开出integer存储空间
(2)调用fun(),进入fun后在栈中开出i存储空间
(3)调用fun1(),进入fun1后在栈中开出c存储空间
(4)遇到return语句,销毁c,返回返回值0,退出fun1。
(5)回到fun的fun1调用地址继续执行,遇到函数体右大括号,销毁i,退出fun。
(6)回到main的fun调用地址继续执行。
变量类型修饰符(type-specifier)
auto关键字可以用来声明变量,所有的局部变量自动就是auto的,所以源程序中根本不需要特别声明。
static关键字可以用来声明静态变量。静态全局变量的作用域被缩小成声明它的那个文件里面的所有语句。静态局部变量在程序一开始运行就被创建直到程序结束才被销毁,它的生存期被拉长为整个程序运行期。
/*static类型修饰符修饰局部变量时可以实现改变变量的生存期,但无法改标识符在源程序中的作用域和可见性。
*static类型修饰符修饰全局变量时可以实现改变变量的作用域。*/
register关键字可以用来声明寄存器变量。
volatile关键字可以声明易变变量。
const关键字可以用来声明不可变变量。
C语言中的地址数据和指针
指针变量是用来存放地址数据的变量。
指针变量声明语法如下:
int *p_value;//声明语句中标识符前的星号表示p_value是指针类型。
int *p_value1, value1, *p_value2, temp, integer;//本声明语句中的标识符有星号的表示是指针类型,没有星号的是int类型。也就是说p_value1, p_value2的类型是int*, value1, temp, integer的类型是int
两个最基本的地址运算操作符&和*。其中*是间接访问操作符,&是取址操作符。他们的运算优先级极高。