《C语言非常道》是站长原著图书,于2019年出版。以下是本书封面及其它相关内容的介绍,同时还提供了配书文件、前6章的PDF、MinGW_W64等相关的下载服务。阅读本书前可先看配套视频,文中给出了购买链接。

---图书封面---

cspecial


---内容简介---

(原书无此部分)


---图书在版编目(CIP)数据---

C语言非常道/李忠著. —北京:电子工业出版社,2019.4
ISBN 978-7-121-36183-8
Ⅰ. ①C…  Ⅱ. ①李…  Ⅲ. ①C语言-程序设计  Ⅳ. ①TP312.8

中国版本图书馆CIP数据核字(2019)第054621号


---增值服务--

flmouse        本书的内容是完整的、循序渐进和自成体系的,用来自学没有任何问题。但书的内容承载力有限,不如视频内容形象、生动、直观,对于某些基础薄弱的人来说可能有些困难。

        视频严格来说不是与本书配套的,侧重于纠正和澄清基本概念,阐述基本原理,演示基本编程环境的创建。所以,我推荐的学习路线是先看视频,再细读本书,效果绝佳。

        本书的配套视频已经在网易云课堂发布。视频内容以纸质书的内容为主线,但并不完全一致,部分内容有所增强和细化。购买或者了解更多

    


---售后服务---

downfile_thumb3        有以下内容可供下载:配书文件包(约3MB,内容为书中的源代码、第6章用到的zmtx.wav文件、书中提到的DLL export viewer程序、书中用到的十六进制查看器和练习题答案);出版前的审校稿前6章(PDF格式,约5MB);MinGW_W64 v8.1.0压缩包(约120MB)及其安装说明。前往下载页面

        书中第二章提到我会提供一个Code::Blocks的安装说明。原先准备提供一个文字版的说明,但考虑到视频更友好、更直观,因此这里提供一个视频形式的安装说明,它来自于本书的配套视频

   


---图书基本信息---

作 者:李忠
出版时间:2019年
字 数:745千字
版 次:2019年4月第1版
页 数:485
开 本:1/16
装 帧:平装
ISBN:978-7-121-36183-8
纸质书定价:¥128.0


