C++ Primer Plus 第一章 预备知识————复习总结

1.1 C++简介

C++是一种多功能编程语言,结合了过程性、面向对象和泛型编程。如果你了解C语言,学习C++会更容易,但需要适应新的思维方式。如果不了解C语言,也可以学习C++,但需要学习更多内容。不管你的背景如何,学习C++可能需要一些思维上的扩展,但它提供了更多强大的工具和方法来构建各种应用程序。

1.2 C++简史

计算机技术近几十年来飞速发展,提升了计算和存储能力,让现代设备如笔记本电脑远超过60年代的大型机。编程工具也变得更强大,但管理和维护大型软件仍然是挑战。70年代,C和Pascal引领了结构化编程,80年代,面向对象编程(OOP)兴起,提高了代码可重用性和可维护性。。

1.2.1 C语言

在20世纪70年代早期,Dennis Ritchie在贝尔实验室开发UNIX操作系统时,面临了一项挑战:需要一种能够控制硬件、生成高效程序,并且具备可移植性的编程语言。传统上,程序员使用低级的汇编语言来编写程序,但汇编语言针对特定的计算机架构,不易移植到其他平台。Ritchie希望创建一种语言,结合了汇编语言的效率和高级语言的通用性,以便在不同平台上使用。为解决这一问题,他开发了C语言,一种简洁而高效的编程语言。

C语言允许程序员直接控制硬件,同时具备了跨平台的能力,通过编译器将C代码转换为不同计算机架构的机器码。这使得UNIX操作系统能够在多种计算机上运行,而不需要为每个平台重新编写操作系统的核心部分。因此,C语言的出现在计算机科学领域产生了深远的影响,它成为了一种通用的、可移植的编程语言,同时也是许多其他编程语言的基础。

1.2.2 C语言编程原理

由于C++在C语言的基础上移植了新的编程理念,因此我们首先来看一看C所遵循的旧的理念。一般来说,计算机语言要处理两个概念——数据和算法。数据是程序使用和处理的信息,而算法是程序使用的方法(参见图1.1)。C语言与当前最主流的语言一样,在最初面世时也是过程性(procedural)语言,这意味着它强调的是编程的算法方面。从概念上说,过程化编程首先要确定计算机应采取的操作,然后使用编程语言来实现这些操作。程序命令计算机按一系列流程生成特定的结果,就像菜谱指定了厨师做蛋糕时应遵循的一系列步骤一样。
图1.1

随着程序规模的扩大,早期的编程语言面临了组织和维护的问题,导致程序难以理解和修改。为解决这些问题,计算机科学家发展了结构化编程方法,其中C语言起到了关键作用。结构化编程限制了混乱的分支语句,引入了有序的编程结构,如循环和条件语句。此外,C语言鼓励自顶向下的程序设计,将大型程序分解成小的、易于管理的模块,这些模块可以表示为函数。这些特性使C语言成为一种适合结构化编程的语言,帮助程序员更有效地组织和管理代码。

1.2.3 面向对象编程

面向对象编程(OOP)提供了一种新的编程方法,与过程性编程不同,它强调数据而不是算法。OOP的核心思想是让编程语言适应问题的要求,而不是试图使问题适应语言的方法。在C++中,类是描述新型数据格式的规范,对象是根据这些规范构造的数据结构。类规定了对象的数据表示和操作方法。OOP程序设计方法首先设计类,以准确地表示程序要处理的内容。OOP不仅仅是将数据和方法组合成类,还要设计有用和可靠的类,这是一项具有挑战性的任务。幸运的是,OOP语言允许程序员轻松使用已有的类,包括供应商提供的类库,从而实现了代码重用和修改的便捷性。C++因其支持OOP特性而受欢迎,允许方便地重用和修改现有的经过测试的代码。

1.2.4 C++和泛型编程

泛型编程是C++支持的一种编程模式,它与面向对象编程(OOP)的目标相同,不过OOP强调的是编程的数据方面,而泛型编程强调的是独立于特定数据类型。它们的侧重点不同。OOP用于管理大型项目,而泛型编程提供了处理通用任务(如排序或链表合并)的工具。泛型编程的核心思想是创建与特定数据类型无关的代码,允许编写一次泛型函数并在多种数据类型上使用。C++的模板提供了实现这种功能的机制。泛型编程使代码更灵活和可重用。

