首页/新闻资讯/正文详情

sizeof(‘a‘) 是 4 还是 1?C语言里单引号和双引号

发布时间:2026/9/24 17:39:22 来源:云帆数科 栏目:资讯中心
sizeof(‘a‘) 是 4 还是 1?C语言里单引号和双引号
参考参考Andrew Koenig《C 陷阱与缺陷第二版》1.5节目录书上结论sizeof混用——出现错误巨坑——printf(\n)yes 和 yes译注书上结论1.5 节开头就把结论摆出来了C 语言中的单引号与双引号含义迥异在某些情况下如果把两者弄混编译器并不会检测报错从而在运行时产生难以预料的结果。然后给了两句定义用单引号引起的一个字符实际上代表一个整数整数值对应于该字符在编译器采用的字符集中的序列值。因此对于采用 ASCII 字符集的编译器而言a的含义与 0141八进制或者 97十进制严格一致。用双引号引起的字符串代表的却是一个指向无名数组起始字符的指针该数组被双引号之间的字符以及一个额外的二进制值为零的字符\0初始化。接着给了个等价写法。这两段是同一件事#include stdio.h int main() { printf(Hello world\n); /* 等价于 */ char hello[] { H, e, l, l, o, , w, o, r, l, d, \n, 0 }; printf(hello); return 0; }数组末尾那个0——就是书里说的额外的二进制值为零的字符。字符串字面量比它看起来的长度多一个字节。也就是单引号包的是值双引号包的是地址。sizeofcpp#include stdio.h int main() { printf(sizeof(a) %u\n, (unsigned)sizeof(a)); printf(sizeof(\a\) %u\n, (unsigned)sizeof(a)); printf(sizeof(char) %u\n, (unsigned)sizeof(char)); printf(sizeof(int) %u\n, (unsigned)sizeof(int)); printf(sizeof(yes) %u\n, (unsigned)sizeof(yes)); printf(sizeof(\yes\) %u\n, (unsigned)sizeof(yes)); return 0; }c#include stdio.h int main() { printf(sizeof(a) %u\n, (unsigned)sizeof(a)); printf(sizeof(\a\) %u\n, (unsigned)sizeof(a)); printf(sizeof(char) %u\n, (unsigned)sizeof(char)); printf(sizeof(int) %u\n, (unsigned)sizeof(int)); printf(sizeof(yes) %u\n, (unsigned)sizeof(yes)); printf(sizeof(\yes\) %u\n, (unsigned)sizeof(yes)); return 0; }有趣的是两种语言下运行结果并不完全相同c:sizeof(a) 4 sizeof(a) 2 sizeof(char) 1 sizeof(int) 4 sizeof(yes) 4 sizeof(yes) 4cpp:sizeof(a) 1 sizeof(a) 2 sizeof(char) 1 sizeof(int) 4 sizeof(yes) 4 sizeof(yes) 4sizeof(a) 2好理解一个a加一个\0。sizeof(yes) 4 , 同理sizeof(a) 4就怪了。它只说明一件事C 里字符常量的类型是int不是char。书里那句实际上代表一个整数是字面意思不是修辞。那.cpp为什么给 1因为 C 把这条规则改了——C 里字符常量的类型就是char。是两种语言的规则不同。混用——出现错误书里接着往下推因为用单引号括起的一个字符代表一个整数而用双引号括起的一个字符代表一个指针如果两者混用那么编译器的类型检查功能将会检测到这样的错误。例如char* slash ‘/’在编译时将会生成一条错误消息因为/并不是一个字符指针。页底部那条译注说现在的编译器一般能够检测到在函数调用时混用单引号和双引号的情形——确实检测到了。但检测到和拦住是两件事一边是 warning一边是 error中间隔着一个能正常生成的 exe。巨坑——printf(\n)书里紧接着的那段然而某些 C 编译器对函数参数并不进行类型检查特别是对 printf 函数的参数。因此如果用printf(\n);来代替正确的printf(\n);则会在程序运行的时候产生难以预料的错误而不会给出编译器诊断信息。printf(\n)传给 printf 的第一个参数是整数 10printf 拿它当字符串指针用去读地址0x0A。这里和书上有个小出入VS 2022 是会给诊断的而且是两条C4047 C4024。但诊断归诊断它并没有拒绝编译。再看一个反面例子——同样传字符常量putchar(\n)用/W4编译零警告运行正常putchar(\n)同一个字符常量传给printf是要命的指针传给putchar是完美正确的int。决定的不在单引号在被调函数期待的是值还是地址。yes和yes书里第三段讲多字符常量整型数一般为 16 位或 32 位的存储空间可以容纳多个字符一般为 8 位因此有的 C 编译器允许在一个字符常量以及字符串常量中包括多个字符。也就是说用yes代替yes不会被该编译器检测到。后者即yes的含义是依次包含y、e、s以及空字符\0的 4 个连续内存单元的首地址。前者即yes的含义并没有准确地进行定义但大多数 C 编译器理解为一个整数值由y、e、s所代表的整数值按照特定编译器实现中定义的方式组合得到。因此这两者如果在数值上有什么相似之处也完全是一种巧合而已。#include stdio.h int main() { printf(a %d 0x%08X\n, a, (unsigned)a); printf(ab %d 0x%08X\n, ab, (unsigned)ab); printf(yes %d 0x%08X\n, yes, (unsigned)yes); printf(abcd %d 0x%08X\n, abcd, (unsigned)abcd); return 0; }a 97 0x00000061 ab 24930 0x00006162 yes 7955827 0x00796573 abcd 1633837924 0x61626364规律很干净y、e、s从高位往低位塞像一个左对齐的 int。字符数不影响sizeof永远是 4。顺手试abcde编译器直接拒收。最多吃 4 个字符。译注译注在 Borland C v5.5 和 LCC v3.6 中采取的做法是忽略多余的字符最后的整数值即第一个字符的整数值而在 Visual C 6.0 和 GCC v2.95 中采取的做法是依次用后一个字符覆盖前一个字符最后得到的整数值即最后一个字符的整数值。忽略多余的字符Borland / LCC 这一派的做法是只认第一个字符后面的当没看见。​按这个规则yes应该等于y也就是1210x79。这个描述是自洽的——忽略多余的所以留下的一定是第一个。忽略多余的字符这句话是最容易被读错的一句。它字面上像是在说覆盖。但这里的内容和实测有出入。真正在做的是移位累加plaintext读 y → 0x00000079 读 e → 0x00007965 旧值左移 8 位新字符进最低字节 读 s → 0x00796573 再来一次所以这句话该这么读每一个新字符进来都会把前面所有字符往前挤一个字节。覆盖指的是挤位不是丢弃。

