static const的作用
来源:互联网 发布:php免杀一句话木马 编辑:程序博客网 时间:2024/05/01 14:49
static的作用
在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。
(1)先来介绍它的第一条也是最重要的一条:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。
下面是a.c的内容
void msg()
{
printf("Hello\n");
}
下面是main.c的内容
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
程序的运行结果是:
A Hello
你可能会问:为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。此例中,a是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。
如果加了static,就会对其它源文件隐藏。例如在a和msg的定义前加上static,main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。
(2)static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。虽然这种用法不常见,但我还是举一个例子。#include <stdio.h>int fun(void){ static int count = 10; // 只执行过一次 return count--;}int count = 1;int main(void){ printf("global\t\tlocal static\n"); for(; count <= 10; ++count) printf("%d\t\t%d\n", count, fun()); return 0;}
程序的运行结果是:
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
(3)static的第三个作用是默认初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置0,然后把不是0的几个元素赋值。如果定义成静态的,就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加’\0’太麻烦。如果把字符串定义成静态的,就省去了这个麻烦,因为那里本来就是’\0’。不妨做个小实验验证一下。
int a;
int main(void)
{
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
integer: 0; string: (begin)(end)
最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0。
const作用
对于C/C++语言来讲,const就是只读的意思,只在声明中使用;
static一般有2个作用,规定作用域和存储方式.
对于局部变量,static规定其为静态存储方式,每次调用的初始值为上一次调用的值,调用结束后存储空间不释放;
对于全局变量,如果以文件划分作用域的话,此变量只在当前文件可见;对于static函数也是在当前模块内函数可见.static const 应该就是上面两者的合集.
下面分别说明:
全局:const,只读的全局变量,其值不可修改.static,规定此全局变量只在当前模块(文件)中可见.static const,既是只读的,又是只在当前模块中可见的.
文件:文件指针可当作一个变量来看,与上面所说类似.
函数:const,返回只读变量的函数.static,规定此函数只在当前模块可见
.类:const,一般不修饰类,(在VC6.0中试了一下,修饰类没啥作用)static,C++中似乎没有静态类这个说法,一般还是拿类当特殊的变量来看.C#中有静态类的详细说明,且用法与普通类大不相同.
int main(){ int i=10; int j=1; const int *p1;//(1) int const *p2=&i; //(2) p2=&j;//(3) int *const p3=&i;//(4) *p3=20;//(5) *p2=30;//(6) p3=&j;//(7)ret
const类型定义:指明变量或对象的值是不能被更新,引入目的是为了取代预编译指令
**************常量必须被初始化*************************
const的作用
(1)可以定义const常量 例如:
const int Max=100;
int Array[Max];
(2)便于进行类型检查 例如:
void f(const int i) { .........}
编译器就会知道i是一个常量,不允许修改;
(3)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。
还是上面的例子,如果在函数体内修改了i,编译器就会报错;
例如:
void f(const int i) { i=10;//error! }
(5) 为函数重载提供了一个参考。
class A
{
......
void f(int i) {......} file://一个函数
void f(int i) const {......} file://上一个函数的重载
......
};
(6) 可以节省空间,避免不必要的内存分配。和宏调用的对比
例如:
#define PI 3.14159 file://常量宏
const doulbe Pi=3.14159; file://此时并未将Pi放入ROM中
......
double i=Pi; file://此时为Pi分配内存,以后不再分配!
double I=PI; file://编译期间进行宏替换,分配内存
double j=Pi; file://没有内存分配
double J=PI; file://再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
(7) 提高了效率。
编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
使用const
(1)修饰一般常量,常数组,常对象
修饰符const可以用在类型说明符前,也可以用在类型说明符后。 例如:
int const x=2; 或 const int x=2;
int const a[5]={1, 2, 3, 4, 5}; 或 const int a[5]={1, 2, 3, 4, 5};
class A; const A a; 或 A const a;
(2)修饰指针
const int *A; 或 int const *A; //const修饰指向的对象,A可变,A指向的对象不可变
int *const A; //const修饰指针A, A不可变,A指向的对象可变
const int *const A; //指针A和A指向的对象都不可变
(3)修饰引用
const double & v; 该引用所引用的对象不能被更新
(4)修饰函数的返回值:
const修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下:
const int Fun1();
const MyClass Fun2();
(5)修饰类的成员函数:
const修饰符也可以修饰类的成员函数,格式如下:
class ClassName
{
public:
int Fun() const;
.....
};
这样,在调用函数Fun时就不能修改类里面的数据
(6)在另一连接文件中引用const常量
extern const int i; //正确的引用
extern const int j=10; //错误!常量不可以被再次赋值
*******************放在类内部的常量有什么限制?
class A
{
private:
const int c3 = 7; // err
static int c4 = 7; // err
static const float c5 = 7; // err
......
};
初始化类内部的常量
1 初始化列表:
class A
{
public:
A(int i=0):test(i) {}
private:
const int i;
};
2 外部初始化,例如:
class A
{
public:
A() {}
private:
static const int i;
};
const int A::i=3;
- Static,Const的作用
- static const的作用
- static和const的作用
- static和const的作用
- const static volatile的作用
- 关键字static/const的作用
- const和static的作用
- 关键字Static/Const的作用
- 关键字static/const的作用
- static和const的作用
- 关键字static/const的作用
- 关键字static/const的作用
- 关键字static/const的作用
- const 和 static 的作用
- 关键字static/const的作用
- 关键字static/const的作用
- 关键字static/const的作用
- 关键字static/const的作用
- android 屏幕适配方案第二版
- COM 对象与其基础 RCW 分开后就不能再使用
- div跟着滚动条移动而移动
- 【诸葛】大数据的未来:数据是商品,你就是猎物
- 第2讲(服务端的配置与启动)
- static const的作用
- 客户端网络库实现真的很简单吗?
- 异步模块定义AMD
- java 同时处理android和ios后台时
- EF6 创建数据库的方法
- 因为 setAdapter 返回的 null
- java 截屏
- c#多文件上传简单实现
- Apache2.4的简介和安装