C语言字面量和常量
目录
引言
1. 字面量
1.1 字符字面量
1.2 整型字面量
1.3 浮点字面量
2. 常量
2.1 使用预处理器指令 #define 定义常量
2.1.1 语法格式
2.1.2 使用举例
2.2 使用 const 关键字定义常量
2.3 使用 #define 和 const 定义常量的区别
引言
看了一些博文,有的文章对字面量和常量区别的不是很明显,个人观点以下对字面量和常量的定义是比较准确的。
字面量是直接在代码中使用的程序运行期间不会改变的没有名字的固定值。所以我们只能用字面量来称呼它,故叫字面量。
常量是用预处理器指令 #define 或 const 关键字定义的在程序运行期间不会改变的在代码中有名字的固定值。
1. 字面量
int i = 100;
像上面语句中的数字 100,这种在程序中不能修改的无法用名字称呼它的字面值常量,叫做字面量。比如 printf("Hello World\n"); 中的 "Hello World\n" 也是字面量。
1.1 字符字面量
在 ASCII 码表中,编码 [0, 31] 和 127 是控制字符,共 33 个字符是不可以打印的,其中编码 [0, 31] 这 32 个字符主要用于控制打印机等外围设备。
编码 [32, 126] 是可显示字符,也就是可以打印在屏幕上。记得以下几个编码规则,在 C语言对字符进行操作的时候,或许挺管用。
- 大写字母 A ~ Z 的 ASCII码 65 ~ 90
- 小写字母 a ~ z 的 ASCII码 97 ~ 122
- 大写字母比小写字母的 ASCII码小 32 (0b00100000,0x20) ,比如: char c = 'a',小写字母变大写字母,c = c - 32 得到,也可以做位与操作,c = c & 0b11011111 得到
- 数字字符 0 ~ 9 的 ASCII码 48 ~ 57,所以一个数字要转换成数字字符,只要将数字 加上 48 (0x30) 即可
- 字符串的终止符为 '\0',ASCII 码为 0
- 换行符 '\n' 的 ASCII码为 10 (0x0A)
对于这些字符字面量,有4种书写格式
1) 用一对单引号把字符括起来(推荐使用)
#include <stdio.h>int main() {char c1 = 'A';printf("%c\n", c1); // Areturn 0;
}
对于不可打印字符和特殊字符,用转义字符书写。
| \n | 换行符 | \t | 水平制表符 |
| \v | 纵向制表符 | \b | 退格符 |
| \r | 回车符 | \f | 换页符 |
| \a | 报警响铃符 | \\ | 反斜杠 |
| \" | 双引号 | \' | 单引号 |
#include <stdio.h>int main() {char c1 = '\\';printf("%c\n", c1);return 0;
}

2) 用编码数值书写
#include <stdio.h>int main() {char c1 = 65; // 十进制,大写字母 A 的ASCII码:65char c2 = 0101; // 八进制char c3 = 0x41; // 十六进制printf("%c,%c,%c\n", c1, c2, c3); // A,A,Areturn 0;
}
3) 对于任何字符,还可以用通用的转义字符书写
- \ooo,其中 ooo 表示三个八进制数字,注意是三个八进制数字,比如即使是编码为 1 的字符,也不能省掉前面那两个0。
- \xhh,其中 x 表示十六进制,hh 是二个十六进制数字
#include <stdio.h>int main() {char c1 = '\x41'; // 十六进制char c2 = '\101'; // 是3位八进制数字,即使编码为 1 的字符,也要写成 '\001',不能写成 '\1'printf("%c,%c", c1, c2); // A,Areturn 0;
}
1.2 整型字面量
整型字面量可以用十进制、八进制、十六进制或二进制来表示。
- 以 0x 或 0X 开头表示十六进制
- 以数字 0 开头表示八进制
- 以 0b 开头表示二进制
- 不带前缀默认是十进制
以下表示同一个整型字面量
15 // 十进制
017 // 八进制
0xf // 十六进制
0b00001111 // 二进制
#include <stdio.h>int main() {int i1 = 15;int i2 = 017;int i3 = 0xf;int i4 = 0b00001111;printf("%d, %d, %d, %d\n", i1, i2, i3, i4);return 0;
}

