《C++程序设计原理与实践》笔记 第4章 计算

本章将介绍一些与计算相关的基本概念。

4.1 计算

程序所做的事情就是计算(compute),即接受输入、产生输出。

程序

从编程的角度看,最重要也是最有趣的两类输入、输出是“从其他程序输入/输出”和“从程序的其他部分输入/输出”。本书后续的大部分内容可以视为后一种类型的实例:在协作完成一个大的软件时,应该如何合理地设计程序结构,并能够保证每一个子程序之间都能够正确地共享和交互数据?这是编程的核心问题。

大的程序

其中I/O是"input/output"的缩写,一部分代码的输出是下一部分代码的输入。代码之间的数据共享可以通过内存、硬盘或者网络完成。

4.2 目标和工具

程序员的任务就是将计算表达出来,并且做到正确、简单、高效。一个输出错误结果的快速程序是没有任何意义的。同样,一个正确、高效但是非常复杂的程序,最终的结果往往是被放弃或者重写。为了适应不同的需求和硬件环境,有用的程序总会被无数次改写。因此,一个程序,或者它的任一子程序,应该以尽可能简单的方式来实现。

在我们开始编写代码的时候,就要特别关注这三个基本原则,这也是专业程序员的最重要职责。

组织程序的主要工具是把一个大的计算任务划分为许多小任务。这一技术主要包括两类方法:

  • 抽象(abstraction):将使用一个功能不需要了解的实现细节隐藏在接口之后。例如,为了实现电话簿的排序,不需要了解排序算法的细节,只需要调用C++标准库的sort函数即可。
  • 分治(divide and conquer):将一个大的问题分为几个小问题分别解决。例如,为了建立一个字典,可以将这一任务分为三个子任务:读取数据、排序和输出数据。

如果你一心想构建能长久留存的东西,就应该在设计过程中对代码结构和组织投入更多关注,而不是在发生错误后再被迫回过头来学习。

4.3 表达式

表达式(expression)是程序的最基本组成单元。表达式从多个操作数(operand)计算一个值。最简单的表达式是字面值(literal value),例如10'a'3.14"Norah"

变量名也是一种表达式,表示与名字对应的那个对象。例如:

// compute area:
int length = 20;
int width = 40;
int area = length * width;

注意:变量名用于赋值运算符左边和右边的含义是不同的。在初始化(或赋值)语句中,length在左边,表示“名为length的对象”(length左值(lvalue));在计算面积的表达式中,length在右边,表示“名为length的对象的值”(length右值(rvalue))。下图可以更清楚地解释这个概念:

整型对象

上图表示了一个名为length的整型对象,其值为99。当length是左值时,表示这个对象本身;当length是右值时,表示这个对象的值。

可以使用运算符组合表达式得到更复杂的表达式,例如:

int perimeter = (length + width) * 2;

运算符有优先级,可以使用括号改变默认优先级。例如,a*b+c/d表示(a*b)+(c/d)a*(b+c)/d表示(a*(b+c))/d

使用括号的第一原则是“如果对运算符优先级不确定,就用括号”。当然,要尽量熟悉优先级规则,像a*b+c/d这种简单的表达式还加括号的话,无疑会降低程序的可读性。

绝对不要在程序中使用非常复杂的表达式,例如a*b+c/d*(e-f/g)/h+7

4.3.1 常量表达式

程序中经常会用到常量。C++提供了符号常量(symbolic constant),即初始化后就不能再赋值的命名对象。例如:

const double pi = 3.14159;
pi = 7;              // error: assignment to const
int v = 2 * pi / r;  // OK: we just read pi; we don't try to change it

使用常量一方面能够维护程序的可读性,例如看到299792458或2.54可能无法猜到它的含义;另一方面方便修改,如果要求把pi的精度提高到12位有效数字,则只需修改常量pi的定义即可。

除个别情况外(例如0和1),程序中应该尽量少用字面值,而是使用有意义名字的符号常量。像2.54这种不能直接识别含义的字面值通常称为魔数(magic number),要避免使用魔数。

常量表达式(constant expression)仅由符号常量和字面值组成。例如:

const int max = 17;
int val = 19;

max+2  // a constant expression: a const plus a literal
val+2  // not a constant expression: it uses a variable

4.3.2 运算符

下表是最常用的运算符:

