c语⾔中的static和const
C语⾔中static 和 const使⽤
static
static在C语⾔中主要是两种⽤法
1、修饰局部变量
2、修饰函数和全局变量
局部变量按照存储形式来分,分为auto,static,register
⾸先从内存四区的⾓度去看,auto即为普通的局部变量,存储在栈上,当函数结束时,随之释放。
register为寄存器变量,存放在寄存器⾥⾯,调⽤速度快。
在C语⾔中register变量不能取地址,会报错。
⽽在c++中,对register做了增强,党C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得⽆效。
static修饰局部变量时该变量是存放在静态存储区,⽣命周期是整个程序结束。
static局部变量初次定义时就要初始化,且只能初始化⼀次。如果在定义的时候不初始化,编译器就会⾃动赋值为0;(也就是说如果重复调⽤同⼀个函数,在第⼆次调⽤时,就不会再执⾏static局部变量初始化那句话 了)
特点: static局部变量的”记忆性”与⽣存期的”全局性”
所谓”记忆性”是指在两次函数调⽤时, 在第⼆次调⽤进⼊时, 能保持第⼀次调⽤退出时的值.
void staticLocalVar()
{
static int a = 0; // 运⾏期时初始化⼀次, 下次再调⽤时, 不进⾏初始化⼯作
printf(“%d”,a);
a++;
}
int main()
{
staticLocalVar(); // 第⼀次调⽤, 输出a=0
staticLocalVar(); // 第⼆次调⽤, 记忆了第⼀次退出时的值, 输出a=1
return 0;
}
注意事项:
1. “记忆性”, 程序运⾏很重要的⼀点就是可重复性, ⽽static变量的”记忆性”破坏了这种可重复性, 造成不同时刻⾄运⾏的结果可能不同.
2. “⽣存期”全局性和唯⼀性. 普通的local变量的存储空间分配在stack上, 因此每次调⽤函数时, 分配的空间都可能不⼀样, ⽽static具有全局唯⼀性的特点, 每次调⽤时, 都指向同⼀块内存, 这就造成⼀个很重要的问题 —- 不可重⼊性
⼆、
当static修饰全局变量或者函数时,不是为了限制其存储⽅式,⽽主要是为了限制该全局变量或者函数的作⽤域仅限于本⽂件,所以⼜称为内部函数。此件时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, ⽣存期都是全局的. 此时的static只是起作⽤域限制作⽤, 限定作⽤域在本模块(⽂)内部.
使⽤内部函数的好处是:不同的⼈编写不同的函数时,不⽤担⼼⾃⼰定义的函数,是否会与其它⽂件中的函数同名。
装载⾃:
const
关键字const⽤来定义常量,如果⼀个变量被const修饰,那么它的值就不能再被改变,我想⼀定有⼈有这样的疑问,C语⾔中不是有
#define吗,⼲嘛还要⽤const呢,我想事物的存在⼀定有它⾃⼰的道理,所以说const的存在⼀定有它的合理性,与预编译指令相
⽐,const修饰符有以下的优点:
1、预编译指令只是对值进⾏简单的替换,不能进⾏类型检查
2、可以保护被修饰的东西,防⽌意外修改,增强程序的健壮性
3、编译器通常不为普通const常量分配存储空间,⽽是将它们保存在符号表中,这使得它成为⼀个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很⾼。
下⾯我们从⼏个⽅⾯来说⼀下const的⽤法:
⼀、修饰局部变量
const int n=5;
int const n=5;
1
2
3
这两种写法是⼀样的,都是表⽰变量n的值不能被改变了,需要注意的是,⽤const修饰变量时,⼀定要给变脸初始化,否则之后就不能再进⾏赋值了。
接下来看看const⽤于修饰常量静态字符串,例如:
const char* str=”fdsafdsa”;
1
2
如果没有const的修饰,我们可能会在后⾯有意⽆意的写str[4]=’x’这样的语句,这样会导致对只读内存区域的赋值,然后程序会⽴刻异常终⽌。有了const,这个错误就能在程序被编译的时候就⽴即检查出来,这就是const的好处。让逻辑错误在编译期被发现。
⼆、常量指针与指针常量
常量指针是指针指向的内容是常量,可以有⼀下两种定义⽅式。
const int * n;
int const * n;
1
2
3
需要注意的是⼀下两点:
1、常量指针说的是不能通过这个指针改变变量的值,但是还是可以通过其他的引⽤来改变变量的值的。
int a=5;
const int* n=&a;
a=6;
1
2
3
4
2、常量指针指向的值不能改变,但是这并不是意味着指针本⾝不能改变,常量指针可以指向其他的地址。
int a=5;
int b=6;
const int* n=&a;
n=&b;
1
2
3
4
5
指针常量是指指针本⾝是个常量,不能在指向其他的地址,写法如下:
int *const n;
1
2
需要注意的是,指针常量指向的地址不能改变,但是地址中保存的数值是可以改变的,可以通过其他指向改地址的指针来修改。
int a=5;
int *p=&a;
int* const n=&a;
*p=8;
1
2
3
4
5
区分常量指针和指针常量的关键就在于星号的位置,我们以星号为分界线,如果const在星号的左边,则为常量指针,如果const在星号的右边则为指针常量。如果我们将星号读作‘指针’,将const读作‘常量’的话,内容正好符合。int const * n;是常量指针,int *const n;是指针常量。
指向常量的常指针
是以上两种的结合,指针指向的位置不能改变并且也不能通过这个指针改变变量的值,但是依然可以通过其他的普通指针改变变量的值。
const int* const p;
1
2
三、修饰函数的参数
根据常量指针与指针常量,const修饰函数的参数也是分为三种情况
1、防⽌修改指针指向的内容
void StringCopy(char *strDestination, const char *strSource);
1
2
其中 strSource 是输⼊参数,strDestination 是输出参数。给 strSource 加上 const 修饰后,如果函数体内的语句试图改动 strSource 的内容,编译器将指出错误。
2、防⽌修改指针指向的地址
const的作用
void swap ( int * const p1 , int * const p2 )
1
2
指针p1和指针p2指向的地址都不能修改。
3、以上两种的结合。
四、修饰函数的返回值
如果给以“指针传递”⽅式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
例如函数
const char * GetString(void);
1
2
如下语句将出现编译错误:
char *str = GetString();
1
2
正确的⽤法是
const char *str = GetString();
1
2
五、修饰全局变量
全局变量的作⽤域是整个⽂件,我们应该尽量避免使⽤全局变量,因为⼀旦有⼀个函数改变了全局变量的值,它也会影响到其他引⽤这个变量的函数,导致除了bug后很难发现,如果⼀定要⽤全局变量,我们应该尽量的使⽤const修饰符进⾏修饰,这样防⽌不必要的⼈为修改,使⽤的⽅法与局部变量是相同的。
转载⾃:
总结⼀下
就是static⽤于全局变量和函数⽤于限制作⽤域,只允许在本⽂件中使⽤。在C语⾔中,⼀般进⾏声明之后全局变量及函数可以整个程序使⽤,但是如果有static修饰则只能在同⼀个c⽂件使⽤;
⽤于局部变量是⽤于存储的不⼀样,存储将会没有可重复性,第⼆次调⽤函数将会使⽤上⼀次停留的结果。
const就不多做说,⾃⼰看吧,这个博客写的很好。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。