---第1版前言---

        毋庸置疑,C是非常流行的编程语言。正是因为流行,和它有关的图书之多,可以用多如牛毛、汗牛充栋来形容。

        既然都已经这么多了,那我为什么还要再来一本,给牛增加负担呢?原因很简单:想看看是否能用一种和别人不同的方法来把C语言讲清楚。这本书面向初学者,但是,已经学过C语言的人也不妨读一读,因为我的讲解方法和对很多问题的阐述和别人不一样。 当然,自负是人类的共性,这本书是否真的能把C语言讲清楚,还得靠读者来检验。

         C语言难学吗?来自这个行业的声音始终自相矛盾。一方面,很多过来人声称C语言其实很简单;另一方面,很多初学者觉得很难,不得其门而入。仅就语法而言,C语言确实比较简单。但是,这种简单性使得很多人对它的掌握只停留在似是而非的表面上。似是而非的学习一开始很轻松,但你走不远。实际上,即使是声称已经掌握了这门编程语言的人,对很多语法要素的认识和理解也是错误的,在书写稍微复杂一些的代码时,也发现自己突然变得糊涂起来。

        那么,学习C语言的诀窍在哪里呢?

        首先,掌握它的类型系统并学会以类型的观点来构造和解析程序中的代码,这样你就不会迷路。如果你没有掌握C语言的类型系统,不会从类型的角度来分析一个表达式,说明你并没有掌握C语言。

        其次,你要了解C语言在整个计算机系统中的位置,知道它和操作系统或者硬件之间的关系;尤其是要理解库和C语言的关系,要明白是库拓展了C语言的实用性。除了C语言本身的简洁、优美和强大的表达能力外,C标准库和其他形形色色的库也是C语言变得流行并威力无穷的重要因素。

        写一本编程语言的通俗入门教材,最痛苦的莫过于你不能一下子展现事物的全貌和众多细节。尽管你知道它,也渴望表达,然而毫不客气地说,读者们并不需要它。读者不了解原委,没有耐心,记不住,而且恐惧。为此,本书力求在以下几个方面做一些突破:

        首先,C语言的知识点是网状的,是互相牵扯和交叉的,如果不加以梳理,随着阅读的深入,读者不理解的概念和术语将越来越多,从而产生挫败感。为了克服这一问题,我们把它变成线性的,还没讲到的内容一概不提,没讲过的概念一概不用;讲过了,有印象了,掌握了,再用来解释新的知识。

        其次,对于一本C语言的图书或者教材来说,最怕的是陷于细节而无法自拔,这往往会使读者成为语法机器而不能领略C语言的全貌,不知道C语言到底有什么实际的用处,更不知道哪些知识才是最重要的。

        因此,在内容的组织上,这本书的宗旨是先观其大略,而不是一上来就究其细节。如果只是陈列各种语法元素及其细节,我们可能需要写几百上千页,各种示例和习题堆砌其中。学生学完了,习题也做完了,还是莫名其妙,不知道C语言到底在整个计算机体系结构中处于什么位置,它和操作系统的关系是什么,也不知道为什么别人的程序可以播放音乐、处理图片、过滤网络数据包,而自己的程序只能打印哪些学生的成绩高于60分。

        第三,考虑到类型系统的重要性,从本书一开始就逐渐强化类型的知识和基于类型的语法分析。这是掌握C语言的关键,不可等闲视之。

        第四,多数教材和图书都从一个令初学者抓狂的语句
        printf ("hello world");
        开始,其理由是初学者可以马上看到“成果”,增加他们的学习兴趣。然而,除非是面向有编程经验的读者,否则这样做可能弊多利少。一方面,printf只是一个普通的输入输出函数,而且并不是C语言的组成部分,但初学者可能会先入为主地认为它就是C语言里的大梁;另一方面,这个函数并不是它表面上看起来的那样简单,实际上涉及多个知识点和概念,而且无法在一本书的开始部分完全展开。对于初学者来说,从一开始就将他们引入一个迷局可能并不值得。

        考虑到这些,本书一反常态,将输入输出留到第6章单独讲述。在此之前,我们用调试软件来跟踪程序的执行过程并观察执行结果。事实上,程序调试是非常重要的技能,所以本书这样安排应该是科学的。

        第五,本书有一章是专门介绍Windows编程的,虽然如走马观花一样简单,也会令某些读者质疑,毕竟C语言无关具体的硬件和操作系统平台。之所以这样安排,主要的目的是让读者领略C语言是如何在具体的平台上发挥作用的,以及库在这个过程中所起到的作用和扮演的角色,并从一个侧面解答C语言到底有什么用的问题。尽管C语言不依赖于平台,但用C语言写出来的程序却需要在具体的平台上执行。

        第六,本书引入了很多概念和术语,但在正文中夹杂这些术语的英文拼写可能会对部分读者造成阅读障碍。考虑到这一点,我们在每一章的前面用思维导图单独列出,这样做的另一个好处是可以让读者清楚地知道本章中都讲了哪些内容。

        第七,这本书开篇没有讲C语言的由来、历史、优点和应用领域,通常来说,这是一本C语言教材的格式化组成部分。但考虑到别的书都已经讲了,网络上也到处都有,所以我就没必要再啰唆了,请大家不要见怪。

        最后,这不是一本类似于辞典或者语法参考手册之类的书,内容的组织具有渐进和逐步展开的特点,应该从第1章开始顺序阅读。在内容的组织上,本书前半部分以如何实现输入输出为主线:第1章引入C语言编程的基本概念和要素;第2章讲解程序的调试;第3章快速介绍C语言里的大部分表达式和语句类型;第4和第5章介绍指针和数组,为输入输出做最后的铺垫;第6章完整介绍输入输出。在积累了相当的知识和经验后,本书后半部分以如何实现汉字的处理(第7章)、如何编写Windows程序以及编写一个复杂计算器为主线(第8、9、10、11章),继续讲解C语言的语法。为方便起见,第12章详细介绍了C语言里的每一种表达式。

        在学习这门编程语言之前,必须先了解计算机的工作原理,有使用计算机的经验。对于大学新生来说,我并不担心这一点,学校自有他们的教学计划和进度安排;对于自学这门编程语言的人来说,这是需要注意的。
       纸质书的内容承载力有限,为了帮助大家更好地使用本书和理解书中的内容,我会准备一些辅助的学习资料,比如导读和习题解析之类的文档,它们都存放在我的个人网站上,网站的地址就在下面。当然,如果你有什么意见和建议,也可以在网站上留言,或者通过下面的电子邮件地址与我联系。

        在即将出版之前,编辑同学希望我能在前言里提一提我以前写过的书。说白了,就是要做做广告。我当时就大义凛然地一口回绝:“此事决不可为!谦虚谨慎乃做人之根本,休想让朕把写过《穿越计算机的迷雾》和《x86汇编语言:从实模式到保护模式》这两本书的事说出来!”

        王晓波和李双圆参与了本书的写作,我们在此共同祝愿读者们阅读愉快,早日通过本书掌握C语言的精髓。

        李 忠
        2019年1月6日于长春
        网站:http://www.lizhongc.com/
        电邮:leechung@126.com


