让我们看一个简单的代码,它将打印Hello World一词。
#include
using namespace std;
int main() {
cout << "Hello World"; // prints Hello World
return 0;
}
C++语言定义了几个头文件,其中包含对你的程序必要或有用的信息。对于这个程序,需要头文件
using namespace std;这一行告诉编译器使用std命名空间。命名空间是C++中相对较新的一个添加内容
int main() 是程序执行开始的主函数
cout << "Hello World"; 导致屏幕上显示消息"Hello World"
return 0; 终止 main() 函数并使其返回值为 0 给调用进程
想象一下,你住在一座大城市,这个城市被划分成不同的区域:市中心、住宅区、商业区等等。每个区域都有独特的街道、建筑和规则。在这个场景中,每个区域就是一个命名空间,它们提供了独立的作用域,允许你在其中声明和使用标识符,而这些标识符的名字在不同的命名空间中可以重复使用,因为它们互相隔离。
在C++中,我们可以使用关键字namespace
来定义命名空间。比如:
// 定义名为math的命名空间
namespace math {
const double PI = 3.14159;
double areaOfCircle(double radius) {
return PI * radius * radius;
}
}
上面的代码定义了一个名为 math
的命名空间。它包含了一个常量 PI
和一个计算圆面积的函数 areaOfCircle
。
就像城市中的区域可以进一步划分为子区域一样,命名空间也可以嵌套定义。例如:
namespace university {
namespace department {
void displayInfo() {
std::cout << "Welcome to Computer Science Department!" << std::endl;
}
}
}
这里,我们有一个嵌套的命名空间结构。university
是外层命名空间,内部有 department
命名空间,其中包含了一个显示信息的函数。
使用命名空间可以通过两种主要的方式:
限定名:使用作用域解析运算符::
来访问命名空间中的成员,例如:
std::cout << "Hello, World!";
university::department::displayInfo();
这里的 std::
表示标准命名空间,cout
是其中的一个成员。
小知识:
C++标准库中的
std
命名空间是什么?为什么要使用它?
std
命名空间是 C++ 标准库的命名空间,包含了标准库中的大部分功能、类和对象。使用std
命名空间可以避免与用户定义的标识符产生冲突,并让代码更具可移植性。要使用标准库的标识符(如std::cout
、std::vector
),需要显式地指明其命名空间。
使用指令:通过 using
指令将整个命名空间的内容引入当前作用域,例如
using namespace math;
using namespace university::department;
这将使得 math
命名空间中的所有内容在当前作用域内可用,但要注意这种方法可能会引入命名冲突。
现在,让我们结合实际的例子来展示命名空间的使用:
#include
// 定义名为math的命名空间
namespace math {
const double PI = 3.14159;
double areaOfCircle(double radius) {
return PI * radius * radius;
}
}
int main() {
// 使用限定名调用命名空间中的函数
std::cout << "Area of circle with radius 2: " << math::areaOfCircle(2.0) << std::endl;
// 使用指令引入命名空间中的常量
using namespace math;
std::cout << "Value of PI: " << PI << std::endl;
return 0;
}
这个示例中,我们展示了如何使用限定名来调用命名空间中的函数,以及如何使用 using namespace
指令将命名空间中的常量引入当前作用域。
#include
namespace university {
namespace department {
void displayInfo() {
std::cout << "Welcome to Computer Science Department!" << std::endl;
}
}
}
int main() {
// 通过限定名调用嵌套命名空间中的函数
university::department::displayInfo();
// 使用指令引入嵌套命名空间
using namespace university::department;
displayInfo(); // 现在可以直接使用 displayInfo(),因为已经引入了 department 命名空间
return 0;
}
在这个示例中,我们展示了使用限定名和使用指令两种方式来使用嵌套命名空间。通过这些方法,我们可以方便地访问嵌套命名空间中的成员,使得代码更具有结构性和可读性。
总的来说,命名空间是C++中一种强大的工具,帮助我们组织和管理代码,避免命名冲突,提高代码的可读性和可维护性。
下面的列表显示了 C++ 中的保留字。这些保留字不得用作常量、变量或任何其他标识符名称,加粗的为C语言的关键字
asm | else | new | this |
auto | enum | operator | throw |
bool | explicit | private | true |
break | export | protected | try |
case | extern | public | typedef |
catch | false | register | typeid |
char | float | reinterpret_cast | typename |
class | for | return | union |
const | friend | short | unsigned |
const_cast | goto | signed | using |
continue | if | sizeof | virtual |
default | inline | static | void |
delete | int | static_cast | volatile |
do | long | struct | wchar_t |
double | mutable | switch | while |
dynamic_cast | namespace | template |
以下是 C++ 中关键字的解释:
- Asm:用于声明需要传递给汇编器的代码块。
- auto:用作存储类别说明符,在特定块中定义对象。
- break:终止任何 switch 语句或循环。
- case:在 switch 语句中使用,指定语句表达式的匹配项。
- catch:指定异常发生时应采取的操作。
- char:C++ 语言中的基本数据类型之一,定义字符对象。
- class:用于声明封装特定类的数据成员、操作或成员函数的用户定义数据类型。
- const:帮助定义在程序执行的整个生命周期中值不会改变的对象。
- continue:将控制转移到循环的起始点。
- default:处理 switch 语句中无法处理的表达式值。
- delete:内存释放运算符。
- do:指示 do-while 语句的起点,在其中子语句将重复执行,直到表达式的值为逻辑假。
- double:用于定义浮点数的基本数据类型。
- else:特定于 if-else 语句的使用。
- enum:声明用户定义的枚举数据类型。
- extern:指定为外部的标识符与块具有外部链接。
- float:用于定义浮点数的基本数据类型。
- for:指示开始一个语句以实现重复控制。
- friend:一个类或操作,其实现可以访问另一个类的私有数据成员。
- long:数据类型修饰符,定义 32 位整数或扩展双精度数。
- new:内存分配运算符。
- operator:使用新声明重载 C++ 运算符。
- private:声明在类外部不可见的类成员。
- protected:声明对派生类除外的私有类成员。
- public:声明在类外部可见的类成员。
- register:存储类别说明符,是 auto 说明符,但也指示编译器将频繁使用的对象保留在寄存器中。
- goto:帮助将控制权转移到指定的标签。
- if:指示开始 if 语句以实现选择性控制。
- inline:函数说明符,指示编译器优先选择内联替换函数体,而不是通常的函数调用实现。
- int:定义整数对象的基本数据类型。
- return:将对象返回给函数的调用者。
- short:定义 16 位整数的数据类型修饰符。
- signed:数据类型修饰符,指示对象的符号存储在高阶位。
- sizeof:以字节为单位返回对象的大小。
- static:静态定义的对象生存期存在于程序执行的整个生命周期。
- struct:声明封装数据和成员函数的新类型。
- switch:用于 switch 语句。
- template:参数化或通用类型。
- this:指向类的对象或实例的类指针。
- throw:生成异常。
- try:指示异常处理程序块的开始。
- typedef:另一个整数或用户定义类型的同义词。
- union:类似于结构体 struct,可以容纳不同类型的数据,但联合体只能同时容纳一个成员。
- unsigned:数据类型修饰符,指示高阶位将用于一个对象。
- virtual:函数说明符,声明一个类的成员函数将由派生类重新定义。
- void:标识缺乏类型或函数参数列表的关键字。
- volatile:这个特定关键字定义了一个对象,其值可能以编译器无法检测到的方式变化。
- while:帮助启动 while 语句并结束 do...while 循环。
在编译器优化中,inline
关键字用于向编译器建议将函数内容直接插入函数调用的地方,而不是进行常规的函数调用。这样的建议通常用于短小的函数,以提高程序的执行效率。
1、inline
关键字1.1 inline
关键字的作用:减少函数调用开销: 普通函数的调用涉及堆栈操作、参数传递、指令跳转等开销,而使用 inline
关键字可以避免这些开销,直接将函数体内容嵌入到调用点处。
减少函数开销: 函数调用会产生一定的开销,如保存寄存器状态等。将函数内联可以减少这些开销,尤其在多次调用的场景中。
优化循环和小函数: inline
更适合用于简单的、执行频率高的函数或者循环体,因为在这些情况下,函数调用的开销相对更大。
代码膨胀: inline
函数的函数体直接嵌入调用点,可能导致代码的膨胀,增加可执行代码的大小,对缓存和内存占用可能产生影响。
适用范围有限: 编译器可能会忽略 inline
关键字的建议,特别是对于复杂的函数、递归函数或函数体过大的情况。因此,即使使用了 inline
,也不一定会被编译器完全内联。
编译器依赖: 编译器对 inline
关键字的处理方式可能因编译器而异,不同编译器可能会有不同的优化方式,对程序性能的影响也会有所不同。
适用于简短函数: 对于函数体较大、复杂的情况,inline
的效果可能不如预期,甚至可能因代码膨胀而降低性能。
#include
// 定义一个简单的加法函数
inline int add(int a, int b) {
return a + b;
}
int main() {
int x = 5, y = 10;
int result = add(x, y); // 调用 add() 函数
std::cout << "Result: " << result << std::endl;
return 0;
}
总的来说,inline
关键字能够在一定程度上提高程序性能,但使用时需慎重考虑函数的大小、调用频率以及编译器的优化能力,避免不必要的代码膨胀,从而达到更好的性能优化效果。
C++ 标识符是用于标识变量、函数、类、模块或任何其他用户定义项的名称。标识符以字母 A 到 Z 或 a 到 z 或下划线 (_) 开头,后跟零个或多个字母、下划线和数字(0 到 9)。
C++ 不允许在标识符中使用标点符号,C++ 是一种区分大小写的编程语言。
三字符序列是一种用于代表单个字符的替代表示方法,通常由三个字符组成,并且序列始终以两个问号开始。
三字符序列可以在出现的任何地方进行扩展,包括字符串字面值和字符字面值、注释以及预处理指令。
以下是最常用的三字符序列及其替换方式:
三字符序列 | 替换 |
---|---|
??= | # |
??/ | \ |
??' | ^ |
??( | [ |
??) | ] |
??! | | |
??< | { |
??> | } |
??- | ~ |
并非所有编译器都支持三字符序列,而且由于它们容易造成混淆,不建议使用。
const
关键字:用于定义常量,标识变量的数值不可修改。在嵌入式系统中,const
关键字常用于声明设备寄存器地址、常量表和程序代码的位置等。
volatile
关键字:用于声明易变的变量,告诉编译器该变量的值可能在程序控制之外发生改变,不应该被优化掉。在嵌入式系统中,volatile
常用于多线程编程、并行处理、硬件寄存器和中断服务程序中,确保编译器不会对这些值进行优化或缓存。
auto
关键字:在 C++11 中,auto
关键字用于自动推断变量的类型。它允许编译器根据变量的初始化表达式来推断变量的数据类型。
register
关键字:register
告诉编译器将变量存储在寄存器中以便快速访问。然而,现代编译器已经足够智能,在大多数情况下能够自行决定将变量存储在寄存器还是内存中。因此,register
关键字在现代编译器中往往不再被频繁使用。
typedef
关键字:用于为现有的类型创建别名。它可以帮助简化复杂的类型名称,提高代码可读性,并减少代码中的重复。// 实际例子:
typedef int IntArray[5]; // 创建一个名为 IntArray 的数组类型别名
int main() {
IntArray arr = {1, 2, 3, 4, 5}; // 使用 IntArray 类型别名创建数组
// ...
return 0;
}
在上面的例子中,IntArray
被定义为一个具有5个整数元素的数组类型别名,使得声明数组变得更简洁。
static
关键字在不同的上下文中有不同的作用。在类内部,它用于声明静态成员变量和静态成员函数。在函数内部,它表示局部变量的生命周期在程序的整个执行过程中都存在。