LOADING

加载过慢请开启缓存 浏览器默认开启

C++ Primer Plus

2025/7/7 C++

C++语言入门教程

目录

第一章 预备知识#

本章包括:

  • C语言和C++的发展历史和基本原理
  • 过程性编程和面向对象编程
  • C++是如何在C语言的基础上添加面向对象概念的
  • C++是如何在C语言的基础上添加泛型编程概念的
  • 编程语言标准
  • 创建程序技巧

1.1C++简介#

C++是在C语言基础上开发的一种集面向对象编程、泛型编程和过程化编程为一体的编程语言,是C语言的超集

1.2C++简史#

1.2.1 C语言#

贝尔实验室的Ritchie(UNIX操作系统开发人员)希望有一种语言将低级语言的效率、硬件访问能力和高级语言的通用性、可移植性融合在一起,所以在旧语言的基础上开发了C语言。

1.2.2 C语言编程原理#

程序=数据+算法

C语言是过程性语言,关注算法,即从操作出发构造程序。

使用自顶向下(top-down)设计,将大型程序分解成小型、便于管理的任务

1.2.3 面向对象编程OOP#

强调数据,其理念是设计与问题的本质特性对应的数据格式,在C++中,类是一种规范,描述了这种新型数据格式

OOP程序设计方法首先设计类,它们准确地表示了程序要处理的东西。从低级组织(如类)到高级组织(如程序)的处理过程叫做自下向上(bottom-up)的编程

三大特性:

  • 封装:信息隐藏可以保护数据,免遭不合法的访问
  • 继承:使用旧类派生出新类
  • 多态:为运算符和函数创建多个定义

C++真正的优点之一:可以方便地重用和修改现有的、经过仔细测试的代码

1.2.4 C++和泛型编程#

术语泛型(generic)指的是创建独立于类型的代码:只编写一个泛型函数并将其用于各种实际类型

1.2.5 C++的起源#

也诞生于贝尔实验室(Bjarne Stroustrup’s Homepage)。

名称C++来自于C语言的递增运算符++,表明它是C的扩充版本

C++的二重性:

  • OOP提供了高级抽象
  • C语言提供了低级硬件访问

C++融合了OOP、泛型编程和传统过程性方法,表明C++强调实用价值而非意识形态方法

1.3 可移植性和标准#

在新平台运行时,如果在不修改代码的情况下,重新编译程序后,该程序运行良好,则该程序是可移植的。

在理想情况下,C语言程序都应该是有效的C++程序。

本书重点介绍大多数编译器都支持的特性,并简要总结其它特性

1.4 程序创建的技巧#

1.4.1 创建源文件#

UNIX编译器报错“bad magic number”->后缀不正确

1.4.2 编译和链接#

.c->.o->.out

如果程序违反了语言规则,编译器将生成错误信息,指出存在问题的行,问题可能在标识行之前,一个错误可能引发一连串的错误,所以改正错误时先改正第一个错误,如果在标识行找不到错误就往前找

程序能通过某个编译器的编译不代表它是合法的C++程序,不能通过也不代表非法。有时编译器在不完全构建程序后将出现混乱,显示无法改正、无意义的错误信息

可以使用cin.get()防止辅助窗口过快自动关闭

第二章 开始学习C++#

本章内容包括:

  • 创建C++程序
  • C++程序的一般格式
  • #include编译指令
  • main()函数
  • 使用cout对象进行输出
  • 在C++程序中加入注释
  • 何时以及如何使用endl
  • 声明和使用变量
  • 使用cin对象进行输入
  • 定义和使用简单函数

2.1 进入C++#

C++能够使用printf()、scanf()和其他所有标准C输入和输出函数,只需要包含常规C语言的stdio.h文件即可

2.1.1 main函数#

函数头对函数与程序其他部分之间的接口进行了总结;函数体是指出函数应做什么的计算机指令

C++与C都使用终止符而非分隔符(如FORTRAN使用行尾将语句分隔开来),终止符是一个分号,是语句的结束标志,是语句的组成部分,不是语句之间的标志,故不能省略分号

  1. 作为接口的函数头

    main()被启动代码调用,启动代码是编译器添加到程序中的,是操作系统和程序之间的桥梁

    int main()
    int main(void)

    在C++中,让括号空着与在括号中使用void等效,但在C中,让括号空着意味着对是否接收参数保持沉默

    在main()函数中如果最后没有返回语句则默认return 0,其他函数不适用

  2. 为什么main()不能使用其他名称

·运行C++程序时,通常从main()函数开始运行

常规独立程序均需要main()函数

2.1.2 C++注释#

C++注释以//开头,到行尾结束,可独立一行也可与代码同一行

[!TIP]

应使用注释来说明程序,程序越复杂,注释的价值就越大

[!NOTE]

