小白编程系列(四):C/C++学习路径

前言

C作为最经典的一门编程语言,按照宋丹丹的话讲”那怎么能叫特别强大,那是相当的强大”,它是系统级的编程语言。随便说一些用C语言编写的项目,你就可以知道它的厉害比如Lua、Sqlite、Nginx,都是用它来写的。

如果你选择学习C语言,那你一定是希望将来是一个系统级程序员,而不是仅仅希望自己在应用领域发展。

C/C++

C语言1972年由Dennis Ritchie设计的命令式、结构化范式编程语言,最新国际标准为C99。设计上主要受到了B、ALGOL68、汇编语言、PL/I、FORTRAN的影响,C语言也影响了大量编程语言,如C++、Objective-C、C#、Java、Go、PHP、Python等等。

由于C语言不是面向对象的编程语言,于是就在C语言的基础上发展出了C++,C++可以视为C语言的超集。

C/C++

C/C++编程的学习范围

我们先还是把学习范围说一下,来张脑图先,可以有个大致的概念。

C语言 脑图

由于C/C++的几乎无所不能,我们在这里先简单的罗列一个清单,作为我们学习路径中的选项:

1.C/C++语言基础

2.基础知识储备

3.编辑器和IDE

  • VIM
  • Eclipse CDT
  • Microsoft Visual Studio
  • Code::Blocks
  • CodeLite
  • QT Creator
  • Borland C++ Builder

4.编译器

  • GCC
  • cl.exe
  • Intel C++
  • bcc.exe
  • Clang

5.版本管理

6.测试

  • GTest
  • CxxTest
  • CppUnitTest

7.构建工具

  • CMake

8.库

  • Boost
  • QT
  • MFC
  • OWL

9.操作系统

10.数据库

11.大数据

  • Hadoop/MapReduce/HDFS/HBase/Hive
  • Spark

12.图形与游戏

  • OpenGL
  • Direct X
  • Unity3D
  • Cocos2d

13.物联网/底层开发

  • 单片机/Arduino
  • 嵌入式系统
  • PLC

怎么开始

做C/C++的编程我们还是建议大家,先熟悉操作系统,最好从Liunx系统下开始比较好些,如果你的系统是windows的操作系统可以安装一个虚拟机软件,这样很方便,linux系统现在比较火的就是Ubuntu操作系统;

如果一定要从Windows系统下开始那就用微软系列的产品吧,不管是编辑器、编译器、测试工具、构建工具都打包在一个IDE了,那就是Visual Studio 系列无论是跨平台的Visual Studio Code还是Visual Studio 2015,但是强大的IDE很快就会让学习者进入到需要面对大量信息的界面中,很可能会干扰到你的学习。

当然你也可以直接从我们的在线编程课程C语言基础开始,先试着学习一些语言基础。

不同的操作系统,学习的过程差异会比较大,Linux和Windows是两个不同的体系。Windows是保姆式服务,IDE平台十分强大,在一个IDE下几乎什么事都可以做了。Linux平台下很多东西都需要自己选择安装,真是因为这样,对学习者来说,可以更深刻的理解和学习很多内容及知识。

我们推荐大家选择在Liunx系统下学习,先熟悉操作系统、Shell命令和简单的Shell脚本程序,然后熟悉一下Vim编辑器。通过这些可以使你找到如何面对一个控制终端进行编程的感觉,这很重要!它和使用一个Windows下的IDE有很大的不同,你会感觉到自己像一个真正的geek。

熟悉了操作系统以后就可以开始学习语言了。

首先掌握 C 语言

想要掌握一门语言,最起初的时候都是要先了解它的语法,C语言也不例外,这个不用多说,主要就是多练习,不过C语言的声明、指针、内存管理还是需要花些功夫的思考和理解。

语法完成以后需要花一些时间去学习标准库,例如字符处理、标准IO、通用工具、字符串处理、时间日期等,学习这些基本的库,掌握C语言的本质。

这个过程中还需要熟悉GCC编译器以及构建工具CMake的使用。关于这个过程我们来看一个Linux下C语言编程的简单例子。

在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器。假设我们有下面一个简单源程序(hello.c):

1
2
3
4
5
#include <stdio.h>
int main(int argc,char **argv)
{   
printf("Hello Linux\n");
}

要编译这个程序,我们只要在命令行下执行:

1
gcc -o hello hello.c 

GCC编译器就会为我们生成一个hello的可执行文件。执行

1
./hello

就可以看到程序的输出结果了。

