编辑推荐
经久不衰的C语言畅销经典教程针对C11标准进行全面更新《C Primer Plus(第6版)中文版》是一本经过仔细测试、精心设计的完整C语言教程,它涵盖了C语言编程中的核心内容。《C Primer Plus(第6版)中文版》作为计算机科学的经典著作,讲解了包含结构化代码和自顶向下设计在内的程序设计原则。与以前的版本一样,作者的目标仍旧是为读者提供一本入门型、条理清晰、见解深刻的C语言教程。作者把基础的编程概念与C语言的细节很好地融合在一起,并通过大量短小精悍的示例同时演示一两个概念,通过学以致用的方式鼓励读者掌握新的主题。每章末尾的复习题和编程练习题进一步强化了重要的信息,有助于读者理解和消化那些难以理解的概念。本书采用了友好、易于使用的编排方式,不仅适合打算认真学习C语言编程的学生阅读,也适合那些精通其他编程语言,但希望更好地掌握C语言这门核心语言的开发人员阅读。《C Primer Plus(第6版)中文版》在之前版本的基础之上进行了全新升级,它涵盖了C语言新的进展以及C11标准的详细内容。本书还提供了大量深度与广度齐备的教学技术和工具,来提高你的学习。详细完整地讨论了C语言的基础特性和附加特性;清晰解释了使用C语言不同部分的时机,以及原因;通过简洁、简单的示例加强读者的动手练习,以帮助一次理解一两个概念;囊括了数百个实用的代码示例;每章末尾的复习题和编程练习可以检测你的理解情况。涵盖了C泛型编程,以提供灵活性。
内容简介
《C Primer Plus(第6版)中文版》详细讲解了C语言的基本概念和编程技巧。《C Primer Plus(第6版)中文版》共17章。第1、2章介绍了C语言编程的预备知识。第3~15章详细讲解了C语言的相关知识,包括数据类型、格式化输入/输出、运算符、表达式、语句、循环、字符输入和输出、函数、数组和指针、字符和字符串函数、内存管理、文件输入输出、结构、位操作等。第16章、17章介绍C预处理器、C库和高级数据表示。本书以完整的程序为例,讲解C语言的知识要点和注意事项。每章末设计了大量复习题和编程练习,帮助读者巩固所学知识和提高实际编程能力。附录给出了各章复习题的参考答案和丰富的参考资料。《C Primer Plus(第6版)中文版》可作为C语言的教材,适用于需要系统学习C语言的初学者,也适用于巩固C语言知识或希望进一步提高编程技术的程序员。
作者简介
Stephen Prata曾在加利福尼亚的马林学院(肯特菲尔德)教授天文学、物理学和程序设计课程,现已退休。他在加州理工学院获得学士学位,在加州大学伯克利分校获得博士学位。他接触程序设计,是为了利用计算机给星团建模。Stephen撰写和与他人合著了十几本书籍,其中包括C Primer Plus和Unix Primer Plus。
目录
- 第1章 初识C语言 1
- 1.1 C语言的起源 1
- 1.2 选择C语言的理由 1
- 1.2.1设计特性 1
- 1.2.2高效性 1
- 1.2.3可移植性 2
- 1.2.4强大而灵活 3
- 1.2.5面向程序员 3
- 1.2.6缺点 3
- 1.3C语言的应用范围 3
- 1.4 计算机能做什么 4
- 1.5 高级计算机语言和编译器 5
- 1.6 语言标准 6
- 1.6.1第1个ANSI/ISO C标准 6
- 1.6.2C99标准 6
- 1.6.3C11标准 7
- 1.7 使用C语言的7个步骤 7
- 1.7.1第1步:定义程序的目标 8
- 1.7.2第2步:设计程序 8
- 1.7.3第3步:编写代码 8
- 1.7.4第4步:编译 8
- 1.7.5第5步:运行程序 9
- 1.7.6第6步:测试和调试程序 9
- 1.7.7第7步:维护和修改代码 9
- 1.7.8说明 9
- 1.8 编程机制 10
- 1.8.1目标代码文件、可执行文件和库 10
- 1.8.2UNIX系统 11
- 1.8.3GNU编译器集合和LLVM项目 13
- 1.8.4Linux系统 13
- 1.8.5PC的命令行编译器 14
- 1.8.6集成开发环境(Windows) 14
- 1.8.7Windows/Linux 15
- 1.8.8Macintosh中的C 15
- 1.9 本书的组织结构 15
- 1.10本书的约定 16
- 1.10.1字体 16
- 1.10.2程序输出 16
- 1.10.3特殊元素 17
- 1.11本章小结 17
- 1.12复习题 18
- 1.13编程练习 18
- 第2章 C语言概述 19
- 2.1 简单的C程序示例 19
- 2.2 示例解释 20
- 2.2.1第1遍:快速概要 21
- 2.2.2第2遍:程序细节 21
- 2.3 简单程序的结构 28
- 2.4 提高程序可读性的技巧 28
- 2.5 进一步使用C 29
- 2.5.1程序说明 30
- 2.5.2多条声明 30
- 2.5.3乘法 30
- 2.5.4打印多个值 30
- 2.6 多个函数 30
- 2.7 调试程序 32
- 2.7.1语法错误 32
- 2.7.2语义错误 33
- 2.7.3程序状态 34
- 2.8 关键字和保留标识符 34
- 2.9 关键概念 35
- 2.10本章小结 35
- 2.11复习题 36
- 2.12编程练习 37
- 第3章 数据和C 39
- 3.1 示例程序 39
- 3.2 变量与常量数据 42
- 3.3 数据:数据类型关键字 42
- 3.3.1整数和浮点数 43
- 3.3.2整数 43
- 3.3.3浮点数 43
- 3.4C语言基本数据类型 44
- 3.4.1int类型 44
- 3.4.2其他整数类型 47
- 3.4.3使用字符:char类型 50
- 3.4.4_Bool类型 54
- 3.4.5可移植类型:stdint.h和inttypes.h 55
- 3.4.6float、double和long double 56
- 3.4.7复数和虚数类型 60
- 3.4.8其他类型 60
- 3.4.9类型大小 62
- 3.5 使用数据类型 63
- 3.6 参数和陷阱 63
- 3.7 转义序列示例 64
- 3.7.1程序运行情况 65
- 3.7.2刷新输出 65
- 3.8 关键概念 66
- 3.9 本章小结 66
- 3.10复习题 67
- 3.11编程练习 68
- 第4章 字符串和格式化输入/输出 71
- 4.1 前导程序 71
- 4.2 字符串简介 72
- 4.2.1char类型数组和null字符 72
- 4.2.2使用字符串 73
- 4.2.3strlen()函数 74
- 4.3 常量和C预处理器 76
- 4.3.1const限定符 78
- 4.3.2明示常量 78
- 4.4printf()和scanf() 80
- 4.4.1printf()函数 80
- 4.4.2使用printf() 81
- 4.4.3printf()的转换说明修饰符 83
- 4.4.4转换说明的意义 87
- 4.4.5使用scanf() 92
- 4.4.6printf()和scanf()的*修饰符 95
- 4.4.7printf()的用法提示 97
- 4.5 关键概念 98
- 4.6 本章小结 98
- 4.7 复习题 99
- 4.8 编程练习 100
- 第5章 运算符、表达式和语句 103
- 5.1 循环简介 103
- 5.2 基本运算符 105
- 5.2.1赋值运算符:= 105
- 5.2.2加法运算符: 107
- 5.2.3减法运算符:- 107
- 5.2.4符号运算符:-和 107
- 5.2.5乘法运算符:* 108
- 5.2.6除法运算符:/ 110
- 5.2.7运算符优先级 110
- 5.2.8优先级和求值顺序 112
- 5.3 其他运算符 113
- 5.3.1sizeof运算符和size_t类型 113
- 5.3.2求模运算符:% 114
- 5.3.3递增运算符: 115
- 5.3.4递减运算符:-- 118
- 5.3.5优先级 118
- 5.3.6不要自作聪明 119
- 5.4 表达式和语句 120
- 5.4.1表达式 120
- 5.4.2语句 120
- 5.4.3复合语句(块) 123
- 5.5 类型转换 124
- 5.6 带参数的函数 127
- 5.7 示例程序 129
- 5.8 关键概念 130
- 5.9 本章小结 130
- 5.10复习题 131
- 5.11编程练习 134
- 第6章 C控制语句:循环 137
- 6.1 再探while循环 137
- 6.1.1程序注释 138
- 6.1.2C风格读取循环 139
- 6.2while语句 140
- 6.2.1终止while循环 140
- 6.2.2何时终止循环 141
- 6.2.3while:入口条件循环 141
- 6.2.4语法要点 141
- 6.3 用关系运算符和表达式比较大小 143
- 6.3.1什么是真 144
- 6.3.2其他真值 145
- 6.3.3真值的问题 146
- 6.3.4新的_Bool类型 147
- 6.3.5优先级和关系运算符 148
- 6.4 不确定循环和计数循环 150
- 6.5for循环 151
- 6.6 其他赋值运算符: =、-=、*=、/=、%= 155
- 6.7 逗号运算符 156
- 6.8 出口条件循环:do while 159
- 6.9 如何选择循环 161
- 6.10嵌套循环 162
- 6.10.1程序分析 163
- 6.10.2嵌套变式 163
- 6.11数组简介 164
- 6.12使用函数返回值的循环示例 166
- 6.12.1程序分析 168
- 6.12.2使用带返回值的函数 169
- 6.13关键概念 169
- 6.14本章小结 170
- 6.15复习题 170
- 6.16编程练习 174
- 第7章 C控制语句:分支和跳转 177
- 7.1if语句 177
- 7.2if else语句 179
- 7.2.1另一个示例:介绍getchar()和putchar() 180
- 7.2.2ctype.h系列的字符函数 182
- 7.2.3多重选择else if 184
- 7.2.4else与if配对 186
- 7.2.5多层嵌套的if语句 187
- 7.3 逻辑运算符 190
- 7.3.1备选拼写:iso646.h头文件 191
- 7.3.2优先级 192
- 7.3.3求值顺序 192
- 7.3.4范围 193
- 7.4 一个统计单词的程序 194
- 7.5 条件运算符:?: 196
- 7.6 循环辅助:continue和break 198
- 7.6.1continue语句 198
- 7.6.2break语句 200
- 7.7 多重选择:switch和break 202
- 7.7.1switch语句 204
- 7.7.2只读每行的首字符 205
- 7.7.3多重标签 206
- 7.7.4switch和if else 208
- 7.8goto语句 208
- 7.9 关键概念 211
- 7.10本章小结 211
- 7.11复习题 212
- 7.12编程练习 214
- 第8章 字符输入/输出和输入验证 217
- 8.1 单字符I/O:getchar()和putchar() 217
- 8.2 缓冲区 218
- 8.3 结束键盘输入 219
- 8.3.1文件、流和键盘输入 219
- 8.3.2文件结尾 220
- 8.4 重定向和文件 222
- 8.5 创建更友好的用户界面 226
- 8.5.1使用缓冲输入 226
- 8.5.2混合数值和字符输入 228
- 8.6 输入验证 230
- 8.6.1分析程序 234
- 8.6.2输入流和数字 234
- 8.7 菜单浏览 235
- 8.7.1任务 235
- 8.7.2使执行更顺利 235
- 8.7.3混合字符和数值输入 237
- 8.8 关键概念 240
- 8.9 本章小结 240
- 8.10复习题 241
- 8.11编程练习 241
- 第9章 函数 243
- 9.1 复习函数 243
- 9.1.1创建并使用简单函数 244
- 9.1.2分析程序 245
- 9.1.3函数参数 247
- 9.1.4定义带形式参数的函数 248
- 9.1.5声明带形式参数函数的原型 249
- 9.1.6调用带实际参数的函数 249
- 9.1.7黑盒视角 250
- 9.1.8使用return从函数中返回值 250
- 9.1.9函数类型 252
- 9.2ANSI C函数原型 253
- 9.2.1问题所在 253
- 9.2.2ANSI的解决方案 254
- 9.2.3无参数和未指定参数 255
- 9.2.4函数原型的优点 256
- 9.3 递归 256
- 9.3.1演示递归 256
- 9.3.2递归的基本原理 258
- 9.3.3尾递归 258
- 9.3.4递归和倒序计算 260
- 9.3.5递归的优缺点 262
- 9.4 编译多源代码文件的程序 262
- 9.4.1UNIX 263
- 9.4.2Linux 263
- 9.4.3 DOS命令行编译器 263
- 9.4.4Windows和苹果的IDE编译器 263
- 9.4.5使用头文件 263
- 9.5 查找地址:&运算符 267
- 9.6 更改主调函数中的变量 268
- 9.7 指针简介 269
- 9.7.1间接运算符:* 270
- 9.7.2声明指针 270
- 9.7.3使用指针在函数间通信 271
- 9.8 关键概念 274
- 9.9 本章小结 275
- 9.10 复习题 275
- 9.11编程练习 276
- 第10章 数组和指针 277
- 10.1数组 277
- 10.1.1初始化数组 277
- 10.1.2指定初始化器(C99) 281
- 10.1.3给数组元素赋值 282
- 10.1.4数组边界 282
- 10.1.5指定数组的大小 284
- 10.2多维数组 284
- 10.2.1初始化二维数组 287
- 10.2.2其他多维数组 288
- 10.3指针和数组 288
- 10.4函数、数组和指针 290
- 10.4.1使用指针形参 293
- 10.4.2指针表示法和数组表示法 294
- 10.5指针操作 295
- 10.6保护数组中的数据 298
- 10.6.1对形式参数使用const 299
- 10.6.2 const的其他内容 300
- 10.7指针和多维数组 302
- 10.7.1指向多维数组的指针 304
- 10.7.2指针的兼容性 305
- 10.7.3函数和多维数组 306
- 10.8变长数组(VLA) 309
- 10.9复合字面量 312
- 10.10关键概念 314
- 10.11本章小结 315
- 10.12复习题 316
- 10.13编程练习 317
- 第11章 字符串和字符串函数 321
- 11.1表示字符串和字符串I/O 321
- 11.1.1在程序中定义字符串 322
- 11.1.2指针和字符串 328
- 11.2字符串输入 329
- 11.2.1分配空间 329
- 11.2.2不幸的gets()函数 330
- 11.2.3gets()的替代品 331
- 11.2.4scanf()函数 336
- 11.3字符串输出 337
- 11.3.1puts()函数 338
- 11.3.2fputs()函数 339
- 11.3.3printf()函数 339
- 11.4自定义输入/输出函数 340
- 11.5字符串函数 342
- 11.5.1strlen()函数 342
- 11.5.2strcat()函数 343
- 11.5.3strncat()函数 345
- 11.5.4strcmp()函数 346
- 11.5.5strcpy()和strncpy()函数 351
- 11.5.6sprintf()函数 356
- 11.5.7其他字符串函数 357
- 11.6字符串示例:字符串排序 359
- 11.6.1排序指针而非字符串 360
- 11.6.2选择排序算法 361
- 11.7ctype.h字符函数和字符串 362
- 11.8命令行参数 363
- 11.8.1集成环境中的命令行参数 365
- 11.8.2Macintosh中的命令行参数 365
- 11.9把字符串转换为数字 365
- 11.10关键概念 368
- 11.11本章小结 368
- 11.12复习题 369
- 11.13编程练习 371
- 第12章 存储类别、链接和内存管理 373
- 12.1存储类别 373
- 12.1.1作用域 374
- 12.1.2链接 376
- 12.1.3存储期 376
- 12.1.4自动变量 377
- 12.1.5寄存器变量 380
- 12.1.6块作用域的静态变量 381
- 12.1.7外部链接的静态变量 382
- 12.1.8内部链接的静态变量 386
- 12.1.9多文件 386
- 12.1.10存储类别说明符 387
- 12.1.11存储类别和函数 389
- 12.1.12存储类别的选择 389
- 12.2随机数函数和静态变量 390
- 12.3掷骰子 393
- 12.4分配内存:malloc()和free() 396
- 12.4.1free()的重要性 399
- 12.4.2calloc()函数 400
- 12.4.3动态内存分配和变长数组 400
- 12.4.4存储类别和动态内存分配 401
- 12.5ANSI C类型限定符 402
- 12.5.1const类型限定符 403
- 12.5.2volatile类型限定符 404
- 12.5.3restrict类型限定符 405
- 12.5.4_Atomic类型限定符(C11) 406
- 12.5.5旧关键字的新位置 406
- 12.6 关键概念 407
- 12.7本章小结 407
- 12.8复习题 408
- 12.9编程练习 409
- 第13章 文件输入/输出 413
- 13.1与文件进行通信 413
- 13.1.1文件是什么 413
- 13.1.2文本模式和二进制模式 413
- 13.1.3I/O的级别 415
- 13.1.4标准文件 415
- 13.2标准I/O 415
- 13.2.1检查命令行参数 416
- 13.2.2fopen()函数 416
- 13.2.3 getc()和putc()函数 417
- 13.2.4文件结尾 418
- 13.2.5fclose()函数 419
- 13.2.6指向标准文件的指针 419
- 13.3一个简单的文件压缩程序 419
- 13.4文件I/O:fprintf()、fscanf()、fgets()和fputs() 421
- 13.4.1fprintf()和fscanf()函数 421
- 13.4.2fgets()和fputs()函数 422
- 13.5随机访问:fseek()和ftell() 423
- 13.5.1fseek()和ftell()的工作原理 424
- 13.5.2二进制模式和文本模式 425
- 13.5.3可移植性 425
- 13.5.4fgetpos()和fsetpos()函数 426
- 13.6标准I/O的机理 426
- 13.7其他标准I/O函数 427
- 13.7.1int ungetc(int c, FILE *fp)函数 427
- 13.7.2int fflush()函数 428
- 13.7.3int setvbuf()函数 428
- 13.7.4二进制I/O:fread()和fwrite() 428
- 13.7.5size_t fwrite()函数 429
- 13.7.6size_t fread()函数 430
- 13.7.7int feof(FILE *fp)和int ferror(FILE *fp)函数 430
- 13.7.8一个程序示例 430
- 13.7.9用二进制I/O进行随机访问 433
- 13.8关键概念 435
- 13.9本章小结 435
- 13.10复习题 435
- 13.11编程练习 437
- 第14章 结构和其他数据形式 439
- 14.1示例问题:创建图书目录 439
- 14.2建立结构声明 441
- 14.3定义结构变量 441
- 14.3.1初始化结构 442
- 14.3.2访问结构成员 443
- 14.3.3结构的初始化器 443
- 14.4结构数组 444
- 14.4.1声明结构数组 446
- 14.4.2标识结构数组的成员 447
- 14.4.3程序讨论 447
- 14.5嵌套结构 448
- 14.6指向结构的指针 449
- 14.6.1声明和初始化结构指针 450
- 14.6.2用指针访问成员 451
- 14.7向函数传递结构的信息 451
- 14.7.1传递结构成员 451
- 14.7.2传递结构的地址 452
- 14.7.3传递结构 453
- 14.7.4其他结构特性 454
- 14.7.5结构和结构指针的选择 458
- 14.7.6结构中的字符数组和字符指针 458
- 14.7.7结构、指针和malloc() 459
- 14.7.8复合字面量和结构(C99) 462
- 14.7.9伸缩型数组成员(C99) 463
- 14.7.10匿名结构(C11) 465
- 14.7.11使用结构数组的函数 466
- 14.8把结构内容保存到文件中 467
- 14.8.1保存结构的程序示例 468
- 14.8.2程序要点 470
- 14.9链式结构 471
- 14.10联合简介 472
- 14.10.1使用联合 472
- 14.10.2匿名联合(C11) 473
- 14.11枚举类型 474
- 14.11.1enum常量 475
- 14.11.2默认值 475
- 14.11.3赋值 475
- 14.11.4enum的用法 476
- 14.11.5共享名称空间 477
- 14.12typedef简介 478
- 14.13其他复杂的声明 479
- 14.14函数和指针 481
- 14.15关键概念 487
- 14.16本章小结 487
- 14.17复习题 488
- 14.18编程练习 490
- 第15章 位操作 493
- 15.1二进制数、位和字节 493
- 15.1.1二进制整数 494
- 15.1.2有符号整数 494
- 15.1.3二进制浮点数 495
- 15.2其他进制数 495
- 15.2.1八进制 495
- 15.2.2十六进制 496
- 15.3C按位运算符 496
- 15.3.1按位逻辑运算符 497
- 15.3.2用法:掩码 498
- 15.3.3用法:打开位(设置位) 498
- 15.3.4用法:关闭位(清空位) 499
- 15.3.5用法:切换位 499
- 15.3.6用法:检查位的值 500
- 15.3.7移位运算符 500
- 15.3.8编程示例 501
- 15.3.9另一个例子 503
- 15.4位字段 505
- 15.4.1位字段示例 506
- 15.4.2位字段和按位运算符 509
- 15.5对齐特性(C11) 515
- 15.6关键概念 516
- 15.7本章小结 516
- 15.8复习题 517
- 15.9编程练习 518
- 第16章 C预处理器和C库 521
- 16.1翻译程序的第一步 521
- 16.2明示常量:#define 522
- 16.2.1记号 525
- 16.2.2重定义常量 525
- 16.3在#define中使用参数 525
- 16.3.1用宏参数创建字符串:#运算符 527
- 16.3.2预处理器黏合剂:##运算符 528
- 16.3.3变参宏:...和_ _VA_ARGS_ _ 529
- 16.4宏和函数的选择 530
- 16.5文件包含:#include 531
- 16.5.1头文件示例 531
- 16.5.2使用头文件 533
- 16.6其他指令 534
- 16.6.1#undef指令 534
- 16.6.2从C预处理器角度看已定义 534
- 16.6.3条件编译 535
- 16.6.4预定义宏 539
- 16.6.5#line和#error 540
- 16.6.6#pragma 540
- 16.6.7泛型选择(C11) 541
- 16.7内联函数(C99) 542
- 16.8_Noreturn函数(C11) 544
- 16.9C库 544
- 16.9.1访问C库 544
- 16.9.2使用库描述 545
- 16.10数学库 546
- 16.10.1三角问题 547
- 16.10.2类型变体 548
- 16.10.3tgmath.h库(C99) 550
- 16.11通用工具库 550
- 16.11.1exit()和atexit()函数 550
- 16.11.2qsort()函数 552
- 16.12断言库 556
- 16.12.1assert的用法 556
- 16.12.2_Static_assert(C11) 557
- 16.13string.h库中的memcpy()和memmove() 558
- 16.14可变参数:stdarg.h 560
- 16.15关键概念 562
- 16.16本章小结 562
- 16.17复习题 562
- 16.18编程练习 563
- 第17章 高级数据表示 567
- 17.1研究数据表示 567
- 17.2从数组到链表 570
- 17.2.1使用链表 572
- 17.2.2反思 576
- 17.3抽象数据类型(ADT) 576
- 17.3.1建立抽象 577
- 17.3.2建立接口 578
- 17.3.3使用接口 581
- 17.3.4实现接口 583
- 17.4队列ADT 589
- 17.4.1定义队列抽象数据类型 590
- 17.4.2定义一个接口 590
- 17.4.3实现接口数据表示 591
- 17.4.4测试队列 598
- 17.5用队列进行模拟 600
- 17.6链表和数组 605
- 17.7二叉查找树 608
- 17.7.1二叉树ADT 608
- 17.7.2二叉查找树接口 609
- 17.7.3二叉树的实现 611
- 17.7.4使用二叉树 624
- 17.7.5树的思想 628
- 17.8其他说明 629
- 17.9关键概念 630
- 17.10本章小结 630
- 17.11复习题 630
- 17.12编程练习 631
- 附录A 复习题答案 633
- 附录B 参考资料 665
- B.1 参考资料I:补充阅读 665
- B.2 参考资料II:C运算符 667
- B.3 参考资料III:基本类型和存储类别 671
- B.4 参考资料IV:表达式、语句和程序流 675
- B.5 参考资料V:新增C99和C11的ANSI C库 679
- B.6 参考资料VI:扩展的整数类型 714
- B.7 参考资料VII:扩展字符支持 716
- B.8 参考资料VIII:C99/C11数值计算增强 720
- B.9 参考资料IX:C和C 的区别 726