5. C语言 常量与宏定义

本章目录:

  • 前言
    • 一、什么是常量?
      • 1. 整型常量
      • 2. 浮点型常量
      • 3. 字符常量
      • 4. 字符串常量
    • 二、如何定义常量?
      • 1. 使用 `#define` 宏定义
      • 2. 使用 `const` 关键字
    • 三、`#define` 和 `const` 的区别
    • 四、使用建议
      • 1. 使用场景区分
      • 2. 避免宏定义的潜在问题
    • 五、特殊用法与小技巧
      • 1. 转义序列的等价性验证
      • 2. 宏的嵌套与动态计算
    • 六、总结


前言

C 语言中,常量是一种固定值,在程序执行期间不会改变。常量可以是整型、浮点型、字符型、字符串型,或者枚举类型。此外,C 提供了两种常用方式定义常量:#define 宏定义和 const 关键字。本篇文章将对常量、宏定义以及它们的区别做深入剖析,帮助你更高效地理解和使用它们。


一、什么是常量?

常量是指在程序运行过程中值不可改变的量。它们可以直接在代码中使用,也可以通过宏或关键字定义。根据类型,常量分为以下几种:

1. 整型常量

整型常量可以是十进制、八进制(前缀为 0)或十六进制(前缀为 0x)。
此外,还可以添加后缀以指示常量的类型:

  • U:无符号整型 (unsigned)
  • L:长整型 (long)
  • UL:无符号长整型

实例:

int decimal = 85;       // 十进制
int octal = 0213;       // 八进制,值为 139
int hex = 0x4B;         // 十六进制,值为 75
unsigned int uInt = 30U; // 无符号整型
long longInt = 100000L; // 长整型
unsigned long uLong = 50UL; // 无符号长整型

2. 浮点型常量

浮点型常量可以用小数形式或科学计数法表示,默认类型是 double,若需指定为 float 类型,可以添加后缀 fF

实例:

float pi = 3.14f;        // 单精度浮点数
double scientific = 3.14e-2; // 科学计数法

3. 字符常量

字符常量用单引号 ' 括起来,例如 'a'。常用转义序列包括 \n(换行)、\t(水平制表符)等。

实例:

char ch = 'A';          // 字符常量
char newline = '\n';    // 换行符

4. 字符串常量

字符串常量由双引号 " 包裹,内部以 \0(空字符)结尾。

实例:

char greeting[] = "Hello, World!";

二、如何定义常量?

C 中提供了两种定义常量的主要方式:

1. 使用 #define 宏定义

#define 是预处理指令,用于定义一个常量名及其对应值,编译时会将代码中的常量名替换为对应的值。

语法:

#define 常量名 常量值

实例:

#include <stdio.h>#define PI 3.14159
#define LENGTH 10
#define WIDTH  5int main() {int area = LENGTH * WIDTH;printf("Area: %d\n", area);printf("Circumference of circle with radius 5: %.2f\n", 2 * PI * 5);return 0;
}

注意事项:

  • 用括号避免“宏边缘效应”:
    #define LENGTH 10+10  // 错误:展开后会出错
    #define LENGTH (10+10) // 正确
    

2. 使用 const 关键字

const 定义的变量值不可修改,编译器会为其分配内存并进行类型检查。

语法:

const 数据类型 常量名 = 常量值;

实例:

#include <stdio.h>int main() {const double PI = 3.14159;const int LENGTH = 10;const int WIDTH = 5;int area = LENGTH * WIDTH;printf("Area: %d\n", area);printf("Circumference of circle with radius 5: %.2f\n", 2 * PI * 5);return 0;
}

三、#defineconst 的区别

特性#defineconst
类型检查无类型,不做检查有具体类型,编译检查
作用域无作用域限制有块级作用域
内存分配不分配内存,仅文本替换分配内存
效率编译时替换,无运行开销编译期间优化
调试信息无符号表信息有符号表信息

四、使用建议

1. 使用场景区分

  • 如果需要类型安全性和作用域控制,优先使用 const
  • 如果只需要简单的值替换且不关心类型,可以选择 #define

2. 避免宏定义的潜在问题

  • 用括号保护复杂的表达式:
    #define AREA(x, y) ((x) * (y))  // 避免 x + y 替换错误
    

五、特殊用法与小技巧

1. 转义序列的等价性验证

