C++教程 C++ 命名空间 假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。 同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。 因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。 定义命名空间 命名空间的定义使用关键字 namespace,后跟命名空间的名称,如下所示: namespace namespace_name { // 代码声明 } 为了调用带有命名空间的函数或变量,需要在前面加上命名空间的名称,如下所示: name::code; // code 可以是变量或函数 让我们来看看命名空间如何为变量或函数等实体定义范围: #include <iostream> using namespace std; // 第一个命名空间 namespace first_space{ void func(){ cout << "Inside first_space" << endl; } } // 第二个命名空间 namespace second_space{ void func(){ cout << "Inside second_space" << endl; } } int main () { // 调用第一个命名空间中的函数 first_space::func(); // 调用第二个命名空间中的函数 second_space::func(); return 0; } 当上面的代码被编译和执行时,它会产生下列结果: Inside first_space Inside second_space using 指令 您可以使用 using namespace 指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。 #include <iostream> using namespace std; // 第一个命名空间 namespace first_space{ void func(){ cout << "Inside first_space" << endl; } } // 第二个命名空间 namespace second_space{ void func(){ cout << "Inside second_space" << endl; } } using...
2024-04-04
C++ 数据封装 所有的 C++ 程序都有以下两个基本要素: 程序语句(代码):这是程序中执行动作的部分,它们被称为函数。 程序数据:数据是程序的信息,会受到程序函数的影响。 封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。 数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。 C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。例如: class Box { public: double getVolume(void) { return length * breadth * height; } private: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; 变量 length、breadth 和 height 都是私有的(private)。这意味着它们只能被 Box 类中的其他成员访问,而不能被程序中其他部分访问。这是实现封装的一种方式。 为了使类中的成员变成公有的(即,程序中的其他部分也能访问),必须在这些成员前使用 public 关键字进行声明。所有定义在 public 标识符后边的变量或函数可以被程序中所有其他的函数访问。 把一个类定义为另一个类的友元类,会暴露实现细节,从而降低了封装性。理想的做法是尽可能地对外隐藏每个类的实现细节。 数据封装的实例 C++ 程序中,任何带有公有和私有成员的类都可以作为数据封装和数据抽象的实例。请看下面的实例: #include <iostream> using namespace std; class Adder{ public: // 构造函数 Adder(int i = 0) { total = i; } // 对外的接口 void addNum(int number) { total += number; } // 对外的接口 int getTotal() { return total; }; private: // 对外隐藏的数据 int total; }; int main( ) { Adder a; a.addNum(10); a.addNum(20); a.addNum(30); cout << "Total " << a.getTotal() <<endl; return 0; } 当上面的代码被编译和执行时,它会产生下列结果:...
2024-04-04
C++ 多态 多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 下面的实例中,基类 Shape 被派生为两个类,如下所示: #include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } int area() { cout << "Parent class area :" <<endl; return 0; } }; class Rectangle: public Shape{ public: Rectangle( int a=0, int b=0):Shape(a, b) { } int area () { cout << "Rectangle class area :" <<endl; return (width * height); } }; class Triangle: public Shape{ public: Triangle( int a=0, int b=0):Shape(a, b) { } int area () { cout << "Triangle class area :" <<endl; return (width * height / 2); } }; // 程序的主函数 int main( ) { Shape *shape; Rectangle rec(10,7);...
2024-04-04
C++ 引用调用 C++ 函数 向函数传递参数的引用调用方法,把引用的地址复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。 按引用传递值,参数引用被传递给函数,就像传递其他值给函数一样。因此相应地,在下面的函数 swap() 中,您需要声明函数参数为引用类型,该函数用于交换参数所指向的两个整数变量的值。 // 函数定义 void swap(int &x, int &y) { int temp; temp = x; /* 保存地址 x 的值 */ x = y; /* 把 y 赋值给 x */ y = temp; /* 把 x 赋值给 y */ return; } 现在,让我们通过引用传值来调用函数 swap(): #include <iostream> using namespace std; // 函数声明 void swap(int &x, int &y); int main () { // 局部变量声明 int a = 100; int b = 200; cout << "交换前,a 的值:" << a << endl; cout << "交换前,b 的值:" << b << endl; /* 调用函数来交换值 */ swap(a, b); cout << "交换后,a 的值:" << a << endl; cout << "交换后,b 的值:" << b << endl; return 0; } 当上面的代码被编译和执行时,它会产生下列结果: 交换前,a 的值: 100 交换前,b 的值:...
2024-04-04
C++ 变量类型 变量其实只不过是程序可操作的存储区的名称。C++ 中每个变量都有指定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为 C++ 是大小写敏感的。 基于前一章讲解的基本类型,有以下几种基本的变量类型,将在下一章中进行讲解: 类型 描述 bool 存储值 true 或 false。 char 通常是一个八位字节(一个字节)。这是一个字符串类型。 int 对机器而言,整数的最自然的大小。 float 单精度浮点值。 double 双精度浮点值。 void 表示类型的缺失。 wchar_t 宽字符类型。 C++ 也允许定义各种其他类型的变量,比如枚举、指针、数组、引用、数据结构、类等等,这将会在后续的章节中进行讲解。 下面我们将讲解如何定义、声明和使用各种类型的变量。 C++ 中的变量定义 变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示: type variable_list; 在这里,type 必须是一个有效的 C++ 数据类型,可以是 char、w_char、int、float、double、bool 或任何用户自定义的对象,variable_list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明: int i, j, k; char c, ch; float f, salary; double d; 行 int i, j, k; 声明并定义了变量 i、j 和 k,这指示编译器创建类型为 int 的名为 i、j、k 的变量。 变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成,如下所示: type variable_name = value; 下面列举几个实例: extern int d = 3, f = 5; // d 和 f 的声明 int d = 3, f = 5; // 定义并初始化 d 和 f byte z = 22; // 定义并初始化 z char x = 'x'; // 变量 x 的值为 'x' 不带初始化的定义:带有静态存储持续时间的变量会被隐式初始化为 NULL(所有字节的值都是 0),其他所有变量的初始值是未定义的。 C++ 中的变量声明 变量声明向编译器保证变量以给定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。...
2024-04-04
C++ 多线程 多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。在一般情况下,有两种类型的多任务处理:基于进程和基于线程。 基于进程的多任务处理处理的是程序的并发执行。基于线程的多任务处理的是同一程序的片段的并发执行。 多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径。 C++ 不包含多线程应用程序的任何内置支持。相反,它完全依赖于操作系统来提供此功能。 本教程假设您使用的是 Linux 操作系统,我们要使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用,比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。 创建线程 有下面的例程,我们可以用它来创建一个 POSIX 线程: #include <pthread.h> pthread_create (thread, attr, start_routine, arg) 在这里,pthread_create 创建一个新的线程,并让它可执行。这个例程可在代码内的任何地方被调用任意次数。下面是关于参数的说明: 参数 描述 thread 一个不透明的、唯一的标识符,用来标识例程返回的新线程。 attr 一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。 start_routine C++ 例程,一旦线程被创建就会执行。 arg 一个可能传递给 start_routine 的参数。它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。 一个进程可以创建的最大线程数是依赖于实现的。线程一旦被创建,就是同等的,而且可以创建其他线程。线程之间没有隐含层次或依赖。 终止线程 有下面的例程,我们可以用它来终止一个 POSIX 线程: #include <pthread.h> pthread_exit (status) 在这里,pthread_exit 用于显式地退出一个线程。通常情况下,pthread_exit() 例程是在线程完成工作后无需继续存在时被调用。 如果 main() 是在它所创建的线程之前结束,并通过 pthread_exit() 退出,那么其他线程将继续执行。否则,它们将在 main() 结束时自动被终止。 实例 这个简单的实例代码使用 pthread_create() 例程创建了 5 个线程。每个线程打印一个 “Hello World!” 消息,然后调用 pthread_exit() 终止线程。 #include <iostream> // 必须的头文件是 #include <pthread.h> using namespace std; #define NUM_THREADS 5 // 线程的运行函数 void* say_hello(void* args) { cout << "Hello w3cschool!" << endl; } int main() { // 定义线程的 id 变量,多个变量使用数组...
2024-04-04
程序的注释是解释性语句,您可以在 C++ 代码中包含注释,这将提高源代码的可读性。所有的编程语言都允许某种形式的注释。 C++ 支持单行注释和多行注释。注释中的所有字符会被 C++ 编译器忽略。 C++ 注释以 /* 开始,以 */ 终止。例如: /* 这是注释 */ /* C++ 注释也可以 * 跨行 */ 注释也能以 // 开始,直到行末为止。例如: #include <iostream> using namespace std; int main() { cout << "Hello World!"; // 输出 Hello World! return 0; } 尝试一下 当上面的代码被编译时,编译器会忽略 // prints Hello World,最后会产生以下结果: Hello World 在 /* 和 */ 注释内部,// 字符没有特殊的含义。在 // 注释内,/* 和 */ 字符也没有特殊的含义。因此,您可以在一种注释内嵌套另一种注释。例如: /* 用于输出 Hello World 的注释 cout << "Hello World"; // 输出 Hello World */
2024-04-04
C++ 接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现。 C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。 如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 “= 0” 来指定的,如下所示: class Box { public: // 纯虚函数 virtual double getVolume() = 0; private: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; 设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。 因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重载纯虚函数,就尝试实例化该类的对象,会导致编译错误。 可用于实例化对象的类被称为具体类。 抽象类的实例 请看下面的实例,基类 Shape 提供了一个接口 getArea(),在两个派生类 Rectangle 和 Triangle 中分别实现了 getArea(): #include <iostream> using namespace std; // 基类 class Shape { public: // 提供接口框架的纯虚函数 virtual int getArea() = 0; void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // 派生类 class Rectangle: public Shape { public: int getArea() { return (width * height); } }; class Triangle: public Shape { public: int getArea() {...
2024-04-04
本文将为大家带来的是几款简单实用的C++编译器(非IDE),希望大家喜欢。 GCC(GNU Compiler Collection) 官方网站: https://gcc.gnu.org/ GCC有Windows移植版本,比较出名的就是MinGW和TDM-GCC GNU编译器套件(GNU Compiler Collection)包括C、C++、Objective-C、Fortran、Java、Ada和Go语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。GCC的初衷是为GNU操作系统专门编写的一款编译器。GNU系统是彻底的自由软件。此处,“自由”的含义是它尊重用户的自由。 llvm+Clang LLVM官方网站:http://llvm.org/ Clang官方网站:http://clang.llvm.org/get_started.html LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。LLVM计划启动于2000年,最初由University of Illinois at Urbana-Champaign的Chris Lattner主持开展。2006年Chris Lattner加盟Apple Inc.并致力于LLVM在Apple开发体系中的应用。Apple也是LLVM计划的主要资助者. Low Level Virtual Machine (LLVM) 是一个开源的编译器架构,它已经被成功应用到多个应用领域。Clang ( 发音为 /kl??/) 是 LLVM 的一个编译器前端,它目前支持 C, C++, Objective-C 以及 Objective-C++ 等编程语言。Clang 对源程序进行词法分析和语义分析,并将分析结果转换为 Abstract Syntax Tree ( 抽象语法树 ) ,最后使用 LLVM 作为后端代码的生成器。 Clang 的开发目标是提供一个可以替代 GCC 的前端编译器。与 GCC 相比,Clang 是一个重新设计的编译器前端,具有一系列优点,例如模块化,代码简单易懂,占用内存小以及容易扩展和重用等。由于 Clang 在设计上的优异性,使得 Clang 非常适合用于设计源代码级别的分析和转化工具。Clang 也已经被应用到一些重要的开发领域,如 Static Analysis 是一个基于 Clang 的静态代码分析工具。 Watcom C/C++ 官方网站:http://www.openwatcom.org/index.php/Download 在DOS开发环境中,Watcom C/C++ 编译器 以编译后的exe运行高速而著称,且首个支持Intel 80386 “保护模式”的编译器。于90年代中期,大批的雄心技术游戏(例如 Doom、Descent、Duke Nukem 3D 都以 Watcom C 写成) Watcom C/C++ 编译器、Watch Fortran 编译器 经已在不其先前所属公司Sybase售卖, 而被 SciTech 软件公司 作为 Open Watcom 开源包 发行。类似于其他的 开源编译器(例如 [GCC])项目,Watcom C代码小而便携, 其编译器后端(代码生成器)的目标码可变。该编译器可在DOS、OS/2、Windows等操作系统上运行,并生成各种可运行的(不必是该操作系统的)代码。该编译器支持Novell NetWare的 NLM 目标码。目前正进行 为 Linux[1] 、modern BSD (例如FreeBSD) 操作系统 重定目标码, 以便在 x86、PowerPC 及 其它处理器上运行。Open Watcom C/C++ 的1.4版于2005年12月发行,采用 Linux x86 为实验目标, 支持NT、OS/2等host平台. 曾有某被弃置的QNX版本,但其编译所须的库并未开源发行。当前最近的稳定版是1.9版,在2010年6月发行。 Digital Mars 官方网站:http://www.digitalmars.com/ DigitalMars是一款高性能的编译器,功能包含,快速编译/链接时、强大的优化技术、Contract设计、完整的资源库、浏览HTML文档,反汇编、库、资源编译器等。命令行及GUI版本、教程、代码示例、在线更新、标准模板库等等。 MSVC系列 与Visual Studio集成发布,微软自己的编译器,VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。所写的目标代码适用于微软支持的所有平台,包括Microsoft Windows、Windows Mobile、Windows CE、.NET Framework、.NET Compact Framework和Microsoft Silverlight 及Windows Phone。 Borland系列(turbo c和Borland C++) Borland C++ Builder Compiler 是一个 BC编译器。它是用来优化 BC 开发系统的工具。它包括最后版本的 ANSI/ISO C++ 语言的支持,包括 RTL,C++ 的 STL框架结构支持。Turbo C(TC)是其早期的命令行编译器作品 Intel C++ Intel C++ Compiler (简称 icc 或 icl)是美国 Intel 公司开发的 C/C++编译器,适用于 Linux、Microsoft Windows 和 Mac OS X 操作系统。 Intel 编译支持 IA-32、Intel 64、Itanium 2、Intel Atom 处理器和某些非 Intel 的兼容处理器(例如某些 AMD 处理器)。开发人员应当检查系统需求。适用于 IA-32 和 Intel 64 的 Intel C++ 编译器的主要特点是自动向量化器,它能够生成 SSE、SSE2 和 SSE3 的 SIMD 指令及其适用于 Intel 无线 MMX 和 MMX 2 的嵌入式变种。 Intel C++ Compiler 进一步支持 OpenMP 3.0 和适用于对称多处理的自动并行化。借助于 Cluster OpenMP 的附加能力,编译器还可为分布存储多处理根据 OpenMP 指示自动生成消息传递接口调用。 Intel C++ Compiler 可通过四种方式获得,它分别是 Intel Parallel Studio、Intel C++ Compiler 专业版、Intel 编译器套装和 Intel Cluster Toolkit 编译器版的一部分。该编译器的最新发布是 Intel C++ Compiler 14.0 版本 TCC(Tiny C Compiler) 官方网站:http://bellard.org/tcc/ Tiny C Compiler(缩写为TCC, tCc或TinyCC)用于x86(16/32位)或是x86-64(64位)系统的C compiler,而开发者为Fabrice Bellard。软件是设计用于低级电脑环境,或是于磁盘容量有限的空间中(1.44磁片或是硬盘)。软件可以适用于Windows、Linux、Unix操作系统,而最新版本为0.9.26(Feb 15, 2013)。TCC是在GNU宽通用公共许可证(LGPL)协议规范下发布。作者是大神法布里斯·贝拉(FabriceBellard) TCC符合ANSI C(C89/C90)规范,Tiny C Compiler Reference Documentation accessed on 2008-08-07]亦符合新版的ISO C99标准规范,与GNU C扩展的内嵌汇编语言(即inline assembler,内联汇编大陆用语)功能汇编语言。 而Google Andriod系统内亦曾经内置于其中,于Andriod 2.0版本中
2024-04-04
C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。 对象 – 对象具有状态和行为。例如:一只狗的状态 – 颜色、名称、品种,行为 – 摇动、叫唤、吃。对象是类的实例。 类 – 类可以定义为描述对象行为/状态的模板/蓝图。 方法 – 从基本上说,一个方法表示一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据以及执行所有的动作。 即时变量 – 每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。 C++ 程序结构 让我们看一段简单的代码,可以输出单词 Hello World。 #include <iostream> using namespace std; // main() 是程序开始执行的地方 int main(){ cout << "Hello World"; // 输出 Hello World return 0; } 尝试一下 接下来我们讲解一下上面这段程序: C++ 定义了一些头文件,这些头文件包含了程序中必需的或有用的信息。上面这段程序中,包含了 <iostream>头文件。 行 using namespace std; 告诉编译器使用 std 命名空间。命名空间是 C++ 中一个相对新的概念。 下一行 // main() 是程序开始执行的地方 是一个单行注释。单行注释以 // 开头,在行末结束。 下一行 int main() 是主函数,程序从这里开始执行。 下一行 cout << “Hello World”; 会在屏幕上显示消息 “Hello World”。 下一行 return 0; 终止 main( )函数,并向调用进程返回值 0。 <iostream>是一个输入输出流相关的头文件。里面包含了一些对输入输出流操作的方法。 编译 & 执行 C++ 程序 接下来让我们看看如何把源代码保存在一个文件中,以及如何编译并运行它。下面是简单的步骤: 打开一个文本编辑器,添加上述代码。 保存文件为 hello.cpp。 打开命令提示符,进入到保存文件所在的目录。 键入 ‘g++ hello.cpp ‘,输入回车,编译代码。如果代码中没有错误,命令提示符会跳到下一行,并生成 a.out 可执行文件。 现在,键入 ‘ a.out’ 来运行程序。 您可以看到屏幕上显示 ‘ Hello World ‘。 $ g++ hello.cpp $ ./a.out Hello World 请确保您的路径中已包含 g++ 编译器,并确保在包含源文件 hello.cpp...
2024-04-04