C语言const关键字的用法详解

 更新时间:2022年08月18日 11:08:30   作者:Love coldplay  
今天探讨const,首先来说是将变量常量化。为什么要将变量常量化,原因有诸多好处有诸多。比如可以使数据更加安全不会被修改

1 介绍

const关键字是constant的缩写,翻译为常量、常数。在C语言中const的作用很强大,它可以修饰变量、数组、指针、函数参数等。

1.1 const修饰变量

const修饰变量,表示希望此变量具有只读性,防止被直接直接修改。

//const关键字是constant的缩写,翻译为常量、常数。
//在C语言中const的作用很强大,它可以修饰变量、数组、指针、函数参数等。
#include<stdio.h>
int main()
{
	const int num = 100;
	num = 20;
	printf("%d\n", num);
}

发现const 修饰的变量,随后试图修改num的值,结果出现红色波浪线,编译器提醒我们:表达式必须是可修改的左值。

所以我们得出结论:const修饰的变量,不能被修改。

const修饰的变量就一定不能被修改吗???

	const int num = 100;
	int *p = &num;
	*p= 20;
	printf("%d\n", num);

运行结果

通过上图我们发现num的值被修改了,通过指针可以间接的修改const修饰的变量。

但是运行时会出现警告:warning C4090: “初始化”: 不同的“const”限定符。

是因为num类型是const修饰,但是p是整型指针变量 ,

类型不同。所以通过下面强转就没警告了。

改进后的代码

    const int num = 100;
	int *p = (int*)&num;
	*p= 20;
	printf("%d\n", num);

总结:const修饰的变量不能被直接修改

1.2 const修饰数组

#include<stdio.h>
int main()
{
	const int array[5] = { 0,1,2,3,4 };
	array[0] = 100;
}

表示const修饰的数组也不能被修改。

通过上面1.1const修饰变量的分析,同理也联想到:指针是否可以修改数组的内容。结果如下:

#include<stdio.h>
int main()
{
	const int array[5] = { 0,1,2,3,4 };
	//array[0] = 100;
	int *p = array;
	*p = 100;
	printf("%d\n", array[0]);
}

不难发现,指针可以修改。和1.1节出现结果一样,同样运行时程序出现了警告:warning C4090: “初始化”: 不同的“const”限定符,同样的警告出现了。

经过强转后:

#include<stdio.h>
int main()
{
	const int array[5] = { 0,1,2,3,4 };
	//array[0] = 100;
	int *p = (int *)array;//array原本的数据类型为const int[5]
	*p = 100;
	printf("%d\n", array[0]);
}

总结:const修饰数组时,其值不能被直接修改

1.3 const修饰指针

此部分分为两种情况去分析:

#include<stdio.h>
int main()
{
	int a = 100;
	const int *p = &a;
	*p = 1000;
	printf("%d\n", a);
}

此时,通过上图容易发现const修饰指针指向的内容一旦修改,就会自动报错,所以*p(指针指向的内容不能被修改),但指针变量p本身是可以被修改的。

#include<stdio.h>
int main()
{
	int a = 100;
	int* const p = &a;//p的数据类型为int *const
	*p = 1000;
	printf("%d\n", a);
}

此时,const修饰的是指针p本身,所以指针本身不能被修改,但是指针所指向的内容*p可被修改

1.4 const修饰函数参数

#include<stdio.h>
int myFunc(const int* p)
{
	*p = *p + 1;
	return *p;
}

const修饰函数参数,对参数起到限定的作用, 通过发现指针也能修改其值。

总结:const修饰函数参数,本质上和修饰变量和指针一样。表示其值不能被直接修改。

2 const对程序的影响

可以发现,在*p下面出现了红色波浪线,让上述的错误提前出现,避免程序在运行时出错。

总结:编译器可以对const修饰的变量进行合理性检查,让错误提前出现。

3 总结

通过这篇博客,我对const修饰变量、数组、指着和函数参数进行了归纳总结。总体来说有几个点需要注意:

const修饰变量,不能被直接修改
const修饰指针指向的内容时(const int * p=&a),指针指向内容(*p)不能被修改,但指针本身(p)可以被修改。
const修饰指针本身时(int * const p =&a),指针指向的内容(*p)可以被修改,但是指针本身(p)不能被修改。
const 修饰字符串 (const *p=“abcd”;)和(const p[]=“abcd”;)这两种情况的分析,前者字符串不能修改,后者字符串可以修改。这    是由C语言使用存储器的方式决定的。

补充内容

char *cards = “JQK”; 的情况下计算机操作的步骤:

计算机做的步骤:

计算机加载字符串字面值:
当计算机把程序载入存储器时,会把所有常数值(如字符串常量"JQK")放到常量存储区,这部分存储器是只读的。