运算符名称
f(a)函数调用(function call)
a[b]下标(subscription)
++a递增(increment)
--a递减(decrement)
!a逻辑非(logical NOT)
-a负(unary minus)
a*b乘(multiplication)
a/b除(division)
a%b余数(remainder)
a+b加(addition)
a-b减(subtraction)
a<<b左移(left shift)或输出
a>>b右移(right shift)或输入
a<b小于(less than)
a<=b小于等于(less than or equal)
a>b大于(greater than)
a>=b大于等于(greater than or equal)
a==b等于(equal)
a!=b不等于(not equal)
a&&b逻辑与(logical AND)
a||b逻辑或(logical OR)
a=b赋值(assignment)
a+=b复合赋值(Compound assignment)

完整列表:Operators

其中,递增、递减和赋值运算符要求a是左值。复合运算符a+=b等价于a=a+b,对-*/%等运算符同理。

注意比较运算符不能连用,表达式a<b<c意味着(a<b)<c,而a<b的结果是布尔值:truefalse,因此表达式a<b<c的值等于true<cfalse<c,这显然是错误的。要想表达“b的值是否介于a和c之间”应该使用a<b && b<c

增量表达式有以下三种形式:++aa+=1a=a+1。建议使用第一种形式,因为它直观地表达了增量的含义。类似地,建议使用a*=scale而不是a=a*scale

4.3.3 类型转换

表达式中允许存在不同的数据类型,例如2.5/2。对于目前遇到的数据类型,转换规则是:如果运算符的一个操作数是double类型,则进行浮点算术运算,结果为double;否则进行整型算术运算,结果为int。例如:

  • 5/2结果是2(不是2.5)
  • 2.5/2意味着2.5/double(2),结果是1.25
  • 'a'+1意味着int('a')+1,结果是98

其中运算符T(v)表示将值v转换为T类型。

注意,在包含浮点操作数的表达式中容易忘记整数除法。例如,摄氏温度与华氏温度的转换公式为: f = 9 / 5 ∗ c + 32 f=9/5*c+32 f=9/5c+32,但以下代码是错误的:

double c;
cin >> c;
double f = 9/5 * c + 32;  // beware!

因为9/5的值是1而不是1.8(乘法和除法运算符是从左到右结合的,9/5*c等价于(9/5)*c,而括号中是整数除法)。应该将9或5(或二者)转换为double类型:9.0/5 * c + 32

4.4 语句

C++通过语句(statement)来实现循环、条件判断、输入输出等功能。

目前已经见过两种语句:表达式语句和声明。表达式语句(expression statement)是以分号结尾的表达式。例如:

a = b;
++b;

注意,表达式语句需要“起作用”(即包含赋值、I/O、函数调用等操作),单纯计算一个值而没有使用结果的表达式语句是没有用的,例如:

1+2;
a*b;

4.4.1 选择语句

C++的选择(selection)语句包括if语句和switch语句。

4.4.1.1 if语句

if语句是最简单的选择语句,一般形式为

if (表达式)
    语句1
else
    语句2

如果表达式为真则执行语句1,否则执行语句2,else部分是可选的。

注:

  • 括号中的条件还可以是一个带初始值的变量声明语句,变量的值必须能够转换为bool。例如:
// Base* bp;
if (Derived* p = dynamic_cast<Derived*>(bp))
    p->f();
  • C++17引入了带有初始化的if语句,可以在if语句的作用域内声明一个变量。例如:
// map<int, string> m;
if (auto it = m.find(10); it != m.end())
    cout << it->second << endl;

C++中并没有else-if语句,但可以通过在else部分使用另一条if语句来实现:

if (表达式1)
    语句1
else if (表达式2)
    语句2
else
    语句3

下面的程序执行厘米和英寸之间的转换:

厘米-英寸转换

注意:如果判断单位的if语句写成if (unit == 'i') ... else ...,则只是区分了'i'和其他所有情况,而没有专门针对'c'进行判断。此时如果用户输入错误的单位(例如15f),则会执行else部分,即厘米到英寸的转换,而这个结果是错误的。

我们必须始终使用错误的输入来测试程序,因为无法避免用户(有意或无意的)错误输入,程序应该能够正确处理。

试一试

4.4.1.2 switch语句

上面示例中unit'i''c'的比较是最常见的选择形式:基于一个值与多个常量比较的选择。因此C++专门提供了一个语句:switch语句,一般形式为

