当前位置: 首页 > news >正文

C语言:const的用法

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

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

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

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

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

const type name = value;

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

type const name = value;

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

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

1. #include <stdio.h>
2.
3. int getNum(){
4. return 100;
5. }
6.
7. int main(){
8. int n = 90;
9. const int MaxNum1 = getNum(); //运行时初始化
10. const int MaxNum2 = n; //运行时初始化
11. const int MaxNum3 = 80; //编译时初始化
12. printf("%d, %d, %d\\n", MaxNum1, MaxNum2, MaxNum3);
13.
14. return 0;
15. }

运行结果: 100, 90, 80

const 和指针

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

1. const int *p1;
2. int const *p2;
3. int * const p3;

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

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

1. const int * const p4;
2. int const * const p5;

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

const 和函数形参

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

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

1. size_t strlen ( const char * str );
2. int strcmp ( const char * str1, const char * str2 );
3. char * strcat ( char * destination, const char * source );
4. char * strcpy ( char * destination, const char * source );
5. int system (const char* command);
6. int puts ( const char * str );
7. int printf ( const char * format, ... );

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

1. #include <stdio.h>
2.
3. size_t strnchr(const char *str, char ch){
4. int i, n = 0, len = strlen(str);
5.
6. for(i=0; i<len; i++){
7. if(str[i] == ch){
8. n++;
9. }
10. }
11. 
12. return n;
13. }
14.
15. int main(){
16. char *str = "zytzixue";
17. char ch = 't';
18. int n = strnchr(str, ch);
19. printf("%d\\n", n);
20. return 0;
21. }

运行结果: 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 类型的例子:

1. #include <stdio.h>
2.
3. void func(char *str){ }
4.
5. int main(){
6. const char *str1 = "zytzixue";
7. char *str2 = str1;
8. func(str1);
9. return 0;
10. }

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

相关文章:

C语言:const的用法

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

Redis - 集合 Set 及代码实战

Set 类型 定义&#xff1a;类似 Java 中的 HashSet 类&#xff0c;key 是 set 的名字&#xff0c;value 是集合中的值特点 无序元素唯一查找速度快支持交集、并集、补集功能 常见命令 命令功能SADD key member …添加元素SREM key member …删除元素SCARD key获取元素个数SI…...

LabVIEW面向对象编程有什么特点?

LabVIEW面向对象编程&#xff08;OOP&#xff09;的特点主要体现在它如何结合传统面向对象编程&#xff08;OOP&#xff09;的理念与LabVIEW的图形化编程模式&#xff0c;提供灵活的抽象和模块化的功能。以下是LabVIEW面向对象编程的几个主要特点&#xff1a; ​ 1. 类&#x…...

配置Nginx自签名SSL证书,支持HTTPS

配置Nginx自签名SSL证书的流程 生成一个SSL自签名证书客户端机器信任这个自签名证书修改RHEL服务器的Nginx配置在客户机用curl测试HTTPS 生成一个SSL自签名证书 在RHEL服务器上, 用openssl命令生成一个自签名证书 openssl genrsa -out server.key 2048 #生成一个2048位的RS…...

使用Spring Boot、VUE实现SSE长连接:跟踪文件上传和任务进度

使用Spring Boot实现SSE长连接&#xff1a;跟踪文件上传和任务进度 文章目录 使用Spring Boot实现SSE长连接&#xff1a;跟踪文件上传和任务进度什么是SSE&#xff1f;使用场景前端库选择安装event-source-polyfill1. 创建SSE连接2. 关闭SSE连接3. 结合Vue.js使用 使用Spring B…...

计算机网络技术基础:3.计算机网络的拓扑结构

网络拓扑结构是指用传输媒体互连各种设备的物理布局&#xff0c;即用什么方式把网络中的计算机等设备连接起来。将工作站、服务站等网络设备抽象为点&#xff0c;称为“节点”&#xff1b;将通信线路抽象为线&#xff0c;称为“链路”。由节点和链路构成的抽象结构就是网络拓扑…...

go-zero(十二)消息队列

go zero 消息队列 在微服务架构中&#xff0c;消息队列主要通过异步通信实现服务间的解耦&#xff0c;使得各个服务可以独立发展和扩展。 go-zero中使用的队列组件go-queue&#xff0c;是gozero官方实现的基于Kafka和Beanstalkd 的消息队列框架,我们使用kafka作为演示。 一、…...