---第1版目录---

第1章 从1加到100 1
1.1 如何从1加到100 2
1.1.1 标准整数类型 7
1.2 相加过程的实现 9
1.2.1 左值和左值转换 13
1.2.2 表达式的值 14
1.2.3 运算符的优先级 16
1.2.4 运算符的结合性 17
1.3 源文件 20
1.3.1 函数 20
1.3.2 return语句 22
1.3.3 main函数 22


第2章 程序的翻译、执行和调试 24
2.1 C实现 25
2.2 程序的翻译和执行 27
2.3 程序的调试 28
2.4 集成开发环境 33
2.5 执行环境 35
2.6 从1加到N 38
2.6.1 注释 39
2.6.2 函数调用和函数调用运算符 39
2.6.3 函数原型 40


第3章 更多的相加方法 44
3.1 变量的初始化 45
3.2 认识复合赋值 46
3.3 认识递增运算符 47
3.4 初识复杂的表达式 48
3.5 认识关系运算符 49
3.6 求值 50
3.7 认识逗号表达式 53
3.7.1 全表达式和序列点 54
3.8 认识表达式语句 56
3.9 认识递减和逻辑求反运算符 57
3.10 参数值的有效性检查 59
3.10.1 认识if语句 60
3.10.2 认识逻辑或运算符 62
3.10.3 未定义的行为 63
3.10.4 摇摆的else子句 65
3.10.5 认识逻辑与运算符 66
3.11 认识标号语句和goto语句 68


第4章 指针不是指南针 71
4.1 认识一元&和一元*运算符 72
4.2 什么是指针 75
4.3 指针类型的变量 76
4.4 指向函数的指针 79
4.4.1 函数指示符—指针转换 80
4.5 返回指针的函数 83
4.6 掌握C语言需要建立类型的观念 85
4.6.1 整型常量 86
4.6.2 整数—整数转换 88
4.6.3 表达式的类型 89
4.6.4 认识整型转换阶和整型提升 92
4.6.5 指针—整数转换 96
4.6.6 指针—指针转换 98
4.7 指向指针(类型)的指针 102