switch (表达式) {
    case 常量表达式1:
        语句1
    case 常量表达式2:
        语句2
    ...
    default:
        语句n
}

关键字switch后括号中的值与一组常量进行比较,每个常量在一个case标签之后。如果该值与某一常量相等,将执行该case后的语句,通常每个case都以break结束;如果该值与任何常量都不相等,则执行default后的语句。

default不是必需的,但建议加上,除非你能够完全确定列出了所有可能的分支。注意,编程将教会你世界上没有绝对确定的事情。

利用switch语句可以将前面的程序改写为:

厘米-英寸转换(switch)

4.4.1.3 switch技术细节

  • switch语句括号中的值必须是整数、字符或枚举类型,不能是字符串
  • case标签后的值必须是常量表达式,不能使用变量
  • 不能在两个case标签中使用相同的值
  • 可以多个case标签使用相同的语句(见下面的示例)
  • 不要忘记在每个case末尾加上break,注意编译器不会给出任何警告

如果希望对多个值采取同样的操作,只需在语句前加上多个case标签即可,而不是重复写同样的代码。例如:

switch (a) {
    case '0': case '2': case '4': case '6': case '8':
        cout << "is even\n";
        break;
    case '1': case '3': case '5': case '7': case '9':
        cout << "is odd\n";
        break;
    default:
        cout << "is not a digit\n";
        break;
}

使用switch语句最常犯的错误是忘记在case末尾加上break。在前面switch版本的单位转换程序中,如果删除两个break语句,则编译器不会报错,但是当执行完case 'i'的代码后,会接着执行case 'c'的代码。如果输入"2i",程序将输出

2in == 5.08cm
2cm == 0.787402in

注:这种情况术语叫作"fallthrough",通常是一个逻辑错误,只有在多个case使用相同操作的情况下是有用的(例如上面判断奇偶数的程序)

试一试

4.4.2 循环语句

循环(repetition/loop)语句用于重复执行某些操作,在对数据结构的一系列元素进行同样处理时也称为迭代(iteration)。

4.4.2.1 while语句

世界上第一台能存储程序的计算机(EDSAC)上运行的第一个程序就是一个循环,其目的是打印一个简单的平方数表:

0	0
1	1
2	4
3	9
4	16
...
98	9604
99	9801

每一行是一个数字,后面跟着一个制表符(tab, '\t'),然后是该数的平方。该程序的C++版本如下:

打印平方数表(while)

其中square(i)是计算平方的函数,在4.5节介绍。

while语句的一般形式为

while (表达式)
    语句

每次循环开始时判断循环条件(括号中的表达式)是否成立,如果成立则执行循环体(后面的语句),之后进入下一次循环;否则结束循环。循环条件使用循环变量来控制,while语句的循环变量必须在while语句之前定义和初始化。

在上面的例子中,while语句的循环变量是i,循环条件是i < 100,循环体输出平方数表的一行,并将i的值加1。由于i的初始值为0,因此循环体将执行100次(i依次取值0~99,循环结束时i的值为100)。

编写循环语句的关键是循环条件的设置和所有变量的初始化。

试一试

4.4.2.2 程序块

用大括号{}括起来的语句序列称为程序块(block)或复合语句(compound statement)。程序块也是一种语句。

注:上面示例中while语句的循环体就是包含两条语句的程序块,如果不加大括号,则循环体只包含输出语句(这将导致死循环,因为循环变量的值没有改变):

while (i < 26)
    cout << char('a' + i) << '\t' << ('a' + i) << '\n';
    ++i;

等价于

while (i < 26) {
    cout << char('a' + i) << '\t' << ('a' + i) << '\n';
}
++i;

缩进只影响代码的可读性,对编译器没有任何作用。

4.4.2.3 for语句

对数字序列(例如0~9)进行迭代非常普遍,因此C++提供了专门的语法——for语句,将循环变量的控制集中放在开头,便于阅读和理解。其语法如下:

for (初始化; 循环条件; 表达式)
    语句

首先执行初始化部分;每次循环开始时判断循环条件,如果成立则执行循环体和表达式(一般用于递增循环变量),之后进入下一次循环;否则结束循环。for语句等价于以下while语句:

初始化;
while (循环条件) {
    语句
    表达式;
}