会议通知:人工智能通识教育与实践发展暨和鲸科技AI通识课解决方案发布会

今年秋季学期起&#xff0c;全国多所高校面向本科生开设人工智能通识课。 当前人工智能通识课程的建设进展主要分为三种情况&#xff1a; 全市统筹&#xff0c;由某头部高校牵头建设市级人工智能通识课&#xff0c;以北京市、天津市为代表&#xff1b; 已于秋季学期按照课程…...

UDS自动化测试-Service 0x27(CAPL调用dll实现key计算)

文章目录 关联文章一、CANoe加载诊断数据库cdd、dll文件二、CAPLdiagGenerateKeyFromSeed关联文章 UDS - 深论Security Access Service 27服务-安全访问状态转换 CDD文件——CANdelaStudio Vector——CAPL语言设计 CANoe诊断测试 相信读者基于Diagnostic/ISO TP Confighratio…...

订单编号如何实现

背景 常见的订单编号是带有一些信息的&#xff0c;比如说创建日期例如&#xff1a;本案例中的订单日期 自增编号日期可以使用格式化字符串&#xff0c;自增则可以使用redis来实现 代码实现 redis就有自增的方法 每天的key都是不一样的&#xff0c;且过期时间设置为1天 // 生成…...

Vue3 大事件管理系统

Vue3 项目实战&#xff1a; &#x1f197;好久没有更新blog&#xff0c;最近在找工作&#xff0c;还有准备考试&#xff0c;哎&#xff0c;&#x1f636;‍&#x1f32b;️爆炸的大环境&#x1f972; 内卷开始&#x1f32f;&#x1f32f; 本篇文章涉及的技术栈速通链接&#x…...

IOS通过WDA自动化中遇到的问题

IOS自动化遇到的问题 搭建WDA环境中遇到的问题1、XCode unsupport iphone xxx.2、创建Bundle Identifier出现问题&#xff1a;Communication with Apple failed3、创建Bundle Identifier出现问题&#xff1a;Automatic signing failed \Signing certificate is invalid4、创建B…...

单独测试 pyautogui 的鼠标点击功能,确保它能够在当前环境中正常工作,鼠标自动点击的录制回放功能

感谢您提供的详细日志信息。根据您的反馈&#xff0c;问题可能出在 pyautogui 没有正确获取鼠标焦点或无法在预期的位置执行点击操作。我们将采取以下步骤来进一步诊断和解决这个问题&#xff1a; 1. **确保 pyautogui 正确执行点击操作**&#xff1a; - 我们将添加更多的调…...

路由引入问题(双点双向路由回馈问题)

简介 总所周知&#xff0c;路由引入import又称路由重分发redistribute&#xff0c;为了解决不同路由协议进程间路由信息不互通而使用的技术&#xff0c;由于不同路由协议的算法、机制、开销等因素的差异&#xff0c;它们之间无法直接交换路由信息。因此&#xff0c;路由引入技…...

设计模式之 适配器模式 C# 范例

在 C# 中&#xff0c;适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;旨在将一个类的接口转换成客户端所期待的另一个接口。适配器模式允许你将现有的类包装起来&#xff0c;使其能够与其他接口兼容。 适配器模式的使用场景&#xff1a; …...

LabVIEW实现GPS通信

目录 1、GPS通信原理 2、硬件环境部署 3、程序架构 4、前面板设计 5、程序框图设计 6、测试验证 本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合实际案例,展示如何利用LabVIEW和常用模块实现物联网系…...

[leetcode100] 543. 二叉树的直径

https://leetcode.cn/problems/diameter-of-binary-tree/description/?envTypestudy-plan-v2&envIdtop-100-liked 题目描述&#xff1a;给一个二叉树&#xff0c;返回二叉树直径最大值。直径指的是二叉树中任意一个结点到另外一个结点产生路径的长度。而长度由边来代表。…...

嵌入式学习(18)-stm32F407串口接收空闲中断+DMA

一、概述 在一些一次性接收大批量数据的引用场合&#xff0c;如果使用接收中断会频繁的进入接收中断影响代码的运行效率。为了解决这个问题可以使用串口的空闲中断DMA实现。 二、应用 在网上招了一些例程在STM32F407的平台上都没有跑通会出现各种异常&#xff0c;主要原因还…...

b站视频爬虫-词云分析

一、设置爬虫程序 # requests 请求b站视频 import jsonimport fake_useragent import requests from lxml import etreeif __name__ == __main__:# UA伪装head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …...

