|
01. 创作背景 首先,跟同学们报告一下,我是x86体系结构及其汇编语言方面的专业人士,也是C语言的专业人士。从2000年开始,IT行业逐渐变得红火,很多人开始学计算机,但我发现很多人苦于搞不清计算机的工作原理,于是我就想让大家轻松搞清楚计算机是如何工作的(心里总有一种想把自己知道的技术告诉别人的冲动)。最终,在2009年,我出版了自己的第一本书《穿越计算机迷雾》(https://book.douban.com/subject/5432475/),这是一本科普读物。同样地,看到大家学汇编语言很吃力,尤其是无法理解x86处理器的保护模式,我又写了《x86汇编语言:从实模式到保护模式》一书(https://book.douban.com/subject/36238072/)。最近,我又出版了《x86汇编语言:编写64位多处理器多线程操作系统》一书(https://book.douban.com/subject/36941945/)。
相较于冷门的汇编语言,学C语言的人就多了,而且不是一般地多,是非常多,很多很多,这让我想到一句话叫“多如过江之鲫”。相应地,C语言的图书也是非常多的,我经常用“多如牛毛”、“汗牛充栋”来形容。和C语言有关的图书市场是极度饱和的,按道理来说,我没必要掺和一下,再写一本。但是,这些图书中存在的大问题激起了我的好胜心,使我有一种把知识的真相告诉大家的冲动。
作为一个熟悉C语言国际标准的人来说,我认为,市面上的绝大多数图书和教材都有各种各样的问题,比如使用术语非常随意,内容含糊,令读者似懂非懂(好象懂了,仔细一想又不是那么回事)。典型地,都说指针难,就是因为没有书把指针到底是什么说清楚。除此之外,更大的问题是以讹传讹,存在大量自相矛盾甚至是错误的内容而不自知。不单单是图书,网络上的绝大多数专栏和视频课程,其错误和离谱程度也是令人震惊的。从发明C语言开始至今已经50多年了,教学环境还是这个样子,实在是难以理解。这是一个历史问题,在C语言第一次标准化(1989年)之前,这门语言还不是十分完备,写书的人会添加很多自己的理解和看法,而Turbo C 2.0(1988年)时代的很多“惯例”被当成了真理。再往后,很多C语言教材的作者,自己也没读过ISO/IEC 9899标准。他们参考的是“前人的教材”,错误就这样一代代传下来。
现在是人工智能AI的时代,很多学生已经借助于AI来学习C语言。但问题是AI(无论是ChatGPT还是国内的大模型)在学习这些教材的数据时,把这些错误也学进去了——所以AI给出的C语言答案,本质上是在复述一个本身就有问题的知识体系。结果就是:AI在C语言问题上的“错误率”,不是AI本身的问题,而是训练数据(国内互联网上的C语言内容)的质量问题。AI只是忠实地反映了这个领域的混乱。更深层的问题:初学者没有能力分辨这些错误,他们用AI查答案,等于在用一个“错误放大器”——AI把教材里的错误变得更流畅、更自信地输出,让初学者更难察觉。
在这种情况下,如果你是一个C语言方面的专家,有点时间,还好为人师,是不是就有一种强烈的冲动,想要去改变这种现状呢?学习语言也是学习一种逻辑,你的书必须能够自圆其说,只有逻辑上通了,才算正直理解和掌握了这门编程语言,也才能真正有“通透”感。注意:文章末尾有本书封面、前言、目录和前7章的PDF下载。
02. 图书封面
03. 内容介绍和版权页
内 容 简 介
本书面向大一新生和其他刚进入计算机领域的初学者,从最基本的计算机工作原理开始,以问题和实例为导向,层层递进到C语言的各个知识点,包括各种数据类型、运算符、表达式和语句等,内容详略得当、重点突出,遵循知识屏蔽的原则,符合C语言国际标准且很多知识点和语法的讲解鲜见于其他同类图书。
未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。 版权所有,侵权必究。
图书在版编目(CIP)数据 零起步快速通透C语言 / 李忠, 李双圆著. -- 北京 : 电子工业出版社, 2026. 3. -- ISBN 978-7-121-52316-8 Ⅰ. TP312.8 中国国家版本馆CIP数据核字第202678MM62号
责任编辑:缪晓红 印 刷: 装 订: 出版发行:电子工业出版社 北京市海淀区万寿路173信箱 邮编:100036 开 本:787×1092 1/16 印张:32.75 字数:676千字 版 次:2026年3月第1版 印 次:2026年3月第1次印刷 定 价:128.00元
凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。若书店售缺,请与本社发行部联系,联系及邮购电话:(010)88254888,88258888。 质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件至dbqq@phei.com.cn。 本书咨询联系方式:(010)88254760,mxh@phei.com.cn。
04. 前 言
欢迎选用这本C语言教材!
从二十世纪七十年代C语言诞生以来,与之相关的图书多如牛毛、汗牛充栋。既然如此,为什么我还要再写一本,给“牛”增加负担呢?这事说来话长。
我当初是如何学习C语言的呢?印象中,我看的第一本书有着朴素亲和的封面,上面印着一个大的“C”字,但它没有解释清楚stdio.h是什么东西,以及程序开头的# include在搞什么名堂。我是一个喜欢刨根问底的人,如果从一开始就整一些暗盒,我也就没兴趣再学下去了,于是我看了几页就将其束之高阁。
接下来我又翻了一下别的C语言图书,发现它们都是一样的。不过,在胡乱翻书的过程中,我对C语言也有了基本的了解。
所以,我并没有认真读过哪一本C语言图书,而是在有了一些简单的经验和基础后,直接从C语言标准文档学起的。C语言标准文档的行文确实晦涩,读起来很费劲,但是它精确,能让你豁然开朗、开心、激动、兴奋。
在那个时候,C语言标准文档的语言部分大约160页,我读完这一部分用了6个月。什么感觉?很通透。后来我又翻了一些C语言图书,它们都有自己的特色,但也有一些共同的特点,例如,“表达式有值”是一个极其重要的规则,但这些书都没有提到它,也很少从这个角度来分析程序的行为。相比之下,说不清stdio.h是什么东西也就算不上缺点了。
市面上的C语言图书还有另一个特点,那就是它们具有明显的代际传承。第一批C语言图书诞生于C语言标准化之前,具有明显的局限性,对很多语法现象的语义描述不标准、不规范,且术语的使用非常随意,容易引起误解。时光荏苒,它们的读者又成了作者。所以你会发现,现在市面上的C语言图书,绝大多数的“祖宗”可以追溯到二十世纪八、九十年代的那几本书,尽管腔调不同,但只要一开始讲语法,就原形毕露了。典型地,这些书通常都有“数组名”这个术语,并宣称数组名是指针常量。
市面上的C语言图书各有特色,很难说孰优孰劣。如果非要说的话,那就是作为一个看惯了C标准文档的人,总觉得它们的内容和语法表述与我想的不一样,也许就是所谓的“我有我的说法”吧。所以你现在明白我为什么要给“牛”增加负担的原因了吗?表面上看,C是一门简单的计算机语言,容易上手,简单培训一下就可以笨拙地写一些可以运行的代码,但是这并不意味着C语言真的简单。我的愿望就是写一本书,讲清楚C语言的本质,带领初学者穿越C语言的迷雾。至于我的能力够不够,能不能实现这个目标,就靠实践来检验了。具体来说,本书的特点如下。
零基础、朴实易懂,循序渐进。考虑到本书的很多读者都是大学新生,对计算机的工作原理、软件和硬件的关系、实际的软件开发流程等等都不太了解,一上来就告诉他们如何编程是不行的,会把他们搞懵,继而失去兴趣。为此,本书是从计算机原理开始的,这和其他C语言图书是不一样的。大道至简,本书行文质朴,直截了当,易于理解。为了使学习过程自然顺滑,我对本书的内容及其顺序做了精心编排,在讲前面的内容时,尽量不使用后面才出现的概念、术语和知识点。
内容正确,符合标准。C语言有自己的国际标准,该标准描述和规定了C语言的编译环境、运行环境和编程语法,而本书所讲授的内容都是与标准保持一致的,不会用错误的概念和内容误导学习者,能够帮助他们掌握这门语言的要点和精髓,让他们能够很快掌握并使用这门语言。
厚度适中,重点突出,详略得当,方便教学。C语言的细节还是很多的,这从它的国际标准文档里就可以看出来。C语言的国际标准文档由语言部分和标准库组成,在它的最新标准里,语言部分就有190页。考虑到标准文档的行文言简意赅,晦涩难懂,你就知道它浓缩了多少知识点。如果把每个知识点都解释得明明白白的,再举两个例子,那本书的厚度将是惊人的,没有一千多页是下不来的,而且最终会变成一本枯燥的手册,这同时也会导致初学者不知道哪些是重点,哪些只需要了解就行;另一个问题就是无法拿进课堂,这么厚,别说一个学期,几个学期都不够。对于初学者来说,只需要把重要的知识点学明白,掌握这门语言的本质和精髓就行了。至于更多的细节,在需要的时候慢慢研究就好了,本书的另一个目标就是为你直接看标准文档打一个良好的基础。
有的同学说了,现在是人工智能(AI)的时代,我完全可以用AI来学习C语言,让它成为我的私人老师,岂不美哉!所以,你这本书还有用吗?
当然有用!
现阶段的AI是没有灵魂、没有思想的,并不能真正“理解”代码。它确实擅长生成答案,但并不等于答案是正确的。它可能会非常自信地给出错误结论,也可能在不经意间带入偏见。相反地,图书承载的是人的思想,内容编排是科学的,文字是有温度的,读书的过程是心灵的交流和思想的碰撞。
看过其他C语言图书的同学会注意到本书没有使用“变量”一词,而这个词是绝大多数编程书籍的标配。那么,为什么本书不使用它呢?
“变量”是从数学领域借来的术语,在C语言的图书和教程里大量使用,但意思和作用已经改变。在这种情况下,要么使用另外的术语(比如本书中的“对象”),要么把它解释清楚,告诉大家它在C语言里是个什么意思。遗憾的是,传统的图书和教材都不觉得这是个问题,一样都没做。所以“变量”到底是什么,没有人能说清楚。给定以下代码片断:
int a, * p = & a; a = 0; * p = 65533;
尽管没人能说清到底啥是变量,但学过C语言的人都知道a是个变量。变量最主要的用途就是保存或者读取值,所以上述代码的第二行是把0保存到变量a。再来看上述代码的第三行,这一行是把65533保存到* p。这个* p是啥?是变量吗?我相信多数人就吱吱唔唔说不清楚了。所以我们需要一个新的概念,它能涵盖所有能被赋值的东西,包括变量。标准化之后的C语言只使用标识符、对象和左值这三个核心概念,而不使用变量。本书依从于标准,也不使用变量这个术语。
本书配套的源码、工具、检测点和习题答案请到我的个人网站www.lizhongc.com下载;我的电子邮件地址是leechung@126.com。需要特别注意的是书中有很多检测点和习题,它们用来检查学习效果,很重要,不可等闲视之,也不要随意跳过!祝我亲爱的同学们都能早日掌握C语言!
吉林大学的李双圆参与了本书的创作。
写书不是一朝一夕的事,好在有我家娘子相助,为我分担家务,让我专心写作,遂使此书早成。
下面这段文字不是乱码,而是用输入法加密的,因为这是一些心里话,我想把它记在书里,但还不太想让别人知道。
2025 rh 11 eee 25 jjjj j wh tgj s r jjjj bb . h tfj ltui nnh ghd aa pfq tym , ntc xwg xyna lkb . gh tfj gmww hko qq , gmww tfk qq wc jfd qh r ftx pe , vc vc ghd d fcl rt sy , ld o mt gd ue vbn edf me me rr ( gqje xyy ) . gn hx m jf , q bn ghd d xwgk ipg rtol pgcf jfd os hw fcl rt sy —— xwg px wu gjq rqmd jn idri sajd fnw. sg go q yid yynw buk d vcg vcg tmd lp r ,wjg p j wh ih rt sy,sks sks veg veg wu ftjb buk d vbn tmd lp,dmj eg q fg fgh qq gd ue mqj lkd ftx pe cde lk wgcf vvvv r vqaj pynn,rn c yi im lkd fcu.wjg jt jq kr q fg veg lfny syp vcg vcg d rt sy ck h r nyng jf ,q tve rg ntx im e lkd fcu .pykq vcg vcg fuf pygl nnw qi ,tmd wsg wvf yvi !sks sks veg veg ey rn e us dhi ee dc wu nynn jfd nynn qh ,nae gm b pwa ue r lft xfk ,dgkn ytmf wb wu r wfy bm !
05. 目 录
第1章 计算机和编程语言 1 1.1 用电表示数字 2 1.2 二进制加法机 4 1.3 具有记忆功能的器件——寄存器 5 1.4 带寄存器的加法机 7 1.5 能做四则运算的机器 8 1.6 机器指令 10 1.7 内存 13 1.8 自动计算 18 1.9 处理器 21 1.10 汇编语言的产生 24 1.11 高级语言的出现 27 本章习题 33
第2章 操作系统和C实现 35 2.1 计算机硬件 36 2.2 操作系统及其编程接口 37 2.2.1 为什么需要操作系统 38 2.2.2 操作系统的用户界面和编程接口 40 2.3 C实现 43 本章习题 50
第3章 输入输出、库和头文件 51 3.1 在Windows上播放音乐的小程序 52 3.2 库和库函数的例子 55 3.3 程序的编译、链接和执行 57 3.4 头文件和文件包含 61 3.5 C标准库 65 本章习题 68
第4章 从1加到100 70 4.1 从1加到100的第1种写法 71 4.1.1 注释 73 4.1.2 标识符和对象 74 4.1.3 表达式和语句 76 4.1.4 while语句 77 4.1.5 关系表达式 78 4.1.6 复合语句 79 4.1.7 复合赋值运算符 80 4.1.8 函数调用表达式 81 4.1.9 格式化输出 82 4.2 表达式的值和副作用 83 4.2.1 赋值表达式的值和副作用 84 4.2.2 运算符的结合性 87 4.2.3 关系运算符的值 88 4.2.4 加性运算符 89 4.2.5 乘性运算符 90 4.2.6 递增和递减运算符 90 4.3 从1加到100的第2种写法 93 4.3.1 初始化和初始化器 94 4.3.2 运算符的优先级 94 4.4 从1加到100的第3种写法 96 4.5 从1加到100的第4种写法 97 4.6 从1加到100的第5种写法 99 4.6.1 do语句 100 4.7 从1加到100的第6种写法 102 4.7.1 for语句 102 4.8 从1加到100的第7种写法 104 4.9 从1加到100的第8种写法 105 4.9.1 空语句 105 4.10 从1加到100的第9种写法 106 4.10.1 标识符的作用域 107 本章习题 109
第5章 集成开发环境 111 5.1 Code::Blocks集成开发环境 112 5.1.1 下载和安装Code::Blocks 113 5.1.2 运行Code::Blocks 113 5.1.3 配置工具链 114 5.1.4 使用Code::Blocks编写和运行程序 115 5.1.5 在Code::Blocks里调试程序 120
第6章 更多的编程实例 124 6.1 打印表格 125 6.1.1 宏定义和宏替换 127 6.2 打印九九乘法表(之一) 129 6.3 打印九九乘法表(之二) 131 6.4 百钱百鸡问题 134 6.4.1 if语句 135 6.4.2 逻辑与、逻辑或和等性运算符 136 6.4.3 语法树 138 6.4.4 嵌套的if语句 139 6.5 寻找符合条件的三位自然数 140 6.5.1 括号表达式 142 6.5.2 摇摆的else子句 144 6.6 素数判定 145 6.6.1 标准整数类型 145 6.6.2 return语句 149 6.6.3 整数类型转换 152 6.6.4 整型常量 154 6.6.5 main函数的末尾可以省略return 0 156 6.6.6 函数原型 157 6.7 函数的递归调用 158 6.7.1 什么是递归 159 6.7.2 递归调用的原理 160 6.7.3 文件作用域 165 6.7.4 静态存储期 166 6.7.5 自动存储期 167 6.7.6 具有静态存储期且只在块内可见的对象 169 6.8 实浮点类型 171 6.8.1 标准浮点类型 171 6.8.2 十进制浮点类型 173 6.9 浮点常量 175 6.10 实浮点类型的应用实例 176 6.10.1 整数—实浮点类型的相互转换 177 6.10.2 实浮点类型的互相转换 178 本章习题 179
第7章 指针 180 7.1 一元&和一元*运算符 181 7.2 指针类型的对象 185 7.3 类型名和强制类型转换 189 7.4 左值和左值转换 193 7.5 参数类型为指针的函数 195 7.6 指向函数的指针 198 7.6.1 函数指示符-指针转换 199 7.6.2 指向函数的指针 200 7.7 返回指针的函数 203 7.7.1 条件表达式 205 7.8 指向指针的指针 206 7.9 const限定的类型 210 7.9.1 指向const限定类型的指针 212 7.9.2 const限定的指针(类型) 213 7.10 restrict限定的指针类型 215 7.11 空指针常量和空指针 219 7.12 格式化输入函数scanf 220 本章习题 223
第8章 数组 225 8.1 声明数组类型的对象 226 8.1.1 数组对象的初始化 228 8.2 数组元素的访问 230 8.2.1 运算符sizeof 231 8.2.2 类型定义 234 8.3 数组的应用:冒泡排序 238 8.4 指针运算 241 8.5 字符数组 246 8.5.1 字符集和字符编码 246 8.5.2 字符类型 249 8.5.3 字符常量 250 8.5.4 脱转序列 251 8.5.5 用putchar库函数打印字符 253 8.6 字符串 253 8.6.1 论程序的可读性 255 8.6.2 puts库函数 256 8.7 字面串 257 8.7.1 包含脱转序列的字面串 259 8.7.2 用作初始化器的字面串 260 8.8 指向数组的指针 263 8.9 变长数组 266 8.10 类型的兼容性 269 8.11 数组-指针转换 272 8.12 下标运算的本质是指针运算 274 8.13 printf和scanf库函数的原型 276 8.14 应用实例:字符串比较 277 8.14.1 strcmp标准库函数 283 8.15 应用实例:连接两个字符串 283 8.15.1 strcat和strcpy标准库函数 287 8.16 应用实例:打印对象的每字节的值 289 8.16.1 默认实参提升 291 8.17 元素类型为数组的数组 292 8.17.1 多维数组的初始化和访问 294 8.18 数组类型的参数 299 8.19 元素类型为指针的数组 301 8.20 main函数的原型和命令行参数 305 8.21 指向void的指针 314 本章习题 317
第9章 中文的输入和输出 318 9.1 字符、字符集和字符编码 319 9.2 ISO 2022和GB 2311字符代码结构标准 322 9.3 GB 2312字符集及其编码方案 324 9.4 EUC编码方案 326 9.5 GBK字符集及其编码方案 329 9.6 ISO 10646和Unicode 330 9.6.1 UCS的基本多语种平面 332 9.6.2 UCS的编码形式 333 9.6.3 字节序(大端和小端) 336 9.6.4 UCS的编码方案 339 9.7 字符集和字符编码的应用现状 343 9.8 GB 18030字符集及其编码方案 344 9.9 源字符集 345 9.10 多字节字符 346 9.11 执行字符集 347 9.12 C语言的国际化 349 9.13 宽字符 354 本章习题 359
第10章 结构、联合与枚举 360 10.1 结构类型 361 10.1.1 幂和平方根的标准库函数 363 10.1.2 结构成员的访问 364 10.1.3 结构类型的标记 364 10.1.4 库的链接 366 10.1.5 标准库的斜边函数 366 10.2 结构对象的内存布局 368 10.2.1 对齐和运算符alignof 369 10.2.2 函数式宏定义 371 10.2.3 宏运算符(预处理器记号)# 372 10.2.4 结构对象的内部和尾部填充 373 10.3 联合类型 376 10.4 联合的应用:打印float数值的位模式 379 10.4.2 常量表达式 380 10.4.3 逐位移动运算符 382 10.4.4 整型提升 386 10.4.5 逐位与运算符 388 10.4.6 常规算术转换 389 10.4.7 逐位或运算符 393 10.4.8 位精度整数类型 394 10.5 枚举类型和枚举常量 396 10.5.1 switch语句 400 10.6 结构、联合与枚举的应用实例 405 10.6.1 匿名结构和匿名联合 407 10.6.2 元素类型为结构的数组 410 10.6.3 逻辑与和逻辑或的短路效应 410 本章习题 415
第11章 链表和动态内存分配 416 11.1 学员信息管理 417 11.1.1 链表和自引用的结构 417 11.1.2 模块化、多文件的程序设计 421 11.1.3 条件包含 431 11.2 添加学员信息 433 11.2.1 动态内存分配 434 11.2.2 成员选择运算符“->” 436 11.2.3 逻辑反运算符 440 11.2.4 逗号运算符 443 11.2.5 goto语句 446 11.2.6 配方法在编程中的应用 448 11.3 打印学员信息 450 11.4 释放链表上的所有节点 452 本章习题 453
第12章 输入输出和文件操作 454 12.1 外部存储设备和文件 455 12.2 输入输出和流 456 12.2.1 文本流和二进制流 457 12.2.2 标准输入、标准输出和标准错误 461 12.2.3 输入输出的重定向 463 12.3 字符的输入输出函数 464 12.4 直接的输入输出 466 12.5 格式化输入输出函数 469 12.5.1 格式化输入scanf和fscanf函数 469 12.5.2 格式输出printf和fprintf函数 477 12.6 学员信息文件的读写 481 12.6.1 将学员信息写入文件 484 12.6.2 从文件读取学员信息 486 12.7 改进后的学员信息管理程序 488 第13章 学员信息管理系统 490
13.1 主程序的执行流程 491 13.1.1 显示系统主菜单 492 13.1.2 菜单的选择和处理 493 13.2 学员信息的删除 494 13.3 学员信息的查询 496 本章习题 503
附录A C语言类型系统全图 504 附录B C语言运算符一览表 506
06. 资料下载
要想了解这本书,可下载前7章的PDF:
零起步快速通透C语言.pdf
(70.85 MB, 下载次数: 37)
。著作权在我,版权归电子工业出版社,所以只能提供前7章的内容(如此已属不易)。 |