这是一部C/C++语言的基础语法教程,面向零基础的初学者。C++是在C语言的基础上做了部分修改和扩展的程序设计语言。本书的前半部分(1~19章)主要是C语言部分,而后半部分(20~31章)则是C++对C语言的扩展。
本书从实际工程需要出发,介绍一个C/C++从业人员所必须掌握的全部语法、核心概念和基本技能,消除了学习考试与实际工作之间的差距。书中不仅介绍函数、指针、结构体、类等基本语法,也介绍了传值与传地址、字符串、深拷贝与浅拷贝、动态创建对象、安全地使用指针、面向对象编程思想等核心概念。同时,书中还讲解初级程序员所必须掌握的知识和技术,如单步调试、编码规范、ANSI函数库、文件操作、标准模板库STL的使用。
本书配备免费的全套视频教程、在线题库及解析,可结合纸质教材同步使用,书中的近三百个示例的源码,以及所有相关资料均可在http://afanihao.cn上获取。
作为一个有十余年软件开发背景的从业人员,作者在招聘面试中发现,现在的绝大多数应聘者往往缺少基本的语法基础和实际的动手能力,更不用说对核心概念的理解了。这似乎表明现有的教材或教育方法,与实际的工作要求之间存在着比较严重的脱节。
因此,作者希望创建一套全新的、完整的、综合性的教学体系,让学员能够打下牢固的语法基础,建立对核心概念的正确认识,并掌握基本的动手能力。这套体系包含纸质教程、视频教程、在线题库、进阶教程4大要素。
本书是目标体系的一个组成部分,它也可以独立地使用。就这部纸质教材的特点来说,有以下几点。
1. 主次分明
C/C++的语法繁多,有些语法是过时的,有些语法很难但工作中并不常用。为了避免给初学者带来不必要的干扰,书中对非重点的章节采用星号标注,并显式地说明这个章节是不重要的、或者是过时的、或者是第一遍学习的时候可以跳过的。
2. 引例
在开始讲解每一章之前,通常会有一个引例,其作用是引起读者对某个背景问题的思考。引例描述了一个语法产生的背景,使读者自然而然地理解本章引入的新概念。
3. 铺垫与衔接
本书各章节前后逻辑相承,一环连接一环。读者只要按顺序学习,就可以很容易地从最简单的概念过渡到复杂的概念。最终的效果是,读者会感觉整个学习过程中没有太难的东西。值得强调的是,如果读者不按顺序学习,则学习难度会加倍。例如,如果读者不学习第3、4、5章,则难以读懂第8、9、10章。反之,如果按顺序学习则可以不知不觉地通过。
本书在编排上注重衔接。例如,第19章起承上启下的作用,使读者可以很容易地从C语言的struct过渡到C++的class。
4. 动手能力
第16、17章中介绍了标准C函数库的使用,第30章介绍了标准模板库的使用,它们都是实际工作中所必须掌握、常用而且重要的知识。
同时,在正文及附录中加强对读者动手能力的培训,强调良好的编码规范,强调自己动手建立项目,并掌握调试技术。
5. 核心概念
C/C++中的核心概念包括“传值与传地址”“字符串”“深拷贝与浅拷贝”“动态创建对象”“安全地使用指针”“面向对象编程思想”等。实际上,如果不深刻理解这些核心概念,就无法写出正确的程序。所以,本书在合适的位置讲解了这些概念,使得读者不必再搜寻别的辅导教材,就可以在学习基本语法的同时掌握这些核心概念。
6. 示例丰富
本书中给出了近三百个示例,为了保证示例的正确性,每个示例都经过作者验证,并且可以在网站(http://afanihao.cn,可扫描二维码)上获取完整的示例源码。
7. 丰富的配套资源
1) 在线题库
使用在线题库的方式提供习题,习题按四星级标注,一星为基本练习,三星最难,四星为工业级应用题。每题配备提示、答案或解析,使得读者可以检验自己的思路是否合理。
2) 配套视频
配套100集免费视频教程,令学习更加高效和轻松。
3) 源代码下载
近三百个示例源代码免费共享,轻松编写程序。
4) 进阶学习
读者在学习完本书的基本语法之后,可以选择继续学习进阶类教程,使自己具备一个软件开发从业人员的各项基本素质。
5) 答疑与讨论区
以在线的形式提供答疑与讨论区,具体信息请在http://afanihao.cn上获取。
感谢我的父母、姐姐、哥哥,我的爱人和孩子,感谢他们对我的全力支持。
感谢邵动、邵字红、石广文、李新华、李特梅、姜满如、沈锋平、周建东、郑宇、杨波参与了部分编写工作。
感谢我的老师,张明凤、王善良、周国林、辛燕君、王守玉、申文甲、王羽、王殿兵、郭全、晋宗华、胡振仙、邹明光、顾秉林、朱小梅、李淑琴、张仰森等在我成长之路上对我的栽培。
感谢我的朋友,艾本仁、白建峰、陈刚、陈希、丁将、符汪洋、顾元凯、葛国锋、关正伟、刘星、刘庆生、罗晓宇、裴勇、裴郊区、王浩、邵安馨、石天泽、王静竞、杨浩杰、杨猛、杨禹等给我的帮助。
感谢网友,涂兆昊(神奇的人鱼)、李若滕、伊文斯、张松华(non)、李显发(李小明)、李睿意(lry)、王浩然(连心线)、李显(江南暮春)、卢阿旺(authur)、黄文海(ggev)、神奇海螺、黑夜的忧伤、李泽铭(角逐新梦想)、蔡万成(by)、张强(玄白)、吴霄(stra)、崔祥祥、邓志光等在本教程开发过程中所起的作用。
邵发
2015年8月于北七家
第1章开始学习C/C++
1.1开发平台
1.2第一个程序
1.2.1代码解析
1.2.2在Windows XP环境下的问题
1.2.3常见的问题
1.3代码与程序
1.4C语言和C++语言
第2章控制台输入与输出
2.1控制台输出
2.1.1输出整数
2.1.2用变量表示整数
2.1.3指定显示宽度
2.1.4输出小数
2.1.5用变量表示小数
2.1.6指定小数点后的位置
2.2控制台输入
2.2.1输入整数
2.2.2输入小数
2.2.3一次输入多个数
2.3注释
2.4空白
2.5常见问题
2.6综合例题
第3章变量与常量
3.1变量
3.1.1变量的定义
3.1.2变量的命名
3.1.3变量的赋值
3.2整型变量
3.2.1char / short / int类型
3.2.2unsigned无符号类型
3.2.3*bool布尔类型
3.2.4*enum枚举类型
3.2.5*long long长整数类型
3.3浮点型变量
3.4数的进制表示
3.4.1数的十进制表示
3.4.2数的十六进制表示
3.4.3数的二进制表示
3.5变量与内存
3.5.1二进制存储
3.5.2内存
3.5.3变量的大小
3.5.4变量在内存中的表示
3.5.5变量的地址
3.5.6理解变量的赋值
3.6const常量
3.7*字面常量
3.8常用类型的范围
第4章数组
4.1引例
4.2数组的定义
4.2.1数组的命名
4.2.2数组的长度
4.3数组的基本使用方法
4.3.1数组的初始值
4.3.2访问数组中的元素
4.3.3用sizeof取得数组的大小
4.4数组的内存视图
4.5常见问题
4.6数组的使用实例
4.6.1实例1
4.6.2实例2
4.6.3实例3
4.6.4实例4
4.7多维数组
4.7.1二维问题的表示
4.7.2二维数组的定义
4.7.3二维数组的初始化
4.7.4二维数组的本质
第5章字符与字符数组
5.1字符是什么
5.2字符的表示
5.3字符的显示
5.4字符常量
5.5字符数组
5.5.1输出字符串
5.5.2输入字符串
5.5.3理解结束符的作用
5.5.4字符串的截断
5.5.5常见问题
5.6转义字符
5.6.1转义字符的概念
5.6.2转义字符的使用举例
第6章表达式与操作符
6.1算术表达式
6.2赋值表达式
6.2.1左值
6.2.2理解赋值运算
6.2.3赋值与算术运算合并
6.2.4等号串连的写法
6.3关系表达式
6.4条件表达式
6.5逻辑表达式
6.6逗号表达式
6.7自增/自减操作符
6.8*位操作符
6.8.1按位表示
6.8.2位运算规则
6.8.3移位操作
6.8.4应用举例
6.8.5例题: 把unsigned int整数转为4个字节
6.9类型的转换与提升
6.10优先级与结合顺序
6.10.1使用括号
6.10.2常用的优先级
第7章语句
7.1什么叫语句
7.2if语句
7.2.1使用复合语句
7.2.2最简形式if
7.2.3完全形式if…else if…else if…else
7.3switch语句
7.3.1匹配
7.3.2跳转与执行
7.3.3注意事项
7.4for语句
7.4.1引例
7.4.2使用for语句
7.4.3变形1: 省略初始表达式
7.4.4变形2: 省略第二个表达式
7.4.5变形3: 省略后置表达式
7.4.6变形4: 全部置空
7.4.7存在break语句
7.4.8存在continue语句
7.5while语句
7.5.1变形: 条件判断内置
7.5.2例题
7.6do…while语句
7.7综合例题1
7.8综合例题2
第8章函数
8.1引例
8.2初步认识函数
8.3函数的定义
8.3.1函数名
8.3.2参数列表
8.3.3返回值类型
8.3.4函数的实现
8.3.5return语句的用法
8.4函数的调用
8.4.1函数的调用过程
8.4.2参数的顺序
8.4.3函数的传值调用
8.4.4忽略返回值
8.4.5直接使用返回值
8.5全局变量和局部变量
8.6变量的作用域与生命期
8.6.1变量的作用域
8.6.2变量的生命期
8.7变量名重名问题
8.8函数声明与函数定义
8.8.1函数的声明
8.8.2函数声明相关问题
8.9main函数
8.10参数的隐式转换
8.11*函数名重载
8.12*重载函数的匹配
8.12.1精确匹配
8.12.2模糊匹配
8.13*参数的默认值
8.14*内联函数
8.15*函数的递归调用
第9章指针
9.1内存地址的表示
9.2指针的概念
9.3星号操作
9.4指针与数组
9.4.1指针加减法
9.4.2指针与数组的转换
9.5指针作为函数的参数
9.6数组作为函数的参数
9.7指针作为函数的返回值
9.8const指针
9.9void*型指针
9.10安全地使用指针
9.11*二重指针
9.12*二维数组与指针
9.12.1作为函数的参数
9.12.2二维数组与指针的转换
第10章结构体
10.1引例
10.2结构体概述
10.3结构体的基本用法
10.3.1变量定义和初始化
10.3.2访问结构体的成员
10.3.3定义结构体数组
10.4结构体的内存视图
10.4.1结构体的成员
10.4.2对齐与填充
10.5结构体的更多用法
10.5.1结构体的赋值
10.5.2结构体指针
10.5.3作为函数的参数
10.5.4作为函数的返回值
10.5.5作为结构体的成员
10.6*结构体的特殊写法
10.6.1没有类型名
10.6.2函数内部的结构体类型
10.6.3紧凑的形式
10.6.4C语言中的struct定义
10.7结构体的命名
10.8传值与传地址
10.9*位字段bitfield
10.10实例
第11章*联合体
11.1概念
11.2进一步理解union
11.3实例
11.4union的替代方案
第12章动态分配内存
12.1引例
12.2动态分配内存
12.3内存管理器与堆
12.4对象的生命期
12.5实例1
12.6实例2
12.7常见问题
第13章链表
13.1概念
13.2链表的构造
13.2.1头节点与末节点
13.2.2链表头的作用
13.2.3常见问题
13.3有头链表
13.3.1概念
13.3.2定义一个有头链表
13.3.3添加一个节点
13.3.4有头链表的遍历
13.3.5按顺序插入节点
13.3.6查找和删除节点
13.3.7和无头链表的比较
第14章引用
14.1引用的定义
14.2与指针的区别
14.3简单的例子
14.4作为函数的参数
14.5作为函数的返回值
14.6const引用
第15章字符串
15.1字符串的三种形式
15.2字符串常量的多行表示
15.3字符串与普通数据
15.4字符串的遍历
15.5字符串长度
15.6字符串复制
15.7字符串比较
15.8字符串插入和删除
15.8.1删除字符
15.8.2插入字符
15.8.3插入和删除的效率问题
15.9字符串的分割
15.10用数组还是用指针
第16章标准C函数库
16.1stdio.h
16.2math.h
16.3time.h
16.3.1time_t
16.3.2struct tm
16.3.3time取得系统当前时间
16.3.4localtime得到年月日时分秒
16.3.5mktime构造时间
16.4stdlib.h
16.5string.h
第17章文件操作
17.1认识文件
17.2保存数据
17.2.1fopen打开文件
17.2.2fclose关闭文件
17.2.3fwrite写入数据
17.3读取数据
17.4数据的存储格式
17.5存储格式: 按字节存储
17.5.1指针指向的对象
17.5.2RunLength Encoding存储
17.6存储格式: 文本化存储
17.6.1fprintf按行格式化写入
17.6.2fgets按行读取
17.7文件的随机访问
17.7.1fseek随机访问
17.7.2文件位置指示器
17.7.3随机访问示例
17.7.4fseek的物理限制
17.7.5文件被重复打开的情况
17.8*文件打开模式
17.9*常见问题
第18章多文件项目及编译过程
18.1extern
18.1.1extern声明全局函数
18.1.2extern声明全局变量
18.1.3深入理解extern
18.2多文件项目的生成
18.2.1第一阶段: 编译
18.2.2第二阶段: 链接
18.2.3*用伪代码表示整个过程
18.2.4全量编译与增量编译
18.3头文件#include指令
18.3.1为什么需要头文件
18.3.2使用头文件
18.3.3#include指令的原理
18.3.4头文件的重复包含问题
18.3.5头文件里的内容
18.4宏定义#define指令
18.4.1#define一个数值
18.4.2#define一个算式
18.4.3几个常见的宏定义
18.5条件编译指令#if
18.5.1#if…#endif
18.5.2#ifdef…#endif
18.5.3解决头文件重复包含的问题
18.6*main函数的参数和返回值
18.6.1main函数的参数
18.6.2main函数的返回值
18.7*static的用法
18.7.1static修饰变量
18.7.2static修饰函数
第19章面向对象编程
19.1面向对象设计的过程
19.2实例演示
19.2.1需求与设计
19.2.2写出代码框架
19.2.3实现各个函数接口
19.3封装
第20章类
20.1类和成员变量
20.1.1了解访问修饰符
20.1.2访问修饰符的用法
20.2类和成员函数
20.2.1访问修饰符的限制
20.2.2了解this指针
20.2.3this指针的用法
20.3变量名字的覆盖
20.4命名规范
20.4.1类名的命名规范
20.4.2成员函数的命名规范
20.4.3成员变量的命名规范
20.5类的封装
20.6类的分离式写法
20.7*const对象与const函数
20.7.1const成员函数
20.7.2const版本与非const版本
第21章构造与析构
21.1引例
21.2构造函数
21.2.1重载构造函数
21.2.2构造函数的调用
21.3析构函数
21.3.1析构函数的调用
21.3.2在析构函数中释放资源
21.4自动生成的构造/析构函数
21.5默认构造函数
21.6构造函数的初始化列表
21.6.1参数名与成员变量名可以相同
21.6.2成员本身也是class类型
21.6.3混合使用两种初始化方式
21.6.4必须使用初始化列表的情形
21.7构造与析构的顺序
21.8分离式写法
21.9*无名对象
21.10*构造函数与类型转换
第22章动态创建对象
22.1回顾malloc/free
22.2用new/delete创建/销毁对象
22.3new/delete与malloc/free的区别
22.4为new指定初始化参数
22.5默认构造函数的必要性
22.6注意事项
第23章继承
23.1引例
23.2继承的概念
23.3访问修饰符protected
23.4成员函数的重写
23.5虚拟继承
23.5.1父类指针指向子类对象
23.5.2虚函数virtual
23.5.3virtual析构函数
23.6继承关系下的构造与析构
23.7*多重继承
23.8*继承函数与纯虚类
23.9*以protected/private方式继承
第24章拷贝构造函数
24.1定义
24.2拷贝构造函数的调用
24.3默认的拷贝构造函数
24.4定义拷贝构造函数
24.5深度拷贝
第25章静态成员
25.1static定义全局变量
25.2static定义全局函数
25.3与普通成员的区别
25.4static语法的特点
25.5应用1: 实例计数
25.6应用2: 单例模式
第26章朋友成员
26.1引例
26.2类的朋友
26.3friend的语法
26.4实例
26.5进一步讨论
第27章重载操作符
27.1引例
27.2算术操作符
27.2.1参数类型
27.2.2加法的互换性
27.3赋值操作符=
27.3.1赋以不同的类型
27.3.2深拷贝
27.3.3相关问题及注意事项
27.3.4检查项列表
27.4自增操作符++与自减操作符--
27.5关系操作符
27.6逻辑操作符
27.7类型转换操作符()
27.8元素操作符[]
27.9输入输出操作符>>与<<
27.10操作符new与delete
27.11小结
第28章内部类和名字空间
28.1内部类
28.1.1内部类的语法
28.1.2内部类和普通类的区别
28.1.3内部类的用途
28.1.4内部类的分离式写法
28.1.5内部enum类型
28.2名字空间
28.2.1名字空间的定义
28.2.2分离式写法
28.2.3using语句: 解除前缀
28.2.4名字空间里的其他类型
28.2.5名字空间的应用场景
第29章模板
29.1函数模板
29.2类模板
29.3模板参数
29.4实例
第30章标准模板库
30.1一般使用方法
30.2向量vector
30.2.1at/front/back
30.2.2push_back/pop_back/resize/clear
30.2.3iterator/const_iterator
30.2.4insert/erase
30.3list
30.3.1push_back/pop_back/push_front/pop_front
30.3.2size/clear
30.3.3front/back
30.3.4iterator
30.3.5insert/erase
30.4string
30.4.1append/clear
30.4.2size/capacity/resize/clear/length
30.4.3at
30.4.4字符串比较
30.4.5字符串查找
30.4.6substr
30.4.7insert/replace
30.4.8string作为函数参数
30.5map
30.5.1使用[]插入数据
30.5.2使用insert插入数据
30.5.3查找
30.5.4遍厉
30.5.5删除
30.6stack
30.7queue
第31章异常
31.1一个例子
31.1.1throw
31.1.2try…catch
31.2try的用法
31.3catch的用法
31.3.1匹配所有类型
31.3.2异常必须被捕获
31.4throw的用法
31.5常见问题
31.5.1异常与错误的区别
31.5.2不在构造函数中抛出异常
31.5.3不在析构函数中抛出异常
31.5.4关于finally
附录A用VC2008创建项目
附录B有符号整数与无符号整数
附录C枚举类型
附录DVC2008调试方法
附录EVS2008常见问题汇总
附录F字面常量
附录GASCII码表
附录H位字段
附录Itypedef的用法
附录J编码规范
附录KC++与C语言的区别
附录L二进制、十进制与十六进制