命令行中gcc表示我们是用gcc来编译我们的源程序,-o选项表示我们要求编译器给我们输出的可执行文件名为hello,而hello.c是我们的源程序文件。

Makefile的编写:

假设我们有下面这样的一个程序,源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/* main.c */
#include "mytool1.h"
#include "mytool2.h"
int main(int argc,char **argv)
{
mytool1_print("hello");
mytool2_print("hello");
}

/* mytool1.h */
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif

/* mytool1.c */
#include "mytool1.h"
void mytool1_print(char *print_str)
{
printf("This is mytool1 print %s\n",print_str);
}

/* mytool2.h */
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif

/* mytool2.c */
#include "mytool2.h"
void mytool2_print(char *print_str)
{
printf("This is mytool2 print %s\n",print_str);
}

当然由于这个程序是很短的我们可以这样来编译:

1
2
3
4
gcc -c main.c
gcc -c mytool1.c
gcc -c mytool2.c
gcc -o main main.o mytool1.o mytool2.o  

这样的话我们也可以产生main程序,而且也不是很麻烦。但是如果我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?特别是如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译?

为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make。我们只要执行以下make,就可以把上面的问题解决掉。 在我们执行make之前,我们要先编写一个非常重要的文件。–Makefile。对于上面的那个程序来说,可能的一个Makefile的文件是:

1
2
3
4
5
6
7
8
main:main.o mytool1.o mytool2.o 
gcc -o main main.o mytool1.o mytool2.o    
main.o:main.c mytool1.h mytool2.h   
gcc -c main.c   
mytool1.o:mytool1.c mytool1.h   
gcc -c mytool1.c   
mytool2.o:mytool2.c mytool2.h   
gcc -c mytool2.c   

有了这个Makefile文件,不管我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件它连理都不想去理的。

如果熟悉了这个过程也掌握了我们提到的学习内容那就可以开始学习C++了。

其次学习 C++ 编程

C++的核心是面向对象编程(OOP),通过C++的学习我们能够掌握面向对象编程中最重要的类和对象、构造器、运算符重载等;掌握面向对象编程的三大特性封装、继承和多态;掌握输入输出流、异常处理(Exception)等;

C++的学习将是我们通往精通C/C++语言的一个重要节点。推荐大家通过《C++ Primer》这本经典的书籍来学习。

来看个C++的”hello world”:

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
int main(int argc,char **argv)
{
cout << "Hello world!\n" << endl;
return 0;
}

除了类库和命令外,和C语言没啥区别,面向对象的内容,大家就去自己动手试试吧。

Unix/Linux下编程

Unix下C/C++语言编程的基本思想与普通C/C++语言编程无异,只是加入了大量的系统调用和特殊应用处理。需要学习的范围如下:

  • 静态库和共享库的使用;
  • 内存管理(malloc/brk/mmap);
  • 文件和输入输出设备的系统调用(System Call);
  • 进程管理;
  • 信号处理(signal);
  • 进程间通信(IPC);
  • 网络编程(socket);
  • 多线程开发;多线程同步技术;
  • 套接字(Socket)编程技术;
  • TCP/IP协议、UDP协议、HTTP协议;

Windows系统下编程

Windows下的C/C++编程,相对来说还是比较容易上手的,有Visual Studio系列的IDE工具,很容易就可以开始学习。Windows系统下的编程和Windows操作系统本身的编程思路结合的很紧密,从基本的窗口程序开发、消息机制、进程线程的处理、动态库、内存管理等到MFC、COM组件、ADO、Socket、TCPIP、UDP等。按照这个路线学习就可以了,下面是学习内容的列表:

1.Windows

  • 窗口程序的开发;
  • 消息机制和消息相关函数(Message);
  • 绘图(Paint);
  • 控件开发(Control);
  • 文件管理和目录管理函数;
  • Windows资源的使用;
  • 内存管理(virtual memory);
  • 静态库和动态库(lib/dll);
  • 进程开发;
  • 线程和线程同步;

2.MFC

  • MFC基础;
  • 消息映射和消息处理
  • 菜单、工具栏和视图;
  • 绘图和DC;
  • 集合类;
  • 序列化;
  • 控件;
  • 对话框和属性页;
  • 动态库;
  • 线程;

3.COM组件开发

  • 组件和接口基本概念;
  • COM组件和ATL库的应用;
  • 类厂和组件;
  • 接口调动和接口函数;
  • Automation程序;
  • ActiveX控件的使用;

4.其他

  • 访问数据库技术ADO(ActiveX Data Object);
  • Windows网络基础;
  • 有连接协议(TCP)和无连接协议(UDP);
  • Windows Socket API;
  • MFC Socket编程;