第5章 准备显示累加结果 104
5.1 什么是数组 105
5.1.1 数组变量的声明 106
5.1.2 数组变量的初始化 107
5.1.3 认识sizeof和乘性运算符 108
5.1.4 认识变长数组 112
5.2 文字和编码 114
5.2.1 字符数组 116
5.2.2 字符常量 118
5.2.3 脱转序列 118
5.2.4 字面串和字符串 120
5.3 访问数组元素 122
5.3.1 数组—指针转换 123
5.3.2 指针运算和for语句 125
5.3.3 下标运算符 128
5.3.4 指针的递增和递减 129
5.4 指向数组的指针 135
5.5 元素类型为指针的数组 140
5.8 将数字转换为字符串 144
5.9 元素类型为数组的数组 150


第6章 输入和输出 155
6.1 输入输出那点事 156
6.2 系统调用 158
6.3 编译和链接 163
6.4 库 166
6.5 头文件、预处理和翻译单元 168
6.6 UNIX和类UNIX函数库 173
6.6.1 限定的类型 174
6.6.2 变参函数 177
6.6.3 认识逐位或、逐位与和逐位异或运算符 185
6.6.4 指向void的指针 187
6.6.5 结构类型 191
6.7 Windows动态链接库 200
6.7.1 认识成员选择运算符“.” 204
6.7.2 复合字面值 206
6.7.3 控制台I/O和音频播放 209
6.7.4 函数main的定义 214
6.8 C标准库 217
6.8.1 流 217
6.8.2 restrict限定的类型 219
6.8.3 C标准库的实现 221
6.8.4 标准输入和标准输出 223
6.8.5 标准I/O的缓冲区 226
6.8.6 直接的输入输出 231
6.8.7 格式化输出 233
6.8.8 格式化输入 245
6.8.9 格式化输入输出的实例 252


第7章 字符集和字符编码 266
7.1 字符集和字符编码的演变 267
7.1.1 GB2312字符集 267
7.1.2 GBK和GB18030字符集 268
7.1.3 UNICODE字符集和编码方案 269
7.2 多字节字符和宽字符 273
7.2.1 源字符集和执行字符集 273
7.2.2 多字节字符、宽字符和字节序 278
7.3 C语言的国际化 287
7.3.1 条件包含 292


第8章 欢迎来到类型之家 300
8.1 扩展整数类型 301
8.2 布尔类型_Bool 302
8.3 枚举类型 303
8.4 认识switch语句 305
8.5 联合类型 309
8.6 复数类型 313
8.7 限定的类型 314
8.8 类型的兼容性 315
8.9 类型转换 318
8.9.1 实浮点—整数转换 319
8.9.2 实浮点—实浮点转换 319
8.9.3 复数—复数转换 319
8.9.4 实数—复数转换 320
8.9.5 常规算术转换 320


第9章 作用域、链接、线程和存储期 324
9.1 标识符的作用域 325
9.1.1 函数作用域 325
9.1.2 文件作用域 326
9.1.3 块作用域 327
9.1.4 函数原型作用域 328
9.1.5 作用域的重叠 329
9.1.6 名字空间 331
9.2 标识符的链接 333
9.3 进程和线程 337
9.3.1 创建POSIX线程 340
9.3.2 线程同步 349
9.3.3 执行时间的测量 356
9.4 变量的存储期 357
9.4.1 线程存储期 360
9.4.2 静态存储期 363
9.4.3 自动存储期 367
9.4.4 指派存储期 368


第10章 Windows编程基础 369
10.1 如何编写Windows程序 370
10.1.1 注册窗口类 374
10.1.2 创建窗口 376
10.1.3 进入消息循环 378
10.2 窗口过程 379
10.2.1 函数调用约定 380
10.2.2 消息处理 382
10.2.3 回调函数 382
10.3 数据链表 387
10.3.1 作用域的起始点 387
10.3.2 动态内存分配 388
10.4 创建和应用所选的字体 390
10.5 关闭窗口并退出程序 393