除非循环体中包含continue语句。

注:

  • break语句用于直接退出循环
  • continue语句用于直接开始下一次循环,对于while语句是执行测试部分,对于for语句是执行循环变量递增部分

使用for语句打印平方数表的示例如下:

打印平方数表(for)

当一个循环的初始化、循环条件和递增操作都很简单时,使用for语句会使代码更容易理解和维护;否则才使用while语句。

注意:不要在for语句的循环体内修改循环变量的值。 虽然这种操作没有语法错误,但它违背了读者对于循环的普遍理解。

试一试

4.5 函数

函数(function)是一个命名的语句序列,能够返回计算结果(称为返回值(return value))。函数定义(function definition)的语法如下:

返回值类型 函数名(参数表) {
    函数体
}

其中参数表(parameter list)的每一个元素称为参数(parameter)或形式参数(formal argument)。函数体(function body)是实现具体功能的程序块,使用return语句返回结果。

标准库提供了许多有用的函数,也可以编写自己的函数。“打印平方数表”示例中,square函数定义如下:

// return the square of x
int square(int x) {
    return x * x;
}

定义表示这是一个名为square的函数,接受一个int参数(名为x),返回一个int

函数调用(function call)的语法如下:

函数名(参数表)

其中参数表的每一个元素称为实际参数(argument/actual argument)。函数调用的结果是一个返回值类型的表达式,可以用在任何允许使用该类型表达式的地方(例如变量初始化、其他表达式、函数参数等)。

例如,在上面的示例的输出语句中,表达式square(i)使用实际参数i调用了square函数,整体是一个int值。

在调用函数时,必须严格按照函数的定义传递参数(参数个数及类型必须完全一致),否则编译器会给出错误信息。例如:

square(2);               // probably a mistake: unused return value
int v1 = square();       // error: argument missing
int v2 = square;         // error: parentheses missing
int v3 = square(1, 2);   // error: too many arguments
int v4 = square("two");  // error: wrong type of argument – int expected

参数表可以为空,如果不需要返回任何结果,返回值类型可以设置为void。例如:

// take no argument; return no value
void write_sorry() {
    cout << "Sorry\n";
}

4.5.1 使用函数的原因

当需要将一部分计算任务独立实现时,可以将其定义为一个函数,因为这样可以:

  • 使计算逻辑分离
  • 使代码更清晰(通过使用函数名)
  • 在程序中可以多次使用该函数
  • 简化测试

计算平方的函数square看起来没有必要(可以直接使用表达式x * x代替),这只是因为该函数很简单。对于求平方根的函数sqrt,其实现代码很长、很复杂,而使用函数不需要了解求平方根的实现细节,只需要知道sqrt(x)返回x的平方根就可以了。

如果想让主函数中的循环更简单,可以将程序改写为

int print_square(int v) {
    cout << v << '\t' << v * v << '\n';
}

int main() {
    for (int i = 0; i < 100; ++i)
        print_square(i);
    return 0;
}

之所以不使用print_square()是因为:

  • print_square()是一个比较特殊的函数,以后很难再次用到它,而square()可以多次使用
  • square()几乎不需要任何说明文档,而print_square()显然需要解释

根本原因是print_square()执行了两个逻辑上独立的操作:计算平方和输出结果。如果每个函数只完成单一的操作,那么程序将更易于编写和理解。

试一试:

int square(int x) {
    int s = 0;
    for (int i = 1; i <= x; ++i)
        s += x;
    return s;
}

4.5.2 函数声明

注意到调用函数所需的所有信息(返回值类型、函数名和参数表)都已经包含在函数定义的第一行。例如,看到int square(int x)就可以写出int x = square(44);,而不需要看函数体。

大多数情况下,我们只关心如何调用函数。C++提供了一种将该信息与函数定义分离的方法,称为函数声明(function declaration)。例如:

int square(int);      // declaration of square
double sqrt(double);  // declaration of sqrt

注意,函数声明以分号结束(代替了函数定义中的函数体部分),形式参数名可以省略。