4.算法和数据结构

由于C/C++的编程主要是系统级的所以对于算法和数据结构的要求会比其他的语言要更高一些,所以我们简单的罗列一些算法与数据结构的内容,这些都是应该逐步掌握的。

  • 数据结构的基本概念;
  • 线性结构;
  • 双向链表;
  • 栈和队列;
  • 树和二叉树;
  • 顺序查找法和二分查找法;
  • 排序算法(冒泡、选择、插入、快速);

模版和STL

模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。使用模板的目的就是能够让程序员编写与类型无关的代码。

STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。STL的代码从广义上讲分为三类:Algorithm(算法)、Container(容器)和Iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。

有控制的用好STL会为我们的开发工作带来极大的便利。

  • 模板基本概念(template);
  • 类模板和模板类;
  • 函数模板和模板函数;
  • 类型推断;
  • 类模板和函数模板的特化;
  • 智能指针的实现;
  • 标准模板库(Standard Template Library);
  • STL容器;
  • 迭代器和算法;

再深入

能够掌握上述C/C++编程技能的话,基本上就是一个真正的程序员了。这个时候你需要根据自己的工作方向来选择侧重点,由于C/C++的特点,系统级的开发和硬件编程应该都是潜在的方向。

物联网是现在的一个热门领域,是我们认为的一个重点。其实物联网的概念出现已经很久了,该领域的技术范围几乎可以将所有的信息化技术囊括在内,对C/C++语言来说,是可以涉猎所有领域范围的编程语言。由于C/C++语言对于底层编程的良好支持,物联网中涉及到的很多硬件开发,对C/C++来说十分适用。无论是嵌入式、无线通信、TCP协议、传感器、中间件等等,都是C/C++擅长的领域,这些领域的商业行为对于C/C++的支持也最为强大。

硬件编程中领域很繁杂,但作为基础,大家可以从三个方面的知识入手:

1.QT编程

QT是跨平台C++图形用户界面应用程序开发框架,熟悉这个框架后可以做很多事情。重点是熟练使用QT Creator和Designer进行开发,理解信号和槽的概念和用法。

  • 图形用户程序框架;
  • 基础;
  • 信号和槽;
  • Creator;
  • Designer;
  • QML;
  • 网络编程;
  • 访问数据库(SQL算法,SQLite数据库编程);

2.单片机 单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。 建议大家可以从arduino的学习开始,这个开源硬件平台现在非常火热。

3.嵌入式系统

完全嵌入受控器件内部,为特定应用而设计的专用计算机系统。国内一般定义为:以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。一般是用来控制或者监视机器、装置、工厂等大规模设备的系统。 作为基础可以尝试一些ARM体系相关编程:包括ARM框架基础、指令流水线、MMU原理、ARM指令集、GNU、GPIO控制、各种驱动开发、中断(异常、GIC)系统启动原理等。之后再深入Linux/Android的系统开发:包括bootloader、bsp开发、驱动开发等。

4.图形处理和游戏。

如果希望进入游戏领域那OpenGL、DirectX这两种图形处理接口就是必须学习和掌握的基础;而Unity3D、cocos2d/3d这两种开源的游戏开发框架是应用最多最热门的框架。

OpenGL(全写Open Graphics Library)是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。它用于三维图像(二维的亦可),是一个功能强大,调用方便的底层图形库。

DirectX,(Direct eXtension,简称DX)是由微软公司创建的多媒体编程接口。由C++编程语言实现,遵循COM。被广泛使用于Microsoft Windows、Microsoft XBOX、Microsoft XBOX 360和Microsoft XBOX ONE电子游戏开发,并且只能支持这些平台。

Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。使用其开发的游戏可发布游戏至Windows、Mac、Wii、iPhone、WebGL、Android等多种平台。而且还可以利用Unity web player插件发布网页游戏,支持Mac和Windows的网页浏览。

cocos2d/3d是一个基于MIT协议的开源框架,用于构建游戏、应用程序和其他图形界面交互应用。可以让你在创建自己的多平台游戏时节省很多的时间。

如果大家能够进入到这个阶段的编程,相信你的核心竞争力就非常强悍了,你可以尝试自制操作系统

推荐书目

http://xb.hubwiz.com/

推荐在线课程

C

C++

C/C++ API

C

C++

如果你精通C/C++了,那你就确实成为了一名真正的程序员拯救世界吧,以后全靠你了。。


C/C++ 拯救世界