相关推荐

15 个工作日内“删干净“一个会员:婚恋系统的注销链路比想象中难
15 个工作日内“删干净“一个会员:婚恋系统的注销链路比想象中难

副标题:网信办新规征求意见稿把注销时限写死后,我们重新梳理了婚恋系统里删除一条会员数据的完整工程链路 9 月 2 日上午,一位会员在某婚恋小程序里点了注销。三分钟后,负责牵线的红娘打开工作台,还能看到她的完整资料… · 2026/9/24 17:39:03

基于协同过滤算法的智能科教助农服务平台系统【源码+文档】
基于协同过滤算法的智能科教助农服务平台系统【源码+文档】

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台… · 2026/9/24 17:39:03

miniQMT 停用后怎么办?散户量化的数据与交易替代方案(附可运行代码)
miniQMT 停用后怎么办?散户量化的数据与交易替代方案(附可运行代码)

miniQMT 停用后怎么办?散户量化的数据与交易替代方案(附可运行代码)本文为技术路径分析。miniQMT 散户通道关停是 2026 年 9 月的事实事件,各券商节奏不一,请以你开户券商的正式通知为准。不构成投资建议。先划边界&am… · 2026/9/24 17:39:03

GTA5增强版460报错实测:驱动、DX11与虚拟内存方案对比
GTA5增强版460报错实测:驱动、DX11与虚拟内存方案对比

玩GTA5的兄弟应该都懂,最近更新“增强版”之后,论坛里冒出来一堆报错帖,最常见的一个就是“460”。这个错误在启动时突然弹出来,游戏刚看到LOGO就黑屏闪退,运气好一点能进去玩十分钟,然后画面一卡&#xff… · 2026/9/24 18:16:01

R星启动器连不上服务器报错460?4种实测修复方法详解
R星启动器连不上服务器报错460?4种实测修复方法详解

估计很多朋友碰到过这种事:游戏里刚打完一局准备回线下,或者清晨打开Steam点开始,R星启动器转两圈,直接弹出一句“无法连接Rockstar Games服务(代码460)”。我第一次遇到时也天真地以为是校园网抽风&#x… · 2026/9/24 18:16:01

AI提效实战:DeepSeek、Kimi、Cursor三款工具组合使用指南
AI提效实战:DeepSeek、Kimi、Cursor三款工具组合使用指南

每天被各类消息、文档、报表轮番轰炸,加班到八九点成了不少职场人的日常。我大概花了三周时间,把市面上能叫得出名字的AI工具挨个用了一遍,最后真正留在工作流里、每天都离不开的其实只有三款。它们不是那种“看起来很酷但用不上”的玩具&… · 2026/9/24 18:16:01

Windows 开机自动录屏 8 种方案详解:从任务计划程序到 FFmpeg 实战
Windows 开机自动录屏 8 种方案详解:从任务计划程序到 FFmpeg 实战

Windows 上实现开机自动录屏,听上去是个很小的需求,真做起来却有一堆讲究。我最近因为要给一台无人值守的机器做操作记录,把 Win10 22H2 和 Win11 23H2 上能用的开机自动录屏方案挨个测了一遍,发现最大的坑不是"找不到方法&q… · 2026/9/24 18:16:01

Python波束形成仿真:从环境配置到算法调试实战指南
Python波束形成仿真:从环境配置到算法调试实战指南

简介:本资源是一套基于Python的波束形成算法仿真代码与可视化结果集,面向信号处理、雷达通信及阵列天线方向的高校学生、科研人员与工程师,用于深入理解并实践主流波束形成技术原理与性能对比。压缩包共114个文件,含23个核心Pytho… · 2026/9/24 18:16:01

朴素贝叶斯实战:真假新闻分类模型从训练到部署
朴素贝叶斯实战:真假新闻分类模型从训练到部署

简介:本资源面向数据挖掘与自然语言处理初学者及进阶学习者,围绕朴素贝叶斯算法构建真假新闻分类模型这一典型文本分类任务,提供从数据准备到模型评估的完整实战方案。压缩包共4个文件,约27.2MB,包含Fake.csv与True.cs… · 2026/9/24 18:15:55

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码