整型字面量还可以带一个由 U 和 L 组合的后缀,U 和 L 不分先后顺序,U 可以大写也可以小写 u,是 unsigned 的意思,L 可以大写也可以小写 l,是 long 的意思。
15u // 无符号整型字面量
15L // 长整形字面量,推荐用大写 L,因为小写字面 l 和数字 1 很容易混淆
15ul // 无符号长整形字面量
0xfu // 无符号整型字面量
0xfL // 长整形字面量
0xful // 无符号长整型字面量
017u // 无符号整型字面量
017L // 长整形字面量
017ul // 无符号长整型字面量
// limits.h 文件中,int, unsigned int, long, unsigned int 取值范围定义
#define INT_MIN (-2147483647 - 1)
#define INT_MAX 2147483647
#define UINT_MAX 0xffffffff
#define LONG_MIN (-2147483647L - 1)
#define LONG_MAX 2147483647L
#define ULONG_MAX 0xffffffffUL
#include <stdio.h>
#include <limits.h>int main() {unsigned int uiVar = 15u;long longVar = 15L;unsigned long ulVar = 15ul;printf("%u\n", uiVar); // %u 无符号整型格式化输出printf("%d\n", longVar); // %d 以十进制格式化输出有符号整数(在 limits.h 中有定义: long 和 int 的取值范围是一样的)printf("%lu\n", ulVar); // %lu 以无符号长整型格式化输出uiVar = 0xfu;longVar = 0xfL;ulVar = 0xful;printf("%u\n", uiVar); // %u 无符号整型格式化输出printf("%d\n", longVar); // %d 以十进制格式化输出有符号整数(在 limits.h 中有定义: long 和 int 的取值范围是一样的)printf("%lu\n", ulVar); // %lu 以无符号长整型格式化输出uiVar = 017u;longVar = 017L;ulVar = 017ul;printf("%u\n", uiVar); // %u 无符号整型格式化输出printf("%d\n", longVar); // %d 以十进制格式化输出有符号整数(在 limits.h 中有定义: long 和 int 的取值范围是一样的)printf("%lu\n", ulVar); // %lu 以无符号长整型格式化输出return 0;
}

注意:
018 是不对的整型字面量,因为八进制没有数码 8
15uu 是不对的整型字面量,后缀 u 不能重复
15Lu 是正确的整型字面量,跟 15uL表达的是同一个字面量,u和l组合时,不分先后顺序
1.3 浮点字面量
通常用十进制或科学计数法来表示浮点字面量。
- 默认浮点字面量为 double 类型,比如:3.14
- 在数值后面加上后缀 f 或 F 表示 float 类型,比如:3.14f 或 3.14F
- 0 的 double 类型表示为 0. ;0 的 float 类型表示为 0.f 或 0.F
- 对于只有小数部分的浮点字面量,整数部分的 0 可以省略掉不写,比如:.01 等价于 0.01;.01f 等价于 0.01f
- 使用科学计数法时,指数用 e 或 E 表示。比如:3.14e0 或 3.14E0 表示的是 double 类型 3.14;而 3.14e0f 或 3.14E0F 表示的是 float 类型 3.14f
- double 类型 0 用科学计数法表示为 0e0,float 类型 0 用科学计数法表示为 0e0f
#include <stdio.h>int main() {printf("%d, %d\n", sizeof(.01), sizeof(0.01)); // 8, 8printf("%d, %d\n", sizeof(.01f), sizeof(0.01f)); // 4, 4printf("%.2f, %.2f\n", .01, 0.01); // 0.01, 0.01printf("%d, %d\n", sizeof(0.), sizeof(0.f)); // 8, 4printf("%d\n", sizeof(3.14)); // 8printf("%d, %d\n", sizeof(3.14f), sizeof(3.14F)); // 4, 4printf("%d, %d\n", sizeof(3.14e0), sizeof(3.14E0)); // 8, 8printf("%d, %d\n", sizeof(3.14e0f), sizeof(3.14E0F)); // 4, 4printf("%d, %d\n", sizeof(0e0), sizeof(0e0f)); // 8, 4return 0;
}

