C语言const的用法详解

news2025/1/9 12:59:21

有时候我们希望定义这样一种变量,它的值不能被改变,在整个作用域中都保持固定。例如,用一个变量来表示班级的最大人数,或者表示缓冲区的大小。为了满足这一要求,可以使用const关键字对变量加以限定:

constint MaxNum =100;//班级的最大人数

这样 MaxNum 的值就不能被修改了,任何对 MaxNum 赋值的行为都将引发错误:

MaxNum =90;//错误,试图向 const 变量写入数据

我们经常将 const 变量称为常量(Constant)。创建常量的格式通常为:

const type name = value;

const 和 type 都是用来修饰变量的,它们的位置可以互换,也就是将 type 放在 const 前面:

type const name = value;

但我们通常采用第一种方式,不采用第二种方式。另外建议将常量名的首字母大写,以提醒程序员这是个常量。

由于常量一旦被创建后其值就不能再改变,所以常量必须在定义的同时赋值(初始化),后面的任何赋值行为都将引发错误。一如既往,初始化常量可以使用任意形式的表达式,如下所示:

#include<stdio.h>

intgetNum(){
return100;
}

intmain(){
int n =90;
constint MaxNum1 =getNum();//运行时初始化
constint MaxNum2 = n;//运行时初始化
constint MaxNum3 =80;//编译时初始化
printf("%d, %d, %d\n", MaxNum1, MaxNum2, MaxNum3);

return0;
}

运行结果:

100, 90, 80

const 和指针

const 也可以和指针变量一起使用,这样可以限制指针变量本身,也可以限制指针指向的数据。const 和指针一起使用会有几种不同的顺序,如下所示:

constint*p1;
intconst*p2;
int*const p3;

在最后一种情况下,指针是只读的,也就是 p3 本身的值不能被修改;在前面两种情况下,指针所指向的数据是只读的,也就是 p1、p2 本身的值可以修改(指向不同的数据),但它们指向的数据不能被修改。

当然,指针本身和它指向的数据都有可能是只读的,下面的两种写法能够做到这一点:

constint*const p4;
intconst*const p5;

const 和指针结合的写法多少有点让初学者摸不着头脑,大家可以这样来记忆:const 离变量名近就是用来修饰指针变量的,离变量名远就是用来修饰指针指向的数据,如果近的和远的都有,那么就同时修饰指针变量以及它指向的数据。

const 和函数形参

在C语言中,单独定义 const 变量没有明显的优势,完全可以使用#define命令代替。const 通常用在函数形参中,如果形参是一个指针,为了防止在函数内部修改指针指向的数据,就可以用 const 来限制。

在C语言标准库中,有很多函数的形参都被 const 限制了,下面是部分函数的原型:

size_t strlen(constchar* str );
intstrcmp(constchar* str1,constchar* str2 );
char*strcat(char* destination,constchar* source );
char*strcpy(char* destination,constchar* source );
intsystem(constchar* command);
intputs(constchar* str );
intprintf(constchar* format,...);

我们自己在定义函数时也可以使用 const 对形参加以限制,例如查找字符串中某个字符出现的次数:

#include<stdio.h>

size_t strnchr(constchar*str,char ch){
int i, n =0, len =strlen(str);

for(i=0; i<len; i++){
if(str[i]== ch){
            n++;
}
}

return n;
}

intmain(){
char*str ="http://csdn.net";
char ch ='t';
int n =strnchr(str, ch);
printf("%d\n", n);
return0;
}

运行结果:

3

根据 strnchr() 的功能可以推断,函数内部要对字符串 str 进行遍历,不应该有修改的动作,用 const 加以限制,不但可以防止由于程序员误操作引起的字符串修改,还可以给用户一个提示,函数不会修改你提供的字符串,请你放心。

const 和非 const 类型转换

当一个指针变量 str1 被 const 限制时,并且类似const char *str1这种形式,说明指针指向的数据不能被修改;如果将 str1 赋值给另外一个未被 const 修饰的指针变量 str2,就有可能发生危险。因为通过 str1 不能修改数据,而赋值后通过 str2 能够修改数据了,意义发生了转变,所以编译器不提倡这种行为,会给出错误或警告。

也就是说,const char *和char *是不同的类型,不能将const char *类型的数据赋值给char *类型的变量。但反过来是可以的,编译器允许将char *类型的数据赋值给const char *类型的变量。