#include <stdio.h>int main() {printf("%c %c %c\n", '\101', '\x41', 'A'); // 输出:A A Areturn 0;
}

2. 宏的嵌套与动态计算

#define SQUARE(x) ((x) * (x))
#define CUBE(x) (SQUARE(x) * (x)) // 嵌套使用宏int result = CUBE(3); // 输出结果 27

六、总结

C 语言中的常量和宏定义各有千秋:

  • #define 注重编译期文本替换,适合简单、无需类型检查的场景。
  • const 提供类型安全和作用域控制,是现代 C 程序的推荐方式。

在实际开发中,建议遵循“能用 const 就不要用 #define”的原则,结合编译器优化,提高代码的可读性和安全性。


希望通过本篇文章,你能对常量和宏定义有更深入的理解!如果有任何问题,欢迎在评论区留言交流。 😊

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

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

相关文章

Elasticsearch:利用 AutoOps 检测长时间运行的搜索查询

作者&#xff1a;来自 Elastic Valentin Crettaz 了解 AutoOps 如何帮助你调查困扰集群的长期搜索查询以提高搜索性能。 AutoOps 于 11 月初在 Elastic Cloud Hosted 上发布&#xff0c;它通过性能建议、资源利用率和成本洞察、实时问题检测和解决路径显著简化了集群管理。 Au…

关于Flutter应用国际化语言的设置

目录 1. Locale配置 2. 用户切换/启动自动加载缓存里面的locale 由于最近在开发app国际化设置的时候遇到一些问题&#xff0c;所以做出一些总结。 1. Locale配置 具体的初始化配置可以参考文档&#xff1a;i18n | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 值得…

基层医联体医院患者历史检验检查数据的快速Python编程分析

​​​​​​​ 一、引言 1.1 研究背景与意义 在当今数字化医疗时代,医疗数据呈爆炸式增长,涵盖患者的基本信息、病史、检验检查结果、治疗方案等各个维度。这些海量且复杂的数据蕴含着巨大价值,为精准医疗决策提供了关键依据。通过对患者历史检验检查数据的深入对比分析…

如何使用OpenCV进行抓图-多线程

前言 需求&#xff1a; 1、如何使用OpenCV捕抓Windows电脑上USB摄像头的流、 2、采用多线程 3、获知当前摄像头的帧率。 这个需求&#xff0c;之前就有做了&#xff0c;但是由于出现了一个问题&#xff0c;人家摄像头的帧率目前都可以达到60帧/s 了&#xff0c;而我的程序…

数势科技:解锁数据分析 Agent 的智能密码(14/30)

一、数势科技引领数据分析变革 在当今数字化浪潮中&#xff0c;数据已然成为企业的核心资产&#xff0c;而数据分析则是挖掘这一资产价值的关键钥匙。数势科技&#xff0c;作为数据智能领域的领军者&#xff0c;以其前沿的技术与创新的产品&#xff0c;为企业开启了高效数据分析…

C++11编译器优化以及引用折叠

1.左值与右值的意义 1.左值引用和右值引用最终目的是减少拷贝&#xff0c;提高效率 2.左值引用还可以修改参数/返回值 左值引用不足&#xff1a; 部分函数放回场景&#xff0c;只能传值返回&#xff0c;不能引用左值返回 当前函数局部对象&#xff0c;出了当前函数作用域生…

小程序学习06——uniapp组件常规引入和easycom引入语法

目录 一 组件注册 1.1 组件全局注册 1.2 组件全局引入 1.3 组件局部引入 页面引入组件方式 1.3.1 传统vue规范&#xff1a; 1.3.2 通过uni-app的easycom 二 组件的类型 2.1 基础组件列表 一 组件注册 1.1 组件全局注册 &#xff08;a&#xff09;新建compoents文件…

【时时三省】(C语言基础)常见的动态内存错误2

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 对非动态开辟空间内存使用free释放 示例&#xff1a; 这个arr数组是在栈上的 *p指向的就是arr 对非动态空间也用了free ferr只能在动态开辟空间使用 使用free释放一块动态开辟空间的一部分…

3D高斯点云CUDA版本数据制作与demo运行

0. 简介 关于UCloud(优刻得)旗下的compshare算力共享平台 UCloud(优刻得)是中国知名的中立云计算服务商&#xff0c;科创板上市&#xff0c;中国云计算第一股。 Compshare GPU算力平台隶属于UCloud&#xff0c;专注于提供高性价4090算力资源&#xff0c;配备独立IP&#xff0c;…