1.4 字符串字面量
字符串字面量用一对双引号把所有的字符括在里面,比如:"Hello World\n"
- 字符串字面量在内存中编译器会自动在末尾加上一个字符串终止符('\0'),所以字符串在内存中占用的字节数会比字符串的长度多1字节。
- 两个相邻的仅由空格、制表符('\t') 或 换行符('\n') 分开的字符串字面量,可以连接成一个新的字符串字面量。
- 一个字符串过长,在一行放不下时,可以使用反斜杠 ('\') 进行换行。
- 空字符串 "" 在内存在占一个字节,这个字节存的是字符串终止符('\0')。
#include <stdio.h>int main() {printf("Hello World\n"); printf("Hello" " world\n"); // 两个字符串字面量连接成一个新的字符串 "Hello World\n"printf("Hello \
World\n"); // 用 '\' 换行printf("%d\n", sizeof("")); // 1return 0;
}

2. 常量
常量是用预处理器指令 #define 或 const 关键字定义的在程序运行期间不会改变的在代码中有名字的固定值。
2.1 使用预处理器指令 #define 定义常量
2.1.1 语法格式
#define 常量名 常量值
// 以下代码定义了一个名为 PI 的常量
#define PI 3.14
2.1.2 使用举例
#include <stdio.h>#define PI 3.14// 圆周长
double circumference(const double r) {return 2 * PI * r; // 使用了预处理器指令 #define 定义的常量 PI
}int main() {printf("半径为 %.2f 的圆周长 = %.2f\n", 2.0, circumference(2.0));return 0;
}
2.2 使用 const 关键字定义常量
2.2.1 语法格式
const 常量类型 常量名 = 常量值;
// 以下代码定义了一个名为 PI 的常量
const double PI = 3.14;
2.2.2 使用举例
#include <stdio.h>const double PI = 3.14;// 圆周长
double circumference(const double r) {return 2 * PI * r; // 使用了用 const 关键字定义的常量 PI
}int main() {printf("半径为 %.2f 的圆周长 = %.2f\n", 2.0, circumference(2.0));return 0;
}
注意:用 const 关键字定义的常量,必须同时它进行初始化
/*
// 以下对定义常量 MAX 是错误的,因为常量必须在定义的时同时对它进行初始化,初始化后的常量是不能改变的
const int MAX;
MAX = 100;
*/
// 正确用 const 定义 MAX 常量的方法
const int MAX = 100;
2.3 使用 #define 和 const 定义常量的区别
- 1. 编译器处理方式不同
- 使用 #define 定义的常量会在预处理阶段用它对应的字面量替换掉代码中的常量字符标识,在程序运行期间内存中并不存在该常量。
- 使用 const 定义的常量是具有数据类型和作用域的常量,在程序运行期间内存中是存在该常量的符号标识的
-
2. 类型和安全检查不同
-
使用 #define 定义的常量不存在数据类型,从而在编译阶段,编译器不会对它进行类型检查
-
使用 const 定义的常量是具有数据类型的,在编译阶段,编译器会对它进行类型检查
-
3. 作用域检查不同
-
使用 #define 定义的常量没有作用域,它在定义之后的整个代码中都有效
-
使用 const 定义的常量具有作用域,只有在它所在的作用域内有效
-
4. 存储方式不同
-
使用 #define 定义的常量在符号表中不会有相应的条目。
-
使用 const 定义的常量会在符号表中有相应的条目,有助于调试和可读性。
使用 #define 与 const 这两种方式都可以用来定义常量,通常情况下,建议使用 const 关键字来定义常量,因为通过 const 关键字定义的常量,具有数据类型和作用域,编译器可以对它进行类型检测和作用域检查,而用 #define 定义的常量,仅在预编译阶段进行简单的文本替换,可能会导致一些没有预料到的问题。
相关文章:
C语言字面量和常量
目录 引言 1. 字面量 1.1 字符字面量 1.2 整型字面量 1.3 浮点字面量 2. 常量 2.1 使用预处理器指令 #define 定义常量 2.1.1 语法格式 2.1.2 使用举例 2.2 使用 const 关键字定义常量 2.3 使用 #define 和 const 定义常量的区别 引言 看了一些博文,有的文…...
视频结构化从入门到精通——行为分析类应用
行为分析类应用 1. 认识行为分析 监控/判断视频画面中目标的运动过程、携带属性等。从数据中自动识别、跟踪和理解人类或物体行为。 1. 车的行为分析应用 车辆行为分析主要用于监控和管理车辆的动态行为,广泛应用于智能交通、城市管理和安全监控。关键应用包括&…...
Redis的KeyExpirationEventMessageListener键过期监听器
MessageListener通过监听key过期的Redis keyspace通知,然后通过ApplicationEventPublisher发布RedisKeyExpiredEvent事件的模式进行事件监听和广播。 redis.conf地址:https://github.com/redis/redis/blob/unstable/redis.conf Redis官方地址࿱…...
MP4视频压缩,推荐这五大压缩操作
MP4视频压缩,在当今数字化的时代,视频已经成为我们日常生活和工作中不可或缺的一部分。然而,随着视频分辨率和长度的增加,MP4文件的大小也变得越来越大,这不仅占用了大量的存储空间,还使得传输和分享变得困…...
docker 安装NextERP
有很多方式: 一 docker sudo docker run -itd -p 8016:80 -v ERPNext_db:/var/lib/mysql -v ERPNext_sites:/home/frappe/frappe-bench/sites --name ERPNext lvxj11/erpnext:latest二 git clone https://e.coding.net/yuanerp/yuanerp/frappe_docker.gitcp exa…...
Android 存储之 SharedPreferences 框架体系编码模板
一、SharedPreferences 框架体系 1、SharedPreferences 基本介绍 SharedPreferences 是 Android 的一个轻量级存储工具,它采用 key - value 的键值对方式进行存储 它允许保存和读取应用中的基本数据类型,例如,String、int、float、boolean …...
弹性容器Flex中的自动外边距(Auto Margins) 的作用
最近在使用Flex布局时,遇到的一个情况: 有以下的代码: <div class"toolbox"><button id"decrease">-</button><span id"size">1</span><button id"increase">…...
C语言调用子函数时入/出栈(保护/恢复现场)全过程分析:以Cortex-M3为例
0 参考资料&工具 Cortex M3权威指南(中文).pdf keil5(用于仿真查看寄存器、栈变化)1 C语言调用子函数时出入/出栈(保护/恢复现场)全过程分析 使用C语言调用子函数是如何保护/恢复现场的呢?本文以Cortex-M3为例&a…...
理解Sigmoid激活函数原理和实现
Sigmoid 激活函数是一种广泛应用于机器学习和深度学习中的非线性函数,特别是在二分类问题中。它的作用是将一个实数值映射到(0, 1)区间,使得输出可以被解释为概率值,这在处理二分类问题时非常有用。 Sigmoid 函数的定义 Sigmoid 函数的数学…...
探秘DevSecOps黄金管道,安全与效率的完美融合
软件应用的安全性已成为企业和用户关注的焦点,DevSecOps作为一种将安全融入开发和运维全过程的理念和实践,旨在消除传统开发模式中安全被后置处理的弊端。DevSecOps黄金管道(Golden Pipeline)是实现这一理念的核心框架,…...
Redis的内存淘汰策略- volatile-lru
volatile-lru 策略简介 在 volatile-lru 策略下,当 Redis 的内存使用达到配置的上限(maxmemory)时,它会优先删除那些设置了过期时间的键,并且选择最近最少使用的键进行删除。LRU 算法的核心思想是,优先删除…...
HTTP和HTTPS的区别?哪一个更适合你的网站?
什么是 HTTP? HTTP(超文本传输协议)(Hypertext Transfer Protocol)它是一组允许网络浏览器与网络服务器(托管网站的计算机)进行通信的规则。 HTTP 使用请求-响应模型。 例如,当你…...
OpenAI SORA团队负责人 通往智能的方式 报告笔记
OpenAI SORA团队负责人 通往智能的方式 报告笔记 这个报告其实是2024年智源大会的主旨报告,OpenAI SORA和DALL-E团队负责人Aditya Ramesh给出的一段有关多模态大模型的报告。我去听了现场,感觉倍受启发,但是感觉很多并不能当场理解ÿ…...
006-Sleuth(Micrometer)+ZipKin分布式链路追踪
这里写目录标题 1 分布式链路追踪概述1.1 为什么会出现这个技术?需要解决哪些问题?1.2 在分布式与微服务场景下需要解决的问题 2 新一代Spring Cloud Sleuth:Micrometer2.1 官网重要提示2.1.1 新一代Sleuth2.1.2 官网2.1.3 说明2.1.3.1 老项目…...
AI模型:追求全能还是专精?-- 之6 语言复杂度类别(Category 0~3 类)和语言功能性类型(Type 0~Ⅲ 型)之2
Q17、我前面说过,语言复杂度的0~3级(Category 0~3)表示了语言的的上下文相关性 : 完全不相关, 单相关的 单词上下文, 双相关的句子上下文 全相关的文章上下文 。我准备翻译为 Context - irrelative /relati…...
20240907 每日AI必读资讯
大疆发布 DJI Neo 掌上 Vlog 无人机! - DJI Neo 是 DJI 迄今最轻、最小的无人机,无需遥控器,掌上起降即可轻松拍出主角大片… |135 克轻巧便携 丨零门槛掌上起降 丨AI 智能跟拍 ,一键成片 丨多种操控,丰富…...
深度学习基础--卷积基础模块
本节主要关注卷积神经网络发展过程中具有里程碑意义的基础模块,了解它们的原理和设计细节 1. 批归一化 在机器学习中,一般会假设模型的输入数据的分布是稳定的。如果这个假设不成立,即模型输入数据的分布发生变化,则称为协变量偏…...
视频智能分析打手机检测算法安防监控打手机检测算法应用场景、算法源码、算法模型介绍
随着智能手机的普及,手机已成为人们生活中不可或缺的一部分。然而,在某些场合,如驾驶、会议、学校课堂等,不当使用手机可能会导致安全隐患或干扰他人。因此,开发出一种能够准确识别并阻止不当使用手机的行为检测算法显…...
6.2图的存储及基本操作
6.2.1顺序存储 邻接矩阵法,用一个一维数组存储图中顶点信息,二维数组存储图中边的信息 无向图 1.无向图的邻接矩阵关于对角线对称,可采用压缩存储 2.边数为e,则邻接矩阵中1为2e; 3.第i行or 第i列非零元素之和恰好为顶点i的度数 4.判断是否有边用0,1 5. 有向图 1.关于对…...
Java语法全解析:掌握基本规则,打造稳固编程基础!
Java基本语法是编写Java程序的核心,它包括了数据类型、运算符、控制结构、类与对象等基本组成部分。这些语法要素共同构成了Java程序的基础框架,掌握它们是进行Java编程的前提。以下是Java基本语法的详细介绍: 数据类型 基本数据类型&#x…...
猫抓浏览器扩展:新手也能掌握的网页资源嗅探终极指南
猫抓浏览器扩展:新手也能掌握的网页资源嗅探终极指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否曾经在浏览网页时ÿ…...
STM32CubeHAL 多外设仿真实战 | Proteus 8.15 驱动整合与调试技巧(LCD/OLED/温湿度/舵机/蜂鸣器)
1. 工程环境搭建与工具准备 第一次用Proteus仿真STM32时,我踩过一个坑:明明CubeMX生成的代码在开发板上运行正常,但仿真时外设死活不工作。后来发现是Proteus版本太旧,根本不支持HAL库模型。这里分享下经过验证的黄金组合…...
[技术突破] 移动高精度定位新纪元:Android平台RTKLIB解决方案全解析
[技术突破] 移动高精度定位新纪元:Android平台RTKLIB解决方案全解析 【免费下载链接】RtkGps Playing with rtklib on android 项目地址: https://gitcode.com/gh_mirrors/rt/RtkGps 技术原理篇:核心算法与协议支持 解锁厘米级定位:R…...
新手友好:借助快马AI生成代码,零基础入门谷歌浏览器扩展开发
最近想尝试开发一个简单的谷歌浏览器扩展,但作为新手完全不知道从何入手。经过一番摸索,我发现用InsCode(快马)平台可以快速生成可运行的示例代码,特别适合零基础学习。下面记录下我的学习过程,希望能帮到同样想入门浏览器扩展开发…...
HTML转Figma工具革新:从网页到设计稿的无缝转换技术指南
HTML转Figma工具革新:从网页到设计稿的无缝转换技术指南 【免费下载链接】figma-html Convert any website to editable Figma designs 项目地址: https://gitcode.com/gh_mirrors/fi/figma-html 一、价值定位:为什么HTML转Figma是设计开发协作的…...
2025_NIPS_Spatial-Aware Decision-Making with Ring Attractors in Reinforcement Learning Systems
文章核心总结与翻译 一、主要内容 文章提出将受神经回路动力学启发的环形吸引子(Ring Attractors)整合到强化学习(RL)系统中,以解决空间结构化环境中的高效动作选择问题。通过构建外源性连续时间循环神经网络(CTRNN)模型和内源性深度学习(DL)模块两种实现方式,环形…...
深度探索Demucs:混合Transformer架构在音乐源分离中的实战应用
深度探索Demucs:混合Transformer架构在音乐源分离中的实战应用 【免费下载链接】demucs Code for the paper Hybrid Spectrogram and Waveform Source Separation 项目地址: https://gitcode.com/gh_mirrors/de/demucs Demucs是一个基于混合Transformer架构的…...
新手程序员必看:7类常见错误与高效解决方案
1. 新手程序员常犯的7类错误及解决方案作为一名带过5届应届生的技术导师,我发现每一批新人都会重复踩同样的坑。最近带的这位应届生让我想起了自己刚入行时的样子——充满热情但缺乏方法。下面这些经验教训,都是我亲自踩过坑后总结出来的实战心得。提示&…...
Python实战:如何用多线程加速破解ZIP/RAR密码(附完整代码)
Python多线程密码破解实战:从原理到性能优化 在数据恢复和渗透测试领域,密码保护的压缩文件处理是常见需求。当我们面对遗忘密码的ZIP/RAR文件时,Python提供了高效的解决方案。本文将深入探讨如何利用多线程技术显著提升密码破解效率…...
浏览器超能力开发指南:解锁Greasy Fork用户脚本的实战手册
浏览器超能力开发指南:解锁Greasy Fork用户脚本的实战手册 【免费下载链接】greasyfork An online repository of user scripts. 项目地址: https://gitcode.com/gh_mirrors/gr/greasyfork 在数字化工作流中,我们每天都在重复着大量机械操作——手…...