1.2.5 C++的起源

与C语言一样,C++也是在贝尔实验室诞生的,Bjarne Stroustrup于20世纪80年代在这里开发出了这种语言。用他自己的话来说,“C++主要是为了我的朋友和我不必再使用汇编语言、C语言或其他现代高级语言来编程而设计的。它的主要功能是可以更方便地编写出好程序,让每个程序员更加快乐”。

Stroustrup之所以在C的基础上创建C++,是因为C语言简洁、适合系统编程、使用广泛且与UNIX操作系统联系紧密。C++的OOP方面是受到了计算机模拟语言Simula67的启发。Stroustrup加入了OOP特性和对C的泛型编程支持,但并没有对C的组件作很大的改动。因此,C++是C语言的超集,这意味着任何有效的C程序都是有效的C++程序

计算机程序将实际问题转化为一系列计算机操作。C++融合了OOP和C的特性,使其既能处理问题概念的联系,又能紧密与硬件交互,这有助于C++的广泛应用。思考方式在不同方面之间切换,有时需要从面向对象编程(OOP)到面向过程编程,或反之。虽然C++是在C语言基础上添加了OOP特性,但忽视这些特性可能会错过许多有用的功能。

C++的模板特性在一定程度的成功后引入,使泛型编程成为可能。模板逐渐被认为与OOP同样重要,甚至有人认为更重要。C++融合了OOP、泛型编程和传统的过程性编程,强调实用性而不是意识形态,这也是C++成功的原因之一。
在这里插入图片描述

名称C++来自C语言中的递增运算符++,该运算符将变量加1。名称C++表明,它是C的扩充版本。

1.3 可移植性和标准

如果您为Windows 2000编写的C++程序使用了特定于硬件的代码,例如直接控制IBM PC视频卡的程序,那么该程序在新平台上可能无法运行,因为硬件不同。要实现可移植性,需要将硬件相关的部分封装在函数模块中,以最大程度地降低可移植性问题。

另一个可移植性障碍是语言方言的差异。不同操作系统和编译器可能有不同的C++实现,因此在重新编译程序时可能需要对代码进行一些修改以适应新的平台。然而,如果遵循C++标准(如ISO/IEC 14882)编写代码,程序应该具有较好的可移植性,只需使用新平台的C++编译器重新编译即可。

C++标准的制定由ANSI和ISO负责,经过多年的努力,制定了多个版本的C++标准,如C++98、C++03、C++11等。这些标准描述了C++语言的特性和规则,有助于确保C++程序在不同平台上的可移植性。不过,仍然需要注意特定平台和编译器的细微差异。

1.3.1 C++的发展

Stroustrup编写的The Programming Language包含65页的参考手册,它成了最初的C++事实标准。

下一个事实标准是Ellis和Stroustrup编写的The Annotated C++ Reference Manual。

C++98标准新增了大量特性,其篇幅将近800页,且包含的说明很少。

C++11标准的篇幅长达1350页,对旧标准做了大量的补充。

1.3.2 本书遵循的C++标准

当代编译器广泛支持C++98标准,而一些编译器也开始支持C++11的特性。我们主要关注C++98,但也会简要介绍C++11的一些新增特性。

本书旨在向读者提供有关C++的基本知识,涵盖了程序创建的基本概念和基础信息。

接下来,我们将开始深入探讨C++编程的各个方面。

1.4 程序创建的技巧

假设您编写了一个C++程序。如何让它运行起来呢?具体的步骤取决于计算机环境和使用的C++编译器,但大体如下
在这里插入图片描述

  • 使用文本编辑器编写程序,并将其保存到文件中,这个文件就是程序的源代码。
  • 编译源代码。这意味着运行一个程序,将源代码翻译为主机使用的内部语言——机器语言。包含了翻译后的程序的文件就是程序的目标代码(object code)。
  • 将目标代码与其他代码链接起来。例如,C++程序通常使用库。C++库包含一系列计算机例程(被称为函数)的目标代码,这些函数可以执行诸如在屏幕上显示信息或计算平方根等任务。链接指的是将目标代码同使用的函数的目标代码以及一些标准的启动代码(startup code)组合起来,生成程序的运行阶段版本。包含该最终产品的文件被称为可执行代码

