C语言深度剖析--不定期更新的第五弹

const关键字

来看一段代码:

c 复制代码
#include <stdio.h>
int main()
{
	int a = 10;
	a = 20;
	printf("%d\n", a);
	return 0;
}

运行结果如下:

接下来我们在上面的代码做小小的修改:

c 复制代码
#include <stdio.h>
int main()
{
	const int a = 10;
	a = 20;
	printf("%d\n", a);
	return 0;
}

编译器报出来警告。这是因为const修饰的变量,不能直接被修改

const既可以放在类型名之前也可以放在类型名之后

来看以下的代码:

c 复制代码
#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	printf("before:%d\n", a);

	*p = 20;
	printf("after:%d\n", a);
	return 0;
}

运行结果如下:

这里我们需要知道一个点*p=a,用来修改a的值

在此基础上做一点点修改:

c 复制代码
int main()
{
	const int a = 10;
	int* p = (int*) & a;//这里需要进行强制类型转换,因为编译器会报出警告,因为类型不一致
	printf("before:%d\n", a);

	*p = 20;
	printf("after:%d\n", a);
	return 0;
}

运行结果如下:

得出结论:const修饰的变量可以被指针间接修改

总的来说,const修饰的变量并非不可修改的常量

const修饰的变量意义何在?

1.让编译器直接修改式检查

2.告诉其他程序员这个变量不能修改

注意一个点:

字符串常量是真正意义上的不可被修改**,这不是C语言层面上的,而是操作系统层面上的保护

const的价值不在于运行的时候,而是在于编译的时候

const只能在定义的时候直接初始化,不能二次赋值。为什么?

c 复制代码
const int a;
a=120;//这是不对的,因为不能被修改了

const修饰数组

一般只能是只读数组,就是不能被修改的

如下:

c 复制代码
const int arr[100]={1,2,3,4,5};

就不能进行修改里面的数据,如:arr[0]=2;,这样编译器会报错的

什么是指针?

指针就是地址,它是一种具体的数据

指针变量是一种变量,里面保存的是指针

再来看个例子:

c 复制代码
int x=100;//空间,变量的属性,左值
int y=x;//内容,数据的属性,右值

任何一个变量名,在不同的应用场景中,代表不同的含义==

对于指针变量来说呢?

c 复制代码
int a=10;
int*p=&a;
q=p;

和上面同理,指针变量和普通变量差不多,不要过度神化或者畏惧

需要做个刻意地小练习:在看到指针和指针变量的时候,一定要问自己这里指的是指针,就是地址,还是指针变量是一个变量。里面存的是地址

const修饰指针

科普一个概念:
指针的解引用

c 复制代码
int a=10;
int*p=&a;

这里面有几个变量?

答案是2个

内存选址的单位是以字节为单位

我们这里拿a举例子,a是int类型的,4个字节,也就意味着有4个地址,但是取地址的时候不是全部取出来,取的是地址最低的那个

我们可以得出来一个结论:在C语言中,任何变量取地址都是从最低地址开始取

解引用:

c 复制代码
*p=20;
int b=*p;

修饰指针

c 复制代码
int a = 10;
const int* p = &a;//p指向的变量不可以直接被修改
*p = 100;//这是不对的
p = 100;

这里可能会有疑惑,const不是离int最近吗,为什么要看*,因为const是关键字,int也是关键字,会引起关键字冲突

第二种写法和第一种写法效果是一致的,但是我们更推荐第一种写法

c 复制代码
int a = 10;
	int* const p = &a;//p的内容不能直接被修改,p指向不能改
	*p = 100;
	//p = 100;//这个不对

同理,第四个,两个都不行

再来看一组代码的对比:

代码1:

c 复制代码
const int *p=&a;
int*q=p;

代码2:

c 复制代码
int *p=&a;
const int*q=p;

代码1,会存在警告是因为左右两边类型不一致,左边是int*类型,右边是被const修饰的常量,需要在p前面加上(int *) ,进行强制类型转换;

代码2不会存在警告,这里是因为我们把一个类型不严格的变量赋值给一个类型严格的变量编译器是不会报出警告的

来看示例:

c 复制代码
void show(const int*_p)
{
	printf("%d\n",*_p);
	printf("show p:%p\n",&_p);
}
int main()
{
	int a=10;
    int*p=&a;
    show(p);
    printf("main p:%p\n",&p);
    
}

这是一种预防性编程,预防未来可能会出现的问题

在C语言中,任何函数参数都一定要形成临时变量,包括指针变量

打印出来的地址是不同的

const修饰函数

例子如下:

c 复制代码
const int*GetVal()
{
	static int a=10;
    return &a;
}
int main()
{
	const int*p=GetVal();
}

这里函数用const修饰,目的是不希望有人在返回值的时候进行修改

一般内置类型返回,加const没有意义

相关推荐
NAGNIP9 小时前
大模型框架性能优化策略:延迟、吞吐量与成本权衡
算法
美团技术团队10 小时前
LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
人工智能·算法
轻松Ai享生活14 小时前
5 节课深入学习Linux Cgroups
linux
Fanxt_Ja15 小时前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下15 小时前
最终的信号类
开发语言·c++·算法
christine-rr15 小时前
linux常用命令(4)——压缩命令
linux·服务器·redis
茉莉玫瑰花茶15 小时前
算法 --- 字符串
算法
三坛海会大神55515 小时前
LVS与Keepalived详解(二)LVS负载均衡实现实操
linux·负载均衡·lvs
東雪蓮☆15 小时前
深入理解 LVS-DR 模式与 Keepalived 高可用集群
linux·运维·服务器·lvs
博笙困了15 小时前
AcWing学习——差分
c++·算法