在C语言中,定义常量的方法有哪几种?

news/2025/10/24 22:37:04/文章来源:https://www.cnblogs.com/wangya216/p/19164357

在C语言中,定义常量的方法主要有以下3种:

一、#define 预处理指令(宏定义)

通过预处理指令将符号替换为指定文本,是最基础的常量定义方式。

语法:

#define 常量名 常量值  // 无分号,预处理阶段会直接替换

示例:

#define PI 3.1415926  // 数值常量
#define MAX_LEN 100   // 整数常量
#define MSG "hello"   // 字符串常量

特点:

  • 无类型:仅做文本替换,不进行类型检查,可能因类型不匹配引发隐蔽错误(如#define NUM 3.5被当作整数使用)。
  • 作用域:从定义处到文件结束,可通过#undef 常量名提前终止。
  • 灵活性:支持表达式(需注意加括号避免优先级问题,如#define MUL(a,b) ((a)*(b)))。

适用场景:

全局通用的常量(如数学常数、数组大小)、预处理阶段需要替换的场景(如条件编译#if MAX_LEN > 50)。

二、const 关键字(常变量)

定义“只读变量”,分配内存但限制修改,编译时会进行类型检查。

语法:

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

示例:

const float pi = 3.14;       // 浮点型常变量
const int arr_size = 20;     // 整型常变量
const char* str = "test";    // 字符串指针(指针本身不可改,指向的内容可改)

特点:

  • 有类型:编译器会检查类型匹配(如const int a=5; float b=a;会警告类型转换)。
  • 本质是变量:占用内存(存储在数据段),可通过指针间接修改(不推荐,破坏常量性)。
  • 作用域:遵循变量规则(局部const仅在函数内有效,全局const在文件内有效)。

注意:

C语言中const是“常变量”,而非编译期常量。例如C89标准中,不能用const int n=5; int arr[n];(C99支持变长数组VLA除外)。

适用场景:

需要类型检查的常量、局部范围的常量(如函数内临时使用的固定值)、标记函数参数为“输入-only”(避免被修改)。

三、枚举(enum)与typedef enum(定义整数常量集)

枚举通过定义枚举类型,其成员本质是整数常量,适合表示一组相关的整数(如状态、选项)。而typedefenum结合可简化类型名,方便使用。

1. 基础enum定义(无typedef

语法:

enum 枚举名 {成员1,          // 默认为0成员2,          // 默认为前一个+1(即1)成员3 = 5,      // 显式赋值,后续成员从5+1=6开始成员4           // 6
};

示例:

// 定义颜色常量(默认从0开始)
enum COLOR {RED,    // 0GREEN,  // 1BLUE    // 2
};

特点:

  • 成员是整数常量,值可显式指定或自动递增(前一个+1)。
  • 声明变量时需带enum关键字:enum COLOR c = RED;(略显繁琐)。

2. typedef enum(常用写法,简化类型名)

通过typedef为枚举类型起别名,后续声明变量时可直接使用别名,无需重复enum

语法:

typedef enum 枚举名 {  // 枚举名可省略(匿名枚举)成员1,成员2,...
} 类型别名;  // 后续用“类型别名”声明变量

示例:

// 带枚举名的typedef enum
typedef enum KEY_TYPE {NO_KEY = 0xff,KEY1 = 1,KEY2,  // 2(自动递增)...
} KEY_TYPE;  // 类型别名为KEY_TYPE// 匿名枚举(省略枚举名,更简洁)
typedef enum {MON,  // 0TUE,  // 1WED   // 2
} WEEK;  // 类型别名为WEEK

使用方式:

KEY_TYPE key = KEY1;  // 直接用类型别名声明变量,无需写enum
WEEK today = MON;     // 匿名枚举的使用

特点:

  • 简化代码:避免每次声明变量都写enum,使代码更简洁(如WEEKenum WEEK更易读)。
  • 保持枚举特性:成员仍是整数常量,支持自动递增和显式赋值,且变量取值被限制在成员范围内(增强规范性)。
  • 类型关联:枚举变量与类型别名绑定,编译器会进行基础类型检查(如WEEK变量不能直接赋值为100,除非强制转换)。

适用场景:

  • 定义一组相关的整数常量(如按键类型、状态码、选项列表)。
  • 需要频繁使用该枚举类型声明变量时(typedef可减少代码冗余)。
  • 希望限制变量取值范围(避免无效值,如KEY_TYPE变量只能取NO_KEYKEY1等成员)。

三种方法的对比与选择

方法 类型检查 内存分配 适用值类型 典型场景
#define 不分配 数值、字符串、表达式 全局通用常量、宏定义
const 分配 任意类型 局部常量、需要类型检查的常量
typedef enum 弱(可转int) 不分配 整数 一组相关的整数常量(状态、选项),且需频繁声明变量

总结

  • 简单全局常量(如数值、字符串)用#define
  • 需类型检查的局部/输入常量用const
  • 一组相关整数常量(如状态、按键)且需频繁使用时,优先用typedef enum(简化声明,增强规范性)。

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

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

相关文章

docker 艹哥笔记

docker 艹哥笔记[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# [root@localhost ~]# docke…

OUC第一周WP

Misc 签到题 扫码关注,回复flag就出来了ezBase64 base64加密,解密出来flagBaseCrack 经过多次base系列加密,赛博厨子试出来 最后经过base64->base32->base64解密得到flag ROT13 rot13加密,解密得到flag Rai…

在windows 上用GPIO定义几个按键

1. ACPI button 文档ACPI 按钮设备 - Windows drivers | Microsoft Learn 2. acpi button 的acpi dochttps://uefi.org/specs/ACPI/6.6/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#button-interrupts …

第二十三篇

今天是10月24号,没上课,爽。

扩展域并查集理解性总结

扩展域并查集理解性总结纯文字内容,较短,较枯燥,但感谢你能点进来并完成阅读。 前置:并查集 扩展域并查集(种类并查集) 理解思想 一.团伙给定若干满足如下两条的关系,求会构成多少个团伙:\(x\)、\(y\) 为朋友 \(…

软件工程学习日志2025.10.24

在当今快节奏的软件开发世界中,技术硬实力是入场券,而卓越的沟通协作能力,则是决定一个工程师能走多快、多远的隐形翅膀。为了弥合校园与职场之间的能力鸿沟,我深入调研了以高效协同著称的字节跳动,并以此为镜,反…

ABP - 种子数据 [IDataSeeder、DataSeedContext]

种子数据(Seed Data) 核心辅助类:IDataSeeder:数据种子接口。 DataSeedContext:种子数据上下文。种子数据是指项目启动时自动向数据库插入的初始化数据(比如默认管理员账号、基础配置项、测试数据等),核心作用…

[KaibaMath]1014 基于取整函数[x]的定义求解一道特殊的一元二次方程

[KaibaMath]1014 基于取整函数[x]的定义求解一道特殊的一元二次方程取整函数[x]的定义是[x]≤x<[x]+1. 下面基于运用此定义,求解一道特殊的一元二次方程:x^2-2[x]+0.9=0.

基础题目

超级基础的题虽然是数学,但是仍以 \(OI\) 的题为例,毕竟 \(OI\) 的组合计数题还是很高质的,但别担心,组合计数主要是数学推导,所以文中的题仅会推导数学的理论知识或公式,不会有代码实现。但为了方便,还是会把题…

完整教程:紫外UV相机在机器视觉检测方向的应用

完整教程:紫外UV相机在机器视觉检测方向的应用pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

三种 Badcase 精度验证方案详解与 hbm_infer 部署实录

在模型结构优化与部署量化过程中,开发者往往会遇到一个关键任务:​基于历史 Badcase 数据验证模型精度变化​,确保模型修改不会引入明显性能退化。 这类验证常见于感知、预测、行为识别等任务,尤其在客户交付或精度…

CF512E. Cycling City

题目传送门 十分有趣的题。 思路 三条路径,本质上其实就是 \(x,y\) 同时属于两个有交集(至少交一条边)的简单环,这个肯定没问题。 套路的跑一遍 dfs,然后就有了返祖边树边和横叉边,然后朴素的分讨然后用个数据结…

ABP - 事件总线(Event Bus)[IEventBus、LocalEventBus、IntegrationEvent]

(1)事件总线(Event Bus) 核心辅助类:IEventBus:发布/订阅事件。 LocalEventBus:本地事件总线(进程内)。 IntegrationEvent:跨服务集成事件。事件总线是一种“发布-订阅”模式的通信机制,用于解耦系统中的各…

【ArcMap】基本操作1:查看属性表Table、测量路线长度、打断点

1.查看 a.查看线段信息b.查看属性表Table c.查看坐标点 2.测量路线长度-简单 3.打断点 4.画线

CSP-S模拟37

T1:回文(string) 思路: 由于本题的数据范围较小,所以可能有多种 \(dp\) 状态,这里只呈现其中可能较典的两种外加一种暴搜最优解。 DP1: 我们设 \(f_{i,j,x,y}\) 表示使用 \(a\) 串的 \(i\) ~ \(j\) 和 \(b\) 串…

Google Skills免费开放啦

Google Skills免费开放啦家人们,AI圈的大事来啦!Google搞了个大动作,直接把内部的AI学习资源打包成“Google Skills”平台,向全球开放!这波操作直接把AI学习的门槛拉到超低,普通人也能轻松上车!免费用户直接用G…

ABP - 缓存(Caching)[IDistributedCache、ICacheManager、ICacheKeyNormalizer、[Cache]、[CacheInvalidate]]

(一)缓存(Caching) 核心辅助类:IDistributedCache:分布式缓存(基于Redis等)。 ICacheManager:缓存管理器(支持多级缓存)。 [Cache]:方法缓存特性。 ICacheKeyNormalizer:缓存键标准化器,自动添加租户前缀…

好想成为人类啊——2025 . 10 . 24

好想成为人类啊。 今天应该是比较著名的程序员节,貌似大家都在庆祝。但我其实没啥感觉,因为我的理想并不是成为一个程序员。 那我的理想是什么呢,也好像并没有什么理想,可能跟艺术方面沾点儿边吧,当然,这怎么看都…

10 24(+第14场补题)

14.3维护 \(cur\), \(ans\) , \(dif = cur - ans\) 。 每次执行 \(cur = cur + a_i, \quad dif = dif + a_i\)。如果 \(cur < 0\),则 \(dif -= cur, \quad cur = 0\)。 如果 \(dif > 0\),则 \(dif = 0\)。考虑…