C++中也包含C 的/* */注释,该注释可跨越多行,但应尽量使用//避免产生问题

2.1.3 C++预处理器和iostream文件(cin)#

#include<iostream>

该编译指令导致预处理器将iostream文件的内容添加到程序中,这是一种典型的预处理器操作:在源代码被编译之前,替换或添加文本

2.1.4 头文件名#

像iostream这样的文件被称为包含文件,因为被包含在其他文件中;也被称为头文件,因为被包含在其他文件起始处

2.1.5 名称空间#

如果使用iostream而非iostream.h则应使用下面的名称空间编译指令来使iostream中的定义对程序可用

using namespace std;

这叫做using编译指令。

名称空间支持是一项C++特性,旨在让您编写大型程序以及多个厂商现有的代码组合起来的程序时更容易,它还有助于组织程序。一个潜在的问题是,可能使用两个已经封装好的产品,而他们都包含一个同名函数,编译器将不知道指的是哪个版本,名称空间让厂商能够将其产品封装在一个叫做名称空间的单元中,这个时候可以使用名称空间来指出想使用哪个厂商的产品

Microflop::wanda("go dancing?");//using Microflop namespace version
Piscine:wanda("a fish named Desire");//using Piscine namespace version

按照这种方式,类、函数、变量便是C++编译器的标准组件,它们现在都放置在名称空间std中,仅当头文件名没有扩展名h时情况才是如此,这意味着在iostream中定义的用于输出的cout变量实际上是std::cout,而endl实际上是std::endl,因此可以省略编译指令using,使用下述方式进行编码

std::cout<<"sdjk";
std::cout << std::endl;

然而多数用户并不喜欢将引入名称空间之前的代码(使用iostream.h和cout)转换为名称空间代码(使用iostream和std::cout)。于是using编译指令产生

using namespace std;//可以使用std名称空间中定义的名称而不必使用std::前缀

这个using指令使得std名称空间中的所有名称都可用,但在大型项目中是一个潜在问题,可以如下只使所需名称可用

using std::cout;//make cout available
using std::endl;//make endl available
using std::cin;//make cin available

2.1.6 使用cout进行C++输出#

cout<<"sidiuw";

<<是一个插入运算符,表示把字符串发送给cout,指出了信息流动的路径,将字符串插入到输出流中;cout是一个预定义的对象,知道如何显示字符串、数字和单个字符

每条cout语句的输出将从前一个输出的末尾开始

[!CAUTION]

<<是一个运算符重载的例子,也可作为按位左移运算符

  1. 控制符endl

    endl:重启一行,在输出流中插入将导致屏幕光标移到下一行开头

    诸如endl等对于cout来说有特殊含义的特殊符号被称为控制符

  2. 换行符

    cout << "\n";

    一个差别是,endl确保程序继续运行前刷新输出(将其立即显示在屏幕上),而是用”“则不能提供这样的保证,这意味着在某些系统中有时可能在输入信息后才会出现提示

    原理:

    1. endl的行为
    • 刷新缓冲区endl不仅插入一个换行符(\n),还会强制刷新输出缓冲区(flush操作)。这意味着无论缓冲区是否已满,当前所有待输出的内容都会立即写入目标设备(如屏幕或文件)。
    • 立即显示:由于刷新操作,用户会立即看到输出内容,不会因为缓冲区未满而延迟显示。
    • 性能影响:频繁使用endl会导致频繁的I/O操作,可能影响程序性能,尤其是在大量输出时。
    1. "\n"的行为
    • 仅插入换行符"\n"仅插入一个换行符,不会触发缓冲区刷新。输出内容会留在缓冲区中,直到缓冲区满、程序结束或显式调用flush时才被实际写入。
    • 延迟显示:在某些系统中(如终端或控制台),如果缓冲区未满且未刷新,后续的输出(如提示信息)可能不会立即显示,导致用户在输入前看不到完整信息,交互混乱。
    • 性能优势:由于不刷新缓冲区,"\n"在大量输出时性能更好

2.1.7 C++源代码的格式化#

不能把空格、制表符或回车放在元素(如名称)中间,也不能把回车放在字符串中间

  1. 源代码中的标记和空白

    一行代码中不可分割的元素叫做标记(token)

    通常必须使用空格、制表符、回车将两个标记分开,空格、制表符、回车统称为空白,有些字符(如逗号括号)是不需要用空白分开的标记

  2. C++源代码风格

    可增加代码易读性

  • 每条语句占一行
  • 每个函数都有一个开始花括号和一个结束花括号,这两个花括号各占一行
  • 函数中的语句都相对于花括号进行缩进
  • 与函数名称相关的圆括号周围没有空白

前三条规则旨在确保代码清晰易读,第四条帮忙区分函数和一些也是用圆括号的C++内置结构,如循环

2.2 C++语句#