如何防止订单二次重复支付?

如何防止订单二次重复支付&#xff1f; 在电商平台和支付系统中&#xff0c;防止订单二次重复支付是一个至关重要的功能。以下是一些常见的策略和技术手段&#xff0c;用于确保订单支付的幂等性和一致性。 目录 唯一订单号订单状态检查数据库事务乐观锁悲观锁支付渠道状态核查…...

Linux 中替换文件中的某个字符串

如果你想在 Linux 中替换文件中的某个字符串&#xff0c;可以使用以下命令&#xff1a; 1. 基本替换&#xff08;sed 命令&#xff09; sed -i s/原字符串/新字符串/g 文件名示例&#xff1a;将 file.txt 中所有的 old_text 替换成 new_text sed -i s/old_text/new_text/g fi…...

CKA考试知识点分享(2)---ingress

CKA 版本&#xff1a;1.32 第二题是涉及ingress相关。本文不是题目&#xff0c;只是为了学习相关知识点做的实验。 1. 环境准备 需要准备一套K8S集群。 1.1 安装ingress-nginx 下载deploy文件&#xff1a; wget -O controller-v1.12.2.yaml https://raw.githubusercontent…...

《架构即未来》笔记

思维导图 第一部分&#xff1a;可扩展性组织的人员配置 第二部分&#xff1a;构建可扩展的过程 第三部分&#xff1a;可扩展的架构方案 第四部分&#xff1a;其他的问题和挑战 资料 问软件工程研究所&#xff1a; https://www.sei.cmu.edu/ AKF公司博客: http://www.akfpart…...

matlab模糊控制实现路径规划

路径规划是机器人和自动驾驶系统中的重要问题之一&#xff0c;它涉及确定如何在给定环境中找到最优路径以达到特定目标。模糊控制是一种有效的控制方法&#xff0c;可以应用于路径规划问题。 路径规划算法的目标是在避免障碍物的情况下&#xff0c;找到机器人或车辆从起点到终…...

分类数据集 - 场景分类数据集下载

数据集介绍&#xff1a;自然场景分类数据集&#xff0c;真实场景高质量图片数据&#xff1b;适用实际项目应用&#xff1a;自然场景下场景分类项目&#xff0c;以及作为通用场景分类数据集场景数据的补充&#xff1b;数据集类别&#xff1a;buildings、forest、glacier、mounta…...

深入理解JavaScript设计模式之闭包与高阶函数

目录 前言小序一场失败面试面试后的觉醒 闭包变量作用域&#xff1a;谁的地盘听谁的变量的生命周期&#xff1a;该走了&#xff0c;不该走的还在闭包的更多作用&#xff1a;不只是谈恋爱&#xff0c;还能干活&#xff01;1、封装私有变量&#xff1a;你的变量我来守护2、延长变…...

IDEA中微服务指定端口启动

在使用IDEA开发SpringBoot微服务时&#xff0c;经常需要开启多个服务实例以测试负载均衡&#xff0c;以下几种方法开启不同端口。 直接在配置文件中指定 # application.propertiesserver.port8001指定VM参数 点击Modify options&#xff0c;选择Add VM options&#xff0c;值…...

uni-app 项目支持 vue 3.0 详解及版本升级方案?

uni-app 支持 Vue 3.0 详解及升级方案 一、uni-app 对 Vue 3.0 的支持现状 uni-app 从 3.0 版本 开始支持 Vue 3.0&#xff0c;主要变化包括&#xff1a; 核心框架升级&#xff1a; 基于 Vue 3.0 的 Composition API 和 Options API 双模式支持提供 vueuse/core 等组合式 API…...

【C++项目】负载均衡在线OJ系统-1

文章目录 前言项目结果演示技术栈&#xff1a;结构与总体思路compiler编译功能-common/util.hpp 拼接编译临时文件-common/log.hpp 开放式日志-common/util.hpp 获取时间戳方法-秒级-common/util.hpp 文件是否存在-compile_server/compiler.hpp 编译功能编写&#xff08;重要&a…...

做题笔记(ctfshow)

一。ctfshow web13 文件扫描 存在upload.php.bak <?php header("content-type:text/html;charsetutf-8");$filename $_FILES[file][name];$temp_name $_FILES[file][tmp_name];$size $_FILES[file][size];$error $_FILES[file][error];$arr pathinfo($fi…...