1.4.1 创建源代码文件

给源文件命名时,必须使用正确的后缀,将文件标识为C++文件。这不仅告诉您该文件是C++源代码,还将这种信息告知编译器。后缀由一个句点和一个或多个字符组成,这些字符被称作扩展名
图1.4

使用什么扩展名取决于C++实现,下面列出了一些常用的扩展名。

C++实现

源代码文件的扩展名

UNIX

C、cc、cxx、c

GNU C++

C、cc、cxx、cpp、c++

Digital Mars

cpp、cxx

Borland C++

cpp

Watcom

cpp

Microsoft Visual C++

cpp、cxx、cc

Freestyle CodeWarrior

cp、cpp、cc、cxx、c++

1.4.2 编译和链接

最初,Stroustrup实现C++时,使用了一个C++到C的编译器程序,而不是开发直接的C++到目标代码的编译器。前者叫作cfront(表示C前端,C front end),它将C++源代码翻译成C源代码,然后使用一个标准C编译器对其进行编译。这种方法简化了向C的领域引入C++的过程。其他实现也采用这种方法将C++引入到其他平台。随着C++的日渐普及,越来越多的实现转向创建C++编译器,直接将C++源代码生成目标代码。这种直接方法加速了编译过程,并强调C++是一种独立(虽然有些相似)的语言。

UNIX编译和链接

最初,UNIX命令CC调用cfront,但cfront未能紧跟C++的发展步伐,其最后一个版本发布于1993年。当今的UNIX计算机可能没有编译器。如果UNIX计算机上有C++编译器,很多情况下命令CC仍然管用,只是启动的编译器随系统而异。

请用CC命令来编译程序。名称采用大写字母,这样可以将它与标准UNIX C编译器cc区分开来。CC编译器是命令行编译器,这意味着需要在UNIX命令行上输入编译命令。

例如,要编译C++源代码文件spiffy.C,则应在UNIX提示符下输入如下命令:

CC spiffy.C

程序没有错误,编译器将生成一个扩展名为o的目标代码文件。在这个例子中,编译器将生成文件spiffy.o。

接下来,编译器自动将目标代码文件传递给系统链接程序,该程序将代码与库代码结合起来,生成一个可执行文件。在默认情况下,可执行文件为a.out。如果只使用一个源文件,链接程序还将删除spiffy.o文件,因为这个文件不再需要了。要运行该程序,只要输入可执行文件的文件名即可:

a.out

注意,如果编译新程序,新的可执行文件a.out将覆盖已有的a.out

在C++中,程序也可以多个文件同时编译:

CC my.C precious.C

如果有多个源代码文件,则编译器将不会删除目标代码文件。这样,如果只修改了my.C文件,则可以用下面的命令重新编译该程序:

CC my.C precious.o

这将重新编译my.C文件,并将它与前面编译的precious.o文件链接起来。

可能需要显式地指定一些库。例如,要访问数学库中定义的函数,必须在命令行中加上-lm标记:

CC usingmath.C -lm

Linux编译和链接

Linux系统中最常用的编译器是g++,g++编译器的工作方式很像标准UNIX编译器。例如,下面的命令将生成可执行文件a.out

g++ spiffy.cxx

有些版本可能要求链接C++库:

g++ spiffy.cxx -lg++

要编译多个源文件,只需将它们全部放到命令行中即可:

g++ my.cxx precious.cxx

这将生成一个名为a.out的可执行文件和两个目标代码文件my.o和precious.o。如果接下来修改了其中的某个源代码文件,如my.cxx,则可以使用my.cxx和precious.o来重新编译:

g++ my.cxx precious.o

Windows命令行编译器

要在Windows PC上编译C++程序,最便宜的方法是下载一个在Windows命令提示符模式(在这种模式下,将打开一个类似于MS-DOS的窗口)下运行的免费命令行编译器。Cygwin和MinGW都包含编译器GNU C++,且可免费下载;它们使用的编译器名为g++。

要使用g++编译器,首先需要打开一个命令提示符窗口。启动程序Cygwin和MinGW时,它们将自动为您打开一个命令提示符窗口。要编译名为great.cpp的源代码文件,请在提示符下输入如下命令:

g++ great.cpp