第11章 递归调用、计算器和树 397
11.1 递归的原理 398
11.2 复杂计算器 402
11.2.1 程序的翻译过程 403
11.2.2 算式的语法 409
11.2.3 词法分析 413
11.2.4 函数指定符_Noreturn 417
11.2.5 语法分析 419
11.3 树和二叉树 425
11.4 计算器的二叉树版本 430
11.4.1 非本地跳转(setjmp/longjmp) 437


第12章 运算符和表达式 441
12.1 全表达式 442
12.2 左值转换 442
12.3 基本表达式 442
12.3.1 泛型选择 443
12.4 后缀表达式 445
12.4.1 复合字面值 446
12.4.2 数组下标 447
12.4.3 函数调用 448
12.4.4 成员选择 453
12.4.5 后缀递增 454
12.4.6 后缀递减 455
12.5 一元表达式 455
12.5.1 前缀递增 456
12.5.2 前缀递减 456
12.5.3 地址 457
12.5.4 间接 458
12.5.5 正号 458
12.5.6 负号 458
12.5.7 逐位取反 459
12.5.8 逻辑非 460
12.5.9 尺寸 460
12.5.10 对齐 463
12.6 转型表达式 464
12.7 乘性表达式 465
12.7.1 乘法 466
12.7.2 除法 466
12.7.3 取余 466
12.8 加性表达式 467
12.8.1 加法 467
12.8.2 减法 469
12.9 移位表达式 470
12.9.1 左移 471
12.9.2 右移 472
12.10 关系表达式 472
12.11 等性表达式 475
12.12 逐位与表达式 478
12.13 逐位异或表达式 478
12.14 逐位或表达式 479
12.15 逻辑与表达式 479
12.16 逻辑或表达式 480
12.17 条件表达式 480
12.18 赋值表达式 483
12.18.1 简单赋值 483
12.18.2 复合赋值 484
12.19 逗号表达式 485

details ends.

标签: none

已有 15 条评论

  1. Sef Sef

    李老师您好,问一下书中提到的Code::Blocks的安装教程是在哪呀?

    1. 对不起,忘了提供了。现在补上。
      同时把链接给你:https://www.bilibili.com/video/BV1bT4y1378j?p=13

  2. 程同学 程同学

    老师有两版C语言的书,这个是第二版?

  3. 123 123

    李老师您好,
    C语言非常道第86页最后一行,“指针函数的指针”疑似应该改为“指向函数的指针”;
    顺便问一下这本书是否有勘误;

  4. 你说得对,是这个问题。
    本书没有做勘误,但是书中的问题已经记录并准备修正。抽时间我会发出来的。

  5. Casper Casper

    P62, 第一行"运算符!的优先级低于等性运算符!=和==", 这里是否是有错误呢? 我在网上找了很多的资料, 都是 ! 的优先级比 !=, == 高, 希望老师解答一下,非常感谢.

    1. 对,一元运算符优先级高。

  6. Casper Casper

    int main (void)
    {
    int r;
    __asm__ (
    "mov eax, 0x4 \n\t"
    "mov ebx, 0x1 \n\t"
    "mov edx, 0xd \n\t"
    "int 0x80 \n\t"
    : "=a" (r)
    : "c" ("hello world.\n")
    );

    return r;
    }

    这段代码在我的环境下显示不出来文字. 我的环境是: Ubuntu 20.04, x86-64, 内核版本是: 5.4.0-74-generic. 麻烦老师给个思路, 我在网上搜索也不知道该如何搜索相关的内容。

  7. 是这样的,32位Linux使用int 0x80中断进入内核,64位Linux使用syscall指令。书上没有这个例子,但是视频里是用的syscall。

  8. holylw holylw

    这本书会出第二版?什么时候出来

  9. lile lile

    c0608.c centos7、MacOS编译不通过,说是unistd没有strlen函数

  10. # include

    有些平台的unistd.h不见得会间接引入这个函数。

  11. string.h

添加新评论