这种限制很容易理解,char *指向的数据有读取和写入权限,而const char *指向的数据只有读取权限,降低数据的权限不会带来任何问题,但提升数据的权限就有可能发生危险。

C语言标准库中很多函数的参数都被 const 限制了,但我们在以前的编码过程中并没有注意这个问题,经常将非 const 类型的数据传递给 const 类型的形参,这样做从未引发任何副作用,原因就是上面讲到的,将非 const 类型转换为 const 类型是允许的。

下面是一个将 const 类型赋值给非 const 类型的例子:

#include<stdio.h>

voidfunc(char*str){}

intmain(){
constchar*str1 ="csdn.net";
char*str2 = str1;
func(str1);
return0;
}

第7、8行代码分别通过赋值、传参(传参的本质也是赋值)将 const 类型的数据交给了非 const 类型的变量,编译器不会容忍这种行为,会给出警告,甚至直接报错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/336760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大型智慧校园系统源码 智慧班牌 智慧安防 家校互联 智慧校园小程序源码

一款针对中小学研发的智慧校园系统源码&#xff0c;智慧学校源码&#xff0c;系统有演示&#xff0c;可正常上线运营正版授权。 技术架构&#xff1a; 后端&#xff1a;Java 框架&#xff1a;springboot 前端页面&#xff1a;vue element-ui 小程序&#xff1a;小程序原生…

【CDP】CDP集群修改solr 存储路径 引发组件的ranger-audit 大量报错的解决方案

前言 我们生产上公司是使用的CDP集群&#xff0c;一次管理员通知&#xff0c;Solr 组件的数据存放路径磁盘空间不够。 我们的solr 组件时为 Ranger 服务提供日志审计功能&#xff0c; 在我们更改了磁盘路径&#xff0c;并重启了Solr 组件&#xff0c;然后发现相关组件&#…

立创eda专业版学习笔记(6)(pcb板移动节点)

先要看一个设置方面的东西&#xff1a; 进入设置-pcb-通用 我鼠标放到竖着的线上面&#xff0c;第一次点左键是这样选中的&#xff1a; 再点一次左键是这样选中的&#xff1a; 这个时候&#xff0c;把鼠标放到转角的地方&#xff0c;点右键&#xff0c;就会出现对于节点的选项…

关于VSCode安装go插件问题

比较常见的go开发编辑工具有VSCode、GoLand等&#xff0c;其中&#xff0c;使用VSCode需要下载相关的go语言插件。但是大多数情况都会下载失败&#xff0c;因为有些资源需要翻墙的原因&#xff0c;有时候翻墙了还是会报错。   本文将介绍一种帮助大家成功下载go插件的方法&am…

流水线使用(测试->构建->部署上线)

流水线介绍&#xff08;可直接查阅云效中流水线介绍&#xff09; 流水线在项目中的使用 1、选择我的流水线—>新建流水线 2、选择流水线模板&#xff08;可以根据需求选择不同模板&#xff09; 3、流水线配置 ①选择代码源&#xff1a;我目前展示的是直接使用codeup中的代码…

apipost-一键压测

apipost新功能可实现一键压测接口压测实践使用场景对指定接口进行性能测试。实现方式为实现高性能的并发需求&#xff0c;使用自研的压测引擎&#xff0c;可以实现一万以上并发。项目已经开源&#xff0c;github地址&#xff1a;https://github.com/Apipost-Team/runnerGo压测结…

antd日期组件时间范围动态跟随

这周遇到了一个很诡异但又很合理的需求。掉了一周头发&#xff0c;死了很多脑细胞终于上线了。必须总结一下&#xff0c;不然对不起自己哈哈哈。 一、需求描述 默认当前日期时间不可清空。 功能 默认时间如下&#xff1a; 目的&#xff1a;将时间改为 2014-08-01 ~ 2014-08…

网络工程师测试命令排行榜,快来看一看吧! -ccie网络工程师

网络工程师测试命令排行榜&#xff0c;快来看一看吧&#xff01; 01 Ping命令 ping命令的主要功能是用来检测网络的连通情况和分析网络运行速度。它是基于TCP/IP协议、通过发送和接收数据包来检测两台计算机间的连接状况。 网络工程师用 ping查看网络情况&#xff0c;主要…

【无标题】tcpdump 命令

tcp一款sniffer工具&#xff0c;是Linux上的抓包工具&#xff0c;嗅探器语法tcpdump (选项)选项-c&#xff1a; 指定要抓取的包数量。注意&#xff0c;是最终要获取这么多个包。例如&#xff0c;指定"-c 10"将获取10个包&#xff0c;但可能已经处理了100个包&#xf…

