如何真正理解Static与Const


这两个关键字可以一起使用,当一起使用时,它们的先后顺序是没有限制的,谁在前面都一样,const是指常量,static则表示静态变量,它们一起使用时则表示一个静态常量.

1、Static

1)、作用于变量:

   用static声明局部变量-------局部变量指在代码块{}内部定义的变量,只在代码块内部有效(作用域),其缺省的存储方式是自动变量或说是动态存储的,即指令执行到变量定义处时才给变量分配存储单元,跳出代码块时释放内存单元(生命期)。用static声明局部变量时,则改变变量的存储方式(生命期),使变量成为静态的局部变量,即编译时就为变量分配内存,直到程序退出才释放存储单元。这样,使得该局部变量有记忆功能,可以记忆上次的数据,不过由于仍是局部变量,因而只能在代码块内部使用(作用域不变)。

   用static声明外部变量-------外部变量指在所有代码块{}之外定义的变量,它缺省为静态变量,编译时分配内存,程序结束时释放内存单元。同时其作用域很广,整个文件都有效甚至别的文件也能引用它。为了限制某些外部变量的作用域,使其只在本文件中有效,而不能被其他文件引用,可以用static关键字对其作出声明。

  总结:用static声明局部变量,使其变为静态存储方式(静态数据区),作用域不变;用static声明外部变量,其本身就是静态变量,这只会改变其连接方式,使其只在本文件内部有效,而其他文件不可连接或引用该变量。

2)、作用于函数:

  使用static用于函数定义时,对函数的连接方式产生影响,使得函数只在本文件内部有效,对其他文件是不可见的。这样的函数又叫作静态函数。使用静态函数的好处是,不用担心与其他文件的同名函数产生干扰,另外也是对函数本身的一种保护机制。

  如果想要其他文件可以引用本地函数,则要在函数定义时使用关键字extern,表示该函数是外部函数,可供其他文件调用。另外在要引用别的文件中定义的外部函数的文件中,使用extern声明要用的外部函数即可。

2、const

1)、基本解释 

const是一个C语言的关键字,它限定一个变量不允许被改变。Const修饰的是只读的变量(常量),具有不可变性。它是全局的只读变量,存放在静态区。

使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在何处呢?请看下面几个问题。        

问题:const变量 & 常量      

为什么我象下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?

const int n =5;   int a[n];     

答案与分析:   

a)、这个问题讨论的是“常量”与“只读变量”的区别。常量肯定是只读的,例如5, “abc”,等,肯定是只读的,因为程序中根本没有地方存放它的值,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是“常量”,“只读变量”也是不可以的。 

b)、注意:在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const intn,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是 ANSI C对数组的规定限制了它。

 

2)、const用法

a)、函数体内修饰局部变量

例:

void func()

{

const int a=0;

}

首先,我们先把const这个单词忽略不看,那么a是一个int类型的局部自动变量,我们给它赋予初始值0。然后再看const.

const作为一个类型限定词,和int有相同的地位。

const int a;

int const a;

是等价的。于是此处我们一定要清晰的明白,const修饰的对象是谁,是a,和int没有关系。const 要求他所修饰的对象为常量,不可被改变,不可被赋值,不可作为左值(l-value)。

这样的写法也是错误的。

const int a;

a=0;

这是一个很常见的使用方式:

const doublepi=3.14;

在程序的后面如果企图对pi再次赋值或者修改就会出错。

注意:const修饰的只读变量必须在定义的同时初始化。

 

b)修饰数组

int const array[5]={1,2,3,4,5};或者const int array[5]={1,2,3,4,5};

array[0]=8;//编译错误,不允许修改

c)const修饰函数参数

(1).传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)

voidfunction(const int Var);

(2).参数指针所指内容为常量不可变

voidfunction(const char* Var); 

(3).参数指针本身为常量不可变(也无意义,因为char* Var也是形参)

voidfunction(char* const Var);

 

d)、Const修饰指针

const int* p;//p可变,p指向的对象不可变

int const* p;//p可变,p指向的对象不可变

int *const p;//p不可变,p指向的对象可变

const int*const p;//指针p和p指向的对象都不可变

记忆和理解的方法记忆和理解的方法:先忽略类型名(编译器解释的时候也是先忽略类型名),我们看const离哪个近,就修饰哪个( “近水楼台先得月”)。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值