【游戏设计原理】46 - 魔杖

幻想&#xff0c;人们可以通过多种形式来引发&#xff0c;比如文字&#xff0c;图片&#xff0c;绘画&#xff0c;语言等&#xff0c;但游戏与以上这些形式的区别&#xff0c;正如游戏与其他艺术形式的区别一样&#xff0c;游戏作为一种艺术和娱乐形式&#xff0c;其独特之处在…

基于Java的敬老院管理系统的设计和实现【源码+文档+部署讲解】

基于Java的敬老院管理系统设计和实现 摘 要 新世纪以来,互联网与计算机技术的快速发展,我国也迈进网络化、集成化的信息大数据时代。对于大众而言,单机应用早已成为过去&#xff0c;传统模式早已满足不了当下办公生活等多种领域的需求,在一台电脑上不联网的软件少之又少&#x…

Git快速入门(一)·Git软件的安装以及GitHubDesktop客户端的安装

目录 1. 概述 1.1 版本控制介绍 1.1.1 集中式版本控制 1.1.2 分布式版本控制 1.1.3 多人协作开发 2. 安装Git 3. 安装GitHubDesktop客户端 1. 概述 Git 是一个免费的、开源的分布式版本控制系统。它能够快速高效地处理从小型到大型的各种项目。Git 具有易于学习…

数据挖掘——神经网络分类

神经网络分类 神经网络分类人工神经网络多层人工神经网络 误差反向传播&#xff08;BP&#xff09;网络后向传播算法 神经网络分类 人工神经网络 人工神经网络主要由大量的神经元以及它们之间的有向连接构成。包含三个方面&#xff1a; 神经元的激活规则 主要是指神经元输入…

PDF文件提示-文档无法打印-的解决办法

背景信息 下载了几个签名的PDF文件&#xff0c;想要打印纸质版&#xff0c;结果打印时 Adobe Acrobat Reader 提示【文档无法打印】: 解决办法 网上的方案是使用老版本的PDF阅读器&#xff0c; 因为无法打印只是一个标识而已。 PDF文件不能打印的五种解决方案-zhihu 这些方…

docker容器间基于bridge双向通信

前面介绍了通过link实现容器间的单向通信&#xff1a; docker容器间基于Link单向通信-CSDN博客 情景概述 通过前面已经知道了设置link来达到容器间通过容器名称双向通信&#xff0c;那是不是可以通过每个容器都设置link来达到双向通信&#xff0c;这种方式实现起来太麻烦&…

前端如何判断多个请求完毕

在前端开发中&#xff0c;经常会遇到需要同时发起多个异步请求&#xff0c;并在所有请求都完成后再进行下一步操作的情况。 这里有几个常用的方法来实现这一需求&#xff1a; 使用 Promise.all() Promise.all() 方法接收一个 Promise 对象的数组作为参数&#xff0c;当所有的…

云备份项目--服务端编写

文章目录 7. 数据管理模块7.1 如何设计7.2 完整的类 8. 热点管理8.1 如何设计8.2 完整的类 9. 业务处理模块9.1 如何设计9.2 完整的类9.3 测试9.3.1 测试展示功能 完整的代码–gitee链接 7. 数据管理模块 TODO: 读写锁&#xff1f;普通锁&#xff1f; 7.1 如何设计 需要管理…

exam0-试卷整理

exam0-试卷整理 2010&#xff0c;2013是梦开始的地方&#xff0c;大概率会出原题的 2010 2013 2015 大题 manchester RIP更新 说出ISO与TCP/IP模型的相同点和不同点&#xff08;8分&#xff09; 相似&#xff1a; 两者都有层次&#xff0c;网络专业人员都需要知道二者&a…

ACL---访问控制列表---策略

在路由器流量流入或者流出的接口上匹配流量&#xff0c;之后执行设定好的动作---permit&#xff08;允许&#xff09;deny&#xff08;拒绝&#xff09; 1.访问控制&#xff1a; 在路由器流量流入或者流出的接口上匹配流量&#xff0c;之后执行设定好的动作---permit&#xf…

element输入框及表单元素自定义前缀

如图所示&#xff1a; <el-input class"custom-input" placeholder"请输入" prefix-icon"prefix" v-model"form.name" clearable></el-input> :deep(.custom-input) {.el-input__icon {display: inline-block;width: 40…