细说C语言【const和static的意义及用法】

c

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修饰后,函数的外部链接属性被修改成内部链接属性,使得这个函数只能在自己的源文件内被使用,因此函数的作用域就变小了

相关文章

【数据结构】——哈夫曼树

速通回忆 这里是完整的代码和运行结果,可以直接选择看下面代码的思路去快速回忆哈夫曼树,或从下面理论部分开始学习 ``` #include "stdio.h" #include "stdlib.h" /* 哈夫曼树结点的结构体 */ typedef struct { int weight; /* 权重 */ int parent; /* 父母结点下标 */ int l...

c

强化C【C语言笔记】——位运算

位运算符C语言提供了六种位运算符 - &:按位与 - !:按位或 - ^:异或 - ~:取反 - <<:左移 - \>>:右移 按位与运算 **其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0** 按位与运算通常用来对某些位清0 按位或运算 **其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就...

c

C语言中规中矩的大树

**没事干,写个树玩玩,真正的“撸树”** 在Ubuntu终端、VScode终端显示 代码 ``` #include "stdio.h" int main(){ int high = 5; //层高 int count = 5; //层数 int start; //每层开始*数 int...

c