如何基于声网互动白板实现一个多人数独游戏

本文作者是声网社区的开发者“tjss”。他基于 Vue、声网的互动白板的代码模板&#xff0c;搭建出了一个支持多人互动的数独游戏。本文记录了他的实现过程&#xff0c;欢迎大家也可以尝试实现自己的小游戏或应用。 我基于声网互动白板的 SDK 与 Window Manager 开发了一个场景化…

第二十三周周报

学习内容&#xff1a; 修改ViTGAN代码 学习时间&#xff1a; 2.3-2.10 学习产出&#xff1a; 现在的效果 可以看到在700k左右fid开始上升&#xff0c;相比vitgan&#xff0c;改的vitgan鉴别器loss有所下降&#xff0c;但是fid没有降下来&#xff0c;最好为23.134&#xf…

Elasticsearch7.8.0版本进阶——分布式集群(水平扩容)

目录一、Elasticsearch集群的安装1.1、Elasticsearch集群的安装&#xff08;win10环境&#xff09;1.2、Elasticsearch集群的安装&#xff08;linux环境&#xff09;二、水平扩容&#xff08;win10环境集群演示&#xff09;三、想要扩容超过 6 个节点怎么办3.1、主分片和副分片…

IDEA合并分支(从开发分支到测试分支)

IDEA合并分支(从开发分支到测试分支) 1、先在当前分支拉去最新的代码且提交自己的修改到远程分支上 2、切换到目标分支(你要合并到的分支上),test测试分支 3、进行分支合并,这里其实有3个选项比较常用 ①Compare with ‘test’ 与当前分支(test)比较,这个比较回弹出个窗口…

刷爆网络的ChatGpt,给大家搞来了。

最近chatgpt可谓是顶上了热搜&#xff0c;之前写代码的同学们应该都知道出了一款插件叫做 Copilot&#xff0c;这是一款可以帮你自动写代码的插件&#xff0c;只要输入你想要写的代码&#xff0c;比如写一个js轮播图之类的&#xff0c;立马就可以帮你生成。不仅如此&#xff0c…

随着攻击者适应绕过零信任,公司在苦苦挣扎

商业情报公司 Gartner 表示&#xff0c;零信任安全方法有望减少威胁并降低成功攻击的破坏性&#xff0c;但公司不应期望实施零信任原则会很容易或阻止大多数攻击。 虽然对零信任架构的兴趣很高&#xff0c;但目前只有大约 1% 的组织拥有满足零信任定义的成熟程序。 该公司还估…

论文投稿指南——中文核心期刊推荐(石油、天然气工业 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

【火电机组、风能、储能】高比例风电电力系统储能运行及配置分析(Matlab代码实现)

目录 摘 要 0 目标函数和约束条件 1 第一题 2 第二题 3 第三题 4 第四题&#xff1a;含高比例风电电力系统最小供电成本模型 6 第六题&#xff1a; 7 第七题&#xff1a; 8 所有题代码及文章详细讲解 9 结论&#xff1a; 10 参考文献 摘 要 高比例风电电力系统储…

JVM——运行期优化

目录一、分层编译&#xff08;TieredCompilation&#xff09;即时编译器&#xff08;JIT&#xff09;与解释器的区别逃逸分析二、方法内联&#xff08;Inlining&#xff09;三、反射优化一、分层编译&#xff08;TieredCompilation&#xff09; JVM 将执行状态分成了 5 个层次…

宜家EDI IFTMBC运输预定确认详解

IFTMBC是宜家与其供应商之间传输的符合EDIFACT标准的报文&#xff0c;在此前的文章如何读懂EDIFACT报文中&#xff0c;我们已经对EDIFACT做了详细的解读。在供应商发给宜家IFTMBF运输预定请求后&#xff0c;宜家会回复IFTMBC运输预订确认给供应商。 本文将从供应商接收宜家发送…

【Java|golang】1798. 你能构造出连续值的最大数目

给你一个长度为 n 的整数数组 coins &#xff0c;它代表你拥有的 n 个硬币。第 i 个硬币的值为 coins[i] 。如果你从这些硬币中选出一部分硬币&#xff0c;它们的和为 x &#xff0c;那么称&#xff0c;你可以 构造 出 x 。 请返回从 0 开始&#xff08;包括 0 &#xff09;&a…