程序在栈上创建cards变量
栈是存储器中计算机用来保存局部变量的部分,局部变量也就是位于函数内部的变量,cards变量就在这个地方。

cards变量设为"JQK"的地址
cards变量将会保存字符串字面值"JQK"的地址。为了防止修改,字符串字面值通常保存在只读存储器中。

计算机试图修改字符串
程序试图修改cards变量指向的字符串中的内容时就会失败,因为字符串是只读的。

char cards[] = “JQK”;的情况下计算机操作的步骤:

计算机加载字符串字面值:
当计算机把程序载入存储器时,会把所有常数值(如字符串常量"JQK")放到常量存储区,这部分存储器是只读的。

程序在栈上新建了一个数组
我们声明了数组,所以程序会创建一个足够大的数组来保存字符串"JQK"

程序初始化数组
除了为数组分配空间,程序还会把字符串字面值"JQK"的内容复制到栈上。

补充内容

char *cards = “JQK”; 的情况下计算机操作的步骤:

计算机做的步骤:

计算机加载字符串字面值:
当计算机把程序载入存储器时,会把所有常数值(如字符串常量"JQK")放到常量存储区,这部分存储器是只读的。

程序在栈上创建cards变量
栈是存储器中计算机用来保存局部变量的部分,局部变量也就是位于函数内部的变量,cards变量就在这个地方。

cards变量设为"JQK"的地址
cards变量将会保存字符串字面值"JQK"的地址。为了防止修改,字符串字面值通常保存在只读存储器中。

计算机试图修改字符串
程序试图修改cards变量指向的字符串中的内容时就会失败,因为字符串是只读的。

char cards[] = “JQK”;的情况下计算机操作的步骤:

计算机加载字符串字面值:
当计算机把程序载入存储器时,会把所有常数值(如字符串常量"JQK")放到常量存储区,这部分存储器是只读的。

程序在栈上新建了一个数组
我们声明了数组,所以程序会创建一个足够大的数组来保存字符串"JQK"

程序初始化数组
除了为数组分配空间,程序还会把字符串字面值"JQK"的内容复制到栈上。

区别:

原来的代码使用了指向只读字符串字面值的指针;而在第二段代码中,用字符串字面值初始化了一个数组,从而得到了这些字母的副本,这样就可以随意修改他们了。

到此这篇关于C语言const关键字的用法详解的文章就介绍到这了,更多相关C语言const内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言枚举与联合图文梳理讲解

    C语言枚举与联合图文梳理讲解

    枚举顾名思义就是把所有的可能性列举出来,像一个星期分为七天我们就可以使用枚举,联合体是由关键字union和标签定义的,和枚举是一样的定义方式,不一样的是,一个联合体只有一块内存空间,什么意思呢,就相当于只开辟最大的变量的内存,其他的变量都在那个变量占据空间
    2023-01-01
  • C++深入讲解哈夫曼树

    C++深入讲解哈夫曼树

    给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近
    2022-05-05
  • C语言数据结构算法基础之循环队列示例

    C语言数据结构算法基础之循环队列示例

    这篇文章主要为大家介绍了C语言数据结构算法基础之循环队列,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • C++实现数据结构的顺序表详解

    C++实现数据结构的顺序表详解

    这篇文章主要为大家详细介绍了C++实现动态顺序表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C++ std:map的使用方法

    C++ std:map的使用方法

    std::map是C++标准库中一个强大而高效的关联容器,本文就来介绍一下C++ std:map的使用方法,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • VS Code+msys2配置Windows系统下C/C++开发环境

    VS Code+msys2配置Windows系统下C/C++开发环境

    我们在windows10中使用VS Code做C++程序开发过程中,需要安装MSYS2和MinGW,下面这篇文章主要给大家介绍了关于VS Code+msys2配置Windows系统下C/C++开发环境的相关资料,需要的朋友可以参考下
    2022-12-12
  • C语言 如何求两整数的最大公约数与最小公倍数

    C语言 如何求两整数的最大公约数与最小公倍数

    这篇文章主要介绍了C语言中如何求两整数的最大公约数与最小公倍数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C语言实现模拟USB对8bit数据的NRZI编码输出

    C语言实现模拟USB对8bit数据的NRZI编码输出

    今天小编就为大家分享一篇关于C语言实现模拟USB对8bit数据的NRZI编码输出,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 详解C语言实现猜数字游戏

    详解C语言实现猜数字游戏

    这篇文章主要为大家介绍了C语言实现猜数字游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助<BR>
    2022-01-01
  • 基于C语言自制华容道游戏的示例代码

    基于C语言自制华容道游戏的示例代码

    这篇文章主要为大家详细介绍了如何利用C语言自制华容道游戏,文中的示例代码讲解详细,对我们学习C语言有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-03-03

最新评论