const与static都是C语言中的关键字,这两个关键字是比较难以彻底理解的,所以写一篇文章专门介绍这两个关键字!
const理论
如果一个变量被const修饰,那么它的值就不能再被改变;这个功能有点像宏定义的#define,但是它存在肯定有它存在的道理,相比预处理,const有以下有点:
- 预编译指令只是对值进行简单的替换,不能进行类型检查
- 可以保护被修饰的东西,防止意外修改,增强程序的健壮性
- 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,没有了存储和读取的过程,效率变高
const修饰局部变量
int const a=100;
const int a= 100;
这两种写法都是一样的,都代表变量a”不允许被直接改变“,使得它称为编译期间的一个常量;
但是不能直接改变,可以通过”间接方式对其进行改变“,可以用指针修改(const只是标识a指向的地址不变,但不代表不可以改变这个地址上的内容),所以这其实并不是真正的const。但是C++就有升级了(自己了解)。改变const值的代码如下
#include<stdio.h>
int main()
{
const int a = 5;
int *p = &a;
*p = 100;
printf("a = %d",a);
return 0;
}
const常量指针与指针常量(重要)
常量指针
常量指针是指针指向的内容是常量,可以有一下两种定义方式
const int * n;
int const * n;
常量指针说的是不能通过这个指针改变变量的值,但是还是可以通过其他的引用来改变变量的值的(不可以改变指针指向的数值,但是可以使用间接修改)
int a=5;
const int* n=&a;
a=6;
常量指针指向的值不能改变,但是这并不是意味着指针本身不能改变,常量指针可以指向其他的地址(
不可以改变指针指向地址上的值,但是可以改变指针指向的地址)
int a=5;
int b=6;
const int* n=&a;
n=&b;
指针常量
指针常量是指指针本身是个常量,不能在指向其他的地址,写法如下:
int *const n;
指针常量指向的地址不能改变,但是地址中保存的数值是可以改变的
int a=5;
int *p=&a;
int* const n=&a;
*p=8;
总结:指针常量,指针指向的值不能用这个指针进行修改,但是可以通过间接的方式修改,并且这个指针可以改变指向其他地址;常量指针,指针指向的地址不可以改变,但是指针指向地址上的内容可以通过其他指向这个地址的指针改变
static理论
static在C语言中是关键字,中文直译过来是“静态的”
static修饰局部变量
称为静态局部变量
我们拿一段代码演示
void test()
{
static int x = 0;
x++;
printf("%d ", x);
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
其输出结果为:1 2 3 4 5 6 7 8 9 10。不加static的话就是10个1
原因是static修饰了局部变量x,令局部变量x变成静态的,使得每次test()函数结束时局部变量x都不销毁,再次进入test()函数时则保留原有数值运行,因此x++数值越来越大
普通的局部变量创建后是放在栈区中,这种局部变量进入作用域时创建,出了作用域就销毁
但static修饰后的局部变量则放在静态区中,它改变了局部变量的存储位置,从而使得变量的生命周期延长,延长至程序结束才销毁。
注意:static修饰局部变量只改变生命周期,不改变作用域
static修饰全局变量
称为静态全局变量
全局变量的生命周期更是贯穿整个程序,并且全局变量想要被另一个文件使用时就需要进行外部声明(extern)
static修饰后让全局变量x的作用域变小了,令全局变量x无法被其他文件调用(有extern也不行)
全局变量本身是具有外部链接属性的,在A文件中定义的全局变量,在B文件中可以通过【链接】来使用;但如果全局变量被static修饰,那这个外部链接属性就会被修改成内部链接属性,此时这个全局变量就只能在自己的源文件中使用;
static修饰函数
称为静态函数
static对函数的修饰与修饰全局变量十分相似,修饰函数时会改变函数的链接属性,从而使得函数的作用域变小
函数本身也是有外部链接属性的;
被static修饰后,函数的外部链接属性被修改成内部链接属性,使得这个函数只能在自己的源文件内被使用,因此函数的作用域就变小了。
评论