如果程序编译成功,则得到的可执行文件名为a.exe

Windows编译器

Windows产品很多且修订频繁,无法对它们分别进行介绍。我推荐的是vs code ,也是我自己在使用的编译器。
vs code安装与配置教程

Macintosh上的C++

当前,Apple随操作系统Mac OS X提供了开发框架Xcode,该框架是免费的,但通常不会自动安装。要安装它,可使用操作系统安装盘,也可从Apple网站免费下载(但需要注意的是,它超过4GB)。Xcode不仅提供了支持多种语言的IDE,还自带了两个命令行编译器(g++和clang),可在UNIX模式下运行它们。而要进入UNIX模式,可通过实用程序Terminal

提示:为节省时间,可对所有示例程序使用同一个项目。方法是从项目列表中删除前一个示例程序的源代码文件,并添加当前的源代码。这样可节省时间、工作量和磁盘空间。

Makefile

Makefile 是什么

Makefile是一个用于自动化构建(编译和链接)源代码的工具,特别是对于大型项目而言,它是非常有用的。Makefile包含一组规则和命令,定义了如何构建程序以及如何处理源代码文件之间的依赖关系。

下面是我需要编译链接的3个文件
在这里插入图片描述

我们进行常规的编译和链接

g++ -c  student.cpp -o student.o
g++ -c  use_stu.cpp -o use_stu.o
g++ -o student student.o use_stu.o

但是如果有很多个.h或者.cpp文件,我们编译链接一次是很痛苦的,尤其是我们可能时常需要修改代码,没修改一次,就全部重新编译链接一次,将会极其痛苦。通过执行Makefile,可以避免手动编译很多个源文件和手动管理项目的构建过程。

Makefile的组成

目标(Target):目标是您要构建的输出文件的名称。它可以是可执行文件、库文件或任何其他输出文件。

依赖项(Dependencies):依赖项是构建目标所需的源代码文件或其他目标文件。如果依赖项发生了变化,那么Makefile将重新构建目标。

命令(Commands):命令是构建目标的具体操作步骤。这些命令通常是编译和链接源代码文件以生成目标文件或可执行文件的命令。

Makefile的基本结构如下:
注意:commands前面必须要用tab制表符,不能手动打空格,否则它不能工作

target: dependencies
    commands

Makefile的工作原理

假如咱们要编译链接file1.cpp和file2.cpp

命令行版本
编译链接

g++ file1.cpp file2.cpp -o main.exe

执行

./main.exe

普通版本 缺点大

main.exe: file1.cpp file2.cpp
	g++  file1.cpp file2.cpp -o main.exe

基础的Makefile版本 现在的缺点也大

CXX = g++
TARGET = hello.exe
OBJ = file1.o file2.o

$(TARGET): $(OBJ)
	$(CXX) $(OBJ) -o $(TARGET)

file1.o: file1.cpp
	$(CXX) -c file1.cpp

file2.o: file2.cpp
	$(CXX) -c file2.cpp

更加健全的Makefile 但还是有不小的缺点

CXX = g++
TARGET = hello.exe
OBJ = file1.o file2.o

CXXFLAGS = -c -Wall

$(TARGET): $(OBJ)
	$(CXX) $^ -o $@

%.o: %.cpp
	$(CXX) $(CXXFLAGS) $< -o $@

.PHONY: clean
clean:
	del /Q *.o hello.exe

Makefile程序的配置

最常用的版本就是下面的这个

CXX = g++
TARGET = main.exe 
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp, %.o, $(SRC))

CXXFLAGS = -c -Wall

# all: $(TARGET) clean

$(TARGET): $(OBJ)
	$(CXX) -o $@ $^
	make clean

%.o: %.cpp
	$(CXX) $(CXXFLAGS) $< -o $@
	

.PHONY: clean
clean:
	rm *.o

只要在该目录下有个这个Makefile文件,在该目录用make命令就好

创建Makefile的文件的配置

作用是在创建一个带有Makefile文件的文件夹

$(f):
	mkdir $(f)
	cp "Makefile的文件所在的路径" $(f)

.PHONY: clean
clean:
	rmdir /s /q $(f)

小思考🤔️

这节没有思考,懒得思考,都是一些常识性内容,是一些学习之前的准备工作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值