如果想使用某个函数,只需要写出该函数的声明(通常是通过#include语句),而该函数的定义可以在程序的其他部分。函数声明和定义的分离对于大型程序是至关重要的,因为这使得读者不必阅读大部分(函数定义)代码,而专注于程序的一部分。

4.6 向量

在编写程序之前,首先要准备好相关的数据。最简单、最常用的数据存储形式是向量(vector)。

向量是可以通过索引(index)访问的元素序列。例如,下面是一个名为v的向量:

向量

其中,第一个元素的索引是0,第二个是1,以此类推。可以通过向量名加元素的索引(下标)来引用一个元素,例如v[0]的值是5,v[1]的值是7,等等。向量元素的索引从0开始,每次加1。图中特别强调了向量“知道自己的大小”,即向量不仅存储元素,也存储它的大小(元素个数)。

可以像这样创建一个向量:

vector<int> v = {5, 7, 9, 4, 6, 8};  // vector of 6 ints

注:

  • C++11之后才有这种初始化语法
  • 使用向量需要包含标准库头文件<vector>

创建一个向量需要指定元素类型和初始元素的集合。元素类型在vector后的尖括号(<>)中,在这里是int。下面是另一个示例:

vector<string> philosopher = {"Kant", "Plato", "Hume", "Kierkegaard"};  // vector of 4 strings

向量元素可以像普通变量一样使用和赋值,只能存储向量所声明的元素类型的值:

v[1] = 99;      // OK
v[2] = "Hume";  // error: trying to assign a string to an int

也可以通过指定大小和初始值来创建向量,如果未指定初始值则使用元素类型的默认值,如果未指定大小则创建一个空向量。例如:

vector<int> v;                  // empty vector
vector<int> vi(6);              // vector of 6 ints initialized to 0
vector<string> vs(4);           // vector of 4 strings initialized to ""
vector<double> vd(1000, -1.2);  // vector of 1000 doubles initialized to -1.2

注意不能引用一个不存在的元素(例如vd[20000]),否则将导致运行时错误。

4.6.1 遍历向量

注:第一版书中没有这一节

可以这样打印向量的元素:

for (int i = 0; i < v.size(); ++i)
    cout << v[i] << '\n';

v.size()返回向量v的元素个数,size()是向量的一个成员函数。由于索引从0开始,因此向量元素的索引范围是[0, v.size())(这种左闭右开区间在C++标准库中普遍使用)。

从C++11开始,可以使用更简单的基于范围的for循环(range-based for loop)来遍历一系列元素(例如向量的元素):

for (int x : v)  // for each x in v
    cout << x << '\n';

4.6.2 增长向量

在使用向量时,一般是从空向量开始,根据需要逐步添加数据。这里的关键操作是push_back(),它将一个新元素添加到向量结尾。例如:

vector<double> v;  // v is empty
v.push_back(2.7);  // v == {2.7}, v.size() == 1
v.push_back(5.6);  // v == {2.7, 5.6}, v.size() == 2
v.push_back(7.9);  // v == {2.7, 5.6, 7.9}, v.size() == 3

push_back是向量的另一个成员函数。

成员函数(member function)调用的语法如下:

对象名.成员函数名(参数表)

向量类似于C语言中的数组,但不需要事先指定大小,而且可以往向量中添加任意多个元素。

4.6.3 一个数值计算的例子

我们经常会把一系列数据读入程序来处理,例如根据数据绘制图形、计算平均值和中位数、找出最大值、排序、查找、与其他数据结合、与其他数据比较等。在做各种处理之前,首先要把数据读入内存中。下面的程序读取一系列温度数据(事先不知道有多少个),并计算平均值和中位数:

计算温度的平均值和中位数

其中,读取循环每次读取一个double并添加到向量结尾。使用读取操作cin >> temp作为循环条件,如果正确读取了一个值,则cin >> temptrue,否则为false。因此while循环将读取所有double,直到读到其他类型的数据为止(例如字符 ‘|’)。任何非double类型的数据都可以作为输入结束的标志,也可以使用EOF终止输入(见3.5.1节)。

为了计算平均值,只需将所有元素累加到sum中,然后除以元素个数(temps.size())即可。

为了计算中位数,需要先将元素排序,这里使用了标准库排序算法sort()(定义在头文件<algorithm>中)。sort()的两个参数分别是待排序元素序列的开始和结束位置(左闭右开),向量的成员函数begin()end()分别返回这两个位置。温度数据排好序之后,求中位数就很简单了:假设元素个数是n,如果n为奇数,则中位数是索引为n/2的元素;如果n为偶数,则中位数是索引为n/2-1n/2的两个元素的平均数。例如:

n=5: 0 1 [2] 3 4
n=4: 0 [1 2] 3

注:该程序没有检查向量为空的情况,此时计算中位数会导致下标越界

4.6.4 一个文本处理的例子

下面的例子建立一个简单的字典:

简单字典

输入一些单词(空白符分隔的字符串),程序将按字典序输出这些单词,同时删除重复的单词。

如何停止字符串输入?在读取数字时,可以通过输入非数值字符来结束输入。但在这里不行,因为所有的(普通字符)都可以被读入字符串。可以利用“非普通”的字符——EOF(见3.5.1节),在Windows中使用Ctrl+Z,在UNIX中使用Ctrl+D。

判断重复单词的语句检查前一个单词是否与当前单词相同(words[i - 1] != words[i])),如果不同就输出这个单词,否则不输出。显然,第一个单词(i == 0)不存在前一个单词,因此单独判断。两个条件使用或运算符(||)组合起来。

注意,字符串的关系运算符(<>等)使用字典序,因此"Ape""Apple""Chimpanzee"之前。

试一试

简单练习

长度统计

习题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为编写实际的应用程序做好准备:无论你是为了进行软件开发还是进行其他领域的工作。《C++程序设计原理实践(英文版)》假定你的最终目标是学会编写实际有用的程序。以基本概念和基本技术为重点:与传统的C++教材相比,《C++程序设计原理实践(英文版)》对基本概念和基本技术的介绍更为深入。这会为你编写有用、正确.易维护和有效的代码打下坚实的基础。, 用现代C++语言编程:, 《C++程序设计原理实践(英文版)》一方面介绍了通用的程序设计方法(包括面向对象程序设计和泛型程序设计)。另一方面还对软件开发实践使用最广泛的程序设计语言——C++进行了很好的介绍。《C++程序设计原理实践(英文版)》从开篇就开始介绍现代C++程序设计技术,并介绍了大量关于如何使用C++标准库来简化程序设计的内容。, 适用于初学者以及任何希望学习新知识的人:, 《C++程序设计原理实践(英文版)》主要是为那些从未编写过程序的人编写的。而且已经由超过1000名大学一年级新生试用过。不过,对于专业人员和高年级学生来说,通过观察公认的程序设计大师如何处理编程的各种问题。同样也会获得新的领悟和指引。, 提供广阔的视野:, 《C++程序设计原理实践(英文版)》第一部分非常广泛地介绍了基本程序设计技术,包括基本概念、设计和编程技术、语言特性以及标准库。这些内容教你如何编写具有输入、输出、计算以及简单图形显示等功能的程序。《C++程序设计原理实践(英文版)》第二部分则介绍了一些更专门性的内容(如文本处理和测试),并提供了大量的参考资料。
 本书是经典程序设计思想与C++开发实践的完美结合,是C++之父回归校园后对C++编程原理和技巧的全新阐述。书全面地介绍了程序设计基本原理,包括基本概念、设计和编程技术、语言特性以及标准库等,教你学会如何编写具有输入、输出、计算以及简单图形显示等功能的程序。此外,本书通过对C++思想和历史的讨论、对经典实例(如矩阵运算、文本处理、测试以及嵌入式系统程序设计)的展示,以及对C语言的简单描述,为你呈现了一幅程序设计的全景图。   ·C++初学者的权威指南。无论你是从事软件开发还是其他领域的工作,本书将为你打开程序开发之门。   ·高级程序员的必备参考。通过观察程序设计大师如何处理编程的各种问题,使你获得新的领悟和指引。   ·全面阐释C++基本概念和技术。与传统的C++教材相比,本书对基本概念和技术的介绍更为深入,为你编写实用、正确、易维护和有效的代码打下坚实的基础。   ·强调现代C++编程风格。本书从开篇就介绍现代C++程序设计技术,并揭示了大量关于如何使用C++标准库来简化程序设计原理,使你快速掌握实用编成技巧。 图书目录   出版者的话   译者序   前言   第0 致读者   第1 计算机、人与程序设计   第一部分 基本知识   第2 Hello,World!   第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 C语言   术语表   参考书目   第五部分 附录?   附录A C++语言概要   附录B 标准库概要   附录C Visual Studio简要入门教程   附录D 安装FLTK   附录E GUI实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值