本书以C语言为编程环境,由浅入深地介绍了C语言的完整内容以及过程化程序设计的思想和方法。全书共有13章。第 1章介绍了什么是程序设计。第 2章给出了一个完整的C语言程序,并介绍了如何在VS2010中输入、编译链接及调试程序。第3~5章分别介绍了C语言中支持结构化程序设计的3种结构:顺序、分支和循环所必需的工具。第6章介绍了如何编写及应用函数;第7章介绍了处理批量数据的工具,即数组。上述章节的内容都是C语言的核心知识,请务必掌握。第8~11章分别讲解了结构体、共用体、链表、位运算和文件等编程技术。第 12章讲解了如何用结构化程序设计思想指导一个大程序的开发,以及软件开发的基本过程。该章中用“猜硬币”游戏介绍了自顶向下分解的过程,用“石头、剪刀、布”游戏介绍了模块划分,用“龟兔赛跑模拟”的例子介绍了如何建立一个自己的库以及如何应用自己创建的库,用学生管理系统和书店管理系统讲述了软件开发的过程。第 13章介绍了通用算法设计技术,旨在让读者了解,当遇到一个问题时应该如何设计解决问题的算法。
本书内容翔实、讲解深入,每个知识点都提供了示例,全书共有171道例题和228个程序样例,所有程序样例都在VS2010中调试通过。为了方便读者自学,本书还提供了118道自测题和141道编程题,以及所有习题的答案,且配套了讲解主要知识点的视频。
本书适合C语言初学者,也适合有一定基础的读者。可作为各高等院校计算机专业的教材,也可供从事计算机软件开发的人员参考。
学习程序设计,初学者往往遇到这样的困境:语言规则可以倒背如流,但写出的代码总是编译通不过,即使编译通过了却也得不出想要的结果。怎么办?《第一行代码 C语言》可以给你提供帮助。
你不需要具备高深的数学和电子学知识,只需要训练自己以计算机能够理解的方式去表达自己的逻辑,也就是要具备“计算思维”,寻找到解决问题的方法,然后用编程语言去指挥计算机执行即可。因此,本书与常规的C语言书不同,除了C语言本身的语法规则外,本书更关注的是培养初学者具有程序设计的思想,掌握程序设计的方法。
另外,计蒜客在线教育团队,为本书的读者提供了伴随式的在线编程平台支持,读者可以将图书和线上编程结合起来学习。
提供扫码看视频服务,全书94个微视频,总时长超过1000分钟。
提供辅助教学资源包,包括实验、试卷及答案、教学大纲、PPT等。
翁惠玉:上海交通大学副教授,“程序设计”“数据结构”和“计算机网络”等课程主讲教师,曾获高等教育教学成果奖一等奖、高等教育教学成果奖二等奖、高等教育上海市级教育成果一等奖等。
第1章 程序设计概述 1
1.1 什么是程序设计 1
1.2 计算机的基本组成 2
1.2.1 计算机硬件 2
1.2.2 计算机软件 4
1.3 程序设计语言 4
1.3.1 机器语言 4
1.3.2 汇编语言 5
1.3.3 高级语言 6
1.3.4 智能语言 7
1.3.5 C语言 7
1.4 程序设计过程 7
1.4.1 算法设计 8
1.4.2 编码 11
1.4.3 编译与链接 11
1.4.4 调试与维护 12
1.5 编程规范及常见问题 13
1.5.1 真的需要算法设计阶段吗 13
1.5.2 为什么不用自然语言编程 13
1.5.3 寄存器、主存储器和外存储器有什么不同 13
1.5.4 所有的计算机能够执行的指令都是相同的吗 13
1.5.5 为什么需要编译和链接 13
1.5.6 为什么在不同类型的计算机上运行C语言程序需要使用不同的编译器 14
1.5.7 为什么不同类型的计算机不能运行同一个汇编程序 14
1.6 小结 14
1.7 自测题 14
1.8 实战训练 15
第2章 初识C语言 16
2.1 一个完整的C语言程序 16
2.1.1 注释 17
2.1.2 预编译 17
2.1.3 主程序 18
2.2 C语言的开发环境 20
2.2.1 VS2010的安装 20
2.2.2 程序输入 20
2.2.3 编译链接 24
2.2.4 程序的运行 25
2.2.5 程序的调试 28
2.3 编程规范及常见问题 30
2.3.1 注意注释 30
2.3.2 良好的排版习惯 30
2.3.3 为什么要学C语言 31
2.3.4 如何学习程序设计 31
2.3.5 什么是库 31
2.4 小结 32
2.5 自测题 32
2.6 实战训练 32
第3章 顺序程序设计 33
3.1 常量与变量 33
3.1.1 变量定义 33
3.1.2 数据类型 35
3.1.3 常量与符号常量 39
3.2 数据的输入/输出 44
3.2.1 字符的输入/输出 44
3.2.2 格式化输入/输出 46
3.3 算术运算 54
3.3.1 算术表达式 54
3.3.2 不同类型数据间的混合运算 56
3.3.3 强制类型转换 57
3.3.4 数学函数库 59
3.4 赋值运算 60
3.4.1 赋值表达式 60
3.4.2 赋值的嵌套 62
3.4.3 复合赋值运算 62
3.4.4 自增和自减运算符 63
*3.5 信息表示 64
3.5.1 数制间的转换 64
3.5.2 整数的表示 66
3.5.3 实数的表示 69
3.6 顺序程序设计示例 69
3.7 程序规范及常见问题 71
3.7.1 变量命名 71
3.7.2 运算符的优先级 71
3.7.3 数据运算时的注意事项 71
3.7.4 为什么要定义符号常量 72
3.7.5 变量定义后且对它赋值前的值是什么 72
3.7.6 不要在表达式中插入有副作用的子表达式 72
3.8 小结 72
3.9 自测题 73
3.10 实战训练 74
第4章 分支程序设计 76
4.1 关系表达式 76
4.2 逻辑表达式 78
4.2.1 逻辑运算 78
4.2.2 短路求值 80
4.3 if语句 82
4.3.1 if语句的形式 82
4.3.2 if语句的嵌套 87
4.3.3 条件表达式 90
4.4 switch语句及其应用 92
4.5 程序规范及常见问题 102
4.5.1 条件语句程序的排版 102
4.5.2 不要连用关系运算符 102
4.5.3 注意短路求值 102
4.5.4 常见错误 102
4.6 小结 103
4.7 自测题 103
4.8 实战训练 104
第5章 循环程序设计 106
5.1 计数循环 106
5.1.1 for语句 106
5.1.2 for语句的进一步讨论 115
5.1.3 for循环的嵌套 116
5.2 break和continue语句 118
5.2.1 break语句 118
5.2.2 continue语句 120
5.3 基于哨兵的循环 121
5.3.1 while语句 122
5.3.2 do…while循环 128
5.4 循环的中途退出 130
5.5 编程规范和常见问题 134
5.5.1 循环语句程序的排版 134
5.5.2 优化循环体 134
5.5.3 使用for循环的注意事项 134
5.5.4 常见错误 134
5.5.5 三个循环语句之间的关系 135
5.6 小结 135
5.7 自测题 135
5.8 实战训练 136
第6章 过程封装——函数 139
6.1 函数的定义 140
6.1.1 函数的基本结构 140
6.1.2 return语句 141
6.1.3 函数示例 141
6.2 函数的使用 144
6.2.1 函数原型的声明 144
6.2.2 函数调用 146
6.2.3 将函数与主程序放在一起 147
6.2.4 函数调用过程 151
6.3 带参数的宏 154
6.4 变量的作用域 155
6.4.1 局部变量 155
6.4.2 全局变量 156
6.5 变量的存储类别 158
6.5.1 自动变量 158
6.5.2 静态变量 159
6.5.3 寄存器变量 160
6.5.4 外部变量 161
*6.6 多源文件程序的编译链接 163
6.7 递归程序设计 164
6.7.1 递归的基本概念 165
6.7.2 递归函数的应用 167
6.8 编程规范及常见问题 173
6.8.1 使用函数时的建议 173
6.8.2 函数命名 174
6.8.3 没有返回值的函数是否需要return语句 174
6.8.4 尽量避免使用全局变量 174
6.8.5 尽量避免实际参数表达式有副作用 175
6.8.6 常见错误 175
6.9 小结 175
6.10 自测题 176
6.11 实战训练 177
第7章 批量数据处理——数组 179
7.1 一维数组 179
7.1.1 一维数组的定义 179
7.1.2 数组元素的引用 180
7.1.3 一维数组的内存映像 184
7.1.4 一维数组的应用 185
7.2 数组作为函数的参数 190
7.3 查找算法 195
7.3.1 顺序查找 196
7.3.2 二分查找 197
7.4 排序算法 201
7.4.1 直接选择排序法 201
7.4.2 冒泡排序法 203
7.5 二维数组 205
7.5.1 二维数组的定义 206
7.5.2 二维数组元素的引用 207
7.5.3 二维数组的内存映像 208
7.5.4 二维数组的应用 208
7.5.5 二维数组作为函数的参数 218
7.6 字符串 220
7.6.1 字符串的存储及初始化 220
7.6.2 字符串的输入/输出 221
7.6.3 字符串作为函数参数 225
7.6.4 字符串处理函数 230
7.6.5 字符串的应用 232
7.7 程序规范及常见问题 234
7.7.1 数组下标必须从0开始吗 234
7.7.2 能用表达式des = src将字符串src赋给字符串des吗 234
7.7.3 为什么存放字符串的数组长度比字符串的实际长度多一个字符235
7.7.4 有了scanf函数为什么还需要gets函数 235
7.7.5 传递字符串为什么只需要一个参数 235
7.7.6 传递二维数组时形式参数中第二个方括号中的值为什么必须指定 235
7.8 小结 235
7.9 自测题 236
7.10 实战训练 237
第8章 指针 240
8.1 指针的概念 240
8.1.1 指针与间接访问 240
8.1.2 指针变量的定义 241
8.1.3 指针变量的操作 242
8.2 指针与数组 246
8.2.1 指向数组元素的指针 246
8.2.2 指针运算与数组访问 246
8.3 指针与函数 250
8.3.1 指针作为参数 250
8.3.2 返回指针的函数 254
8.3.3 数组作为函数参数的进一步讨论 256
8.4 动态内存分配 259
8.4.1 动态变量 259
8.4.2 动态变量的创建 259
8.4.3 动态变量的消亡 261
8.4.4 内存泄露 261
8.4.5 查找malloc和calloc的失误 261
8.4.6 动态变量应用 263
8.5 指针与字符串 265
8.5.1 用指向字符的指针变量表示字符串 265
8.5.2 字符串作为函数的参数 266
8.5.3 返回字符串的函数 268
8.6 指针数组与多级指针 270
8.6.1 指针数组 270
*8.6.2 main函数的参数 272
*8.6.3 多级指针 276
*8.6.4 二维数组与指向一维数组的指针 277
*8.6.5 动态二维数组 279
*8.7 函数指针 280
8.7.1 指向函数的指针 280
8.7.2 函数指针作为函数参数 281
8.7.3 函数指针用于菜单选择 284
8.8 编程规范与常见问题 285
8.8.1 int x, *p = &x;有错吗 285
8.8.2 避免使用悬空指针和未初始化的指针 286
8.8.3 不同类型的指针之间为什么不能赋值 286
8.8.4 指针与数组等价吗 286
8.8.5 值传递和指针传递的区别是什么 286
8.8.6 返回指针的函数必须确保返回值指向的变量在函数执行
结束时依然存在 287
8.8.7 使用动态变量时必须严格防止内存泄露 287
8.9 小结 287
8.10 自测题 288
8.11 实战训练 289
第9章 更多的数据类型 290
9.1 枚举类型 290
9.2 类型别名 293
9.3 结构体 294
9.3.1 结构体的概念 294
9.3.2 结构体类型的定义 295
9.3.3 结构体类型变量的定义 296
9.3.4 结构体类型变量的使用 299
9.3.5 结构体与函数 302
9.4 链表 308
9.4.1 链表的概念 308
9.4.2 单链表的存储 310
9.4.3 单链表的操作 311
9.4.4 带头结点的单链表 312
9.4.5 单链表实例 313
9.5 共用体 316
9.5.1 共用体概念和共用体类型的定义 316
9.5.2 共用体类型变量的定义及初始化 318
9.5.3 共用体变量的使用 318
9.6 编程规范及常见问题 324
9.6.1 结构体中每个字段的类型都不相同吗 324
9.6.2 单链表中为什么要引入头结点 324
9.6.3 引入结构体有什么用处 324
9.6.4 结构体和共用体的区别 324
9.6.5 结构体和共用体类型定义时能否省略类型名 324
9.6.6 结构体类型定义与结构体变量定义 325
9.7 小结 325
9.8 自测题 325
9.9 实战训练 326
第10章 位运算与位段 328
10.1 位运算 328
10.1.1 “按位与”运算 328
10.1.2 “按位或”运算 330
10.1.3 “按位异或”运算 331
10.1.4 “按位取反”运算 333
10.1.5 “左移”运算 335
10.1.6 “右移”运算 335
10.1.7 位运算与赋值运算 337
10.1.8 不同长度的数据进行位运算 337
10.2 位段 338
10.2.1 位段的概念及定义 338
10.2.2 位段的引用 339
10.3 编程规范及常见问题 341
10.3.1 检验某数中指定位的值 341
10.3.2 将数据中的某一位的值置成0 341
10.3.3 将数据中的某一位的值置成1 342
10.3.4 将数据中的某一位的值取反 342
10.4 小结 342
10.5 自测题 342
10.6 实战训练 343
第11章 文件 344
11.1 内存与外存 344
11.2 文件的概念 345
11.2.1 什么是文件 345
11.2.2 ASCII文件与二进制文件 346
11.3 文件缓冲与文件指针 346
11.4 文件的打开与关闭 347
11.4.1 打开文件 347
11.4.2 关闭文件 349
11.5 ASCII文件的读写 349
11.5.1 字符读写函数 350
11.5.2 字符串读写函数 352
11.5.3 数值读写函数 354
11.6 二进制文件的读写 358
11.6.1 fwrite函数 358
11.6.2 fread函数 360
11.7 文件的顺序访问 362
11.7.1 什么是文件的顺序访问 362
11.7.2 feof函数 363
11.8 文件的随机访问 364
11.8.1 文件定位指针 365
11.8.2 rewind函数 365
11.8.3 fseek函数 367
11.8.4 ftell函数 369
*11.9 文件操作与控制台操作 370
11.10 编程规范及常见问题 371
11.10.1 良好的文件使用习惯 371
11.10.2 文件打开方式选择 372
11.10.3 文件指针与文件定位指针 372
11.10.4 流与文件 372
11.11 小结 372
11.12 自测题 373
11.13 实战训练 373
第12章 软件开发过程 374
12.1 结构化程序设计思想 374
12.2 自顶向下分解示例:“猜硬币”游戏 375
12.2.1 顶层分解 375
12.2.2 prn_instruction函数的实现 376
12.2.3 play函数的实现 376
12.2.4 get_call_from_user函数的实现 378
12.3 模块划分示例:“石头、剪刀、布”游戏 380
12.3.1 自顶向下分解 381
12.3.2 模块划分 382
12.3.3 头文件的设计 383
12.3.4 模块实现 386
12.4 设计自己的库示例:随机函数库的设计和实现 389
12.4.1 随机函数库的功能设计 390
12.4.2 接口文件的设计 390
12.4.3 实现文件的设计 391
12.5 随机函数库的应用示例:模拟龟兔赛跑 392
12.5.1 自顶向下分解 392
12.5.2 模块划分及实现 393
12.6 软件开发过程 395
12.6.1 软件危机 395
12.6.2 软件工程 396
12.7 软件开发过程示例:学生管理系统的设计与实现 397
12.7.1 需求分析 397
12.7.2 概要设计 398
12.7.3 详细设计 400
12.7.4 编码与测试 402
12.8 软件开发示例:网上书店的设计 407
12.8.1 需求分析 407
12.8.2 概要设计 408
12.8.3 详细设计 411
12.9 编程规范及常见问题 413
12.9.1 头文件的格式 413
12.9.2 实现一个库为什么需要两个文件 413
12.9.3 慎用全局变量 414
12.10 小结 414
12.11 自测题 414
12.12 实战训练 414
第13章 通用算法设计 416
13.1 枚举法 416
13.2 贪婪法 423
13.3 分治法 427
13.4 动态规划 431
13.5 回溯法 435
13.6 小结 442
13.7 实战训练 442
附录 443
附录1 第1章自测题答案 443
附录2 第2章自测题答案 445
附录3 第3章自测题答案 446
附录4 第4章自测题答案 451
附录5 第5章自测题答案 453
附录6 第6章自测题答案 455
附录7 第7章自测题答案 459
附录8 第8章自测题答案 463
附录9 第9章自测题答案 466
附录10 第10章自测题答案 467
附录11 第11章自测题答案 470
附录12 第12章自测题答案 472
附录13 ASCII编码表 474