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没有意义

相关推荐
Vane Zhang2 分钟前
VirtualBox7.1.0 安装 Ubuntu22.04.5 虚拟机
linux
sysin.org3 分钟前
Ubuntu 22.04.5 LTS 发布下载 - 现代化的企业与开源 Linux
linux·ubuntu
MonkeyKing_sunyuhua4 分钟前
Ubuntu 中无法直接使用 `conda` 命令,设置conda的环境变量
linux·ubuntu·conda
柠檬少少开发13 分钟前
图像拼接算法及实现(一)
人工智能·算法·计算机视觉
DreamByte17 分钟前
Python Tkinter小程序
开发语言·python·小程序
jnrjian23 分钟前
USE_CONCAT in list OR 以及 filter Nest LOOP
数据结构·list
覆水难收呀26 分钟前
三、(JS)JS中常见的表单事件
开发语言·前端·javascript
阿华的代码王国30 分钟前
【JavaEE】多线程编程引入——认识Thread类
java·开发语言·数据结构·mysql·java-ee
繁依Fanyi36 分钟前
828 华为云征文|华为 Flexus 云服务器部署 RustDesk Server,打造自己的远程桌面服务器
运维·服务器·开发语言·人工智能·pytorch·华为·华为云
小狮子安度因39 分钟前
边缘智能-大模型架构初探
linux·网络