CPP初识
C++ 入门
一、C++ 语言介绍
1. C++ 语言发展历史
C++ 语言是一种面向对象的、编译型语言,在 C 语言的基础上发展而来。它由 Bjarne Stroustrup 于 20 世纪 70 年代末开始开发,最初被称为 “C with classes”,1983 年正式命名为 C++。1998 年发布了第一个国际标准 ISO/IEC 14882:1998(C++98),之后又经历了多次修订和改进,如 C++11、C++14、C++17、C++20 等标准分别在 2011 年、2014 年、2017 年和 2020 年发布。
2. C++ 语言的优点
- 完全兼容 C:保留了 C 语言的大部分语法和语义,同时增加了面向对象、面向泛型、容器等特性。
- 高性能:编译型语言,直接编译成机器码运行,执行速度快,允许直接访问硬件。
- 面向对象编程:支持封装、继承、多态等特性,有助于模块化编程、代码重用和维护。
- 可移植性:代码具有良好的跨平台能力,能在多种操作系统和硬件平台上编译运行。
- 标准库丰富:提供大量实用的模板和算法,如 STL,加速开发过程。
3. 应用领域
C++ 应用广泛,涵盖系统级底层架构、游戏开发、嵌入式开发、桌面应用、工业控制、数据库、AI 核心库、航空航天、网络协议、电子通讯等领域。
二、快速上手
1. main 函数
每个 C++ 程序中有且只有一个名为 main () 的主函数,是程序执行的入口。
#include <iostream> //引入标准库头文件
int main(){int num = 10;std::cout << num;std::cout << "hello world" << std::endl;//endline换行//std 命名空间,区分不同文件可能出现相同对象名//:: 作用域限定符//cout 标准输出流对象(把代码输出在屏幕上)// << c++可以给运算符赋予新的功能,把变量/常量提取给cout对象return 0;
}
关键词 | 解释 |
---|---|
#include <iostream> | 引入输入输出相关的函数,如 std::cout , std::cin |
std | 标准命名空间,C++ 所有标准库内容都定义在这里 |
:: | 作用域限定符,访问命名空间或类中的成员,比如 std::cout 表示命名空间 std 中的 cout |
cout | console output,控制台输出对象,用来把数据输出到终端 |
<< | 输出运算符,把右边的数据“送进”左边的输出流(cout) |
endl | 换行符,相当于 "\n" ,但还会刷新缓冲区 |
int main() | 程序主入口,返回值 int 是返回给操作系统的状态码 |
return 0; | 返回 0 表示程序正常退出 |
2. C++ 程序的编译和链接
- 编译器选择:常见的 C++ 编译器有 GCC(在 Linux 系统上广泛使用,也可用于 Windows 和 Mac OS X)、MSVC(微软开发,用于 Windows 平台,有丰富调试和性能分析工具)、MinGW(Windows 上的 GCC 版本)。
- 安装配置 MinGW 编译器:在 Windows 下下载 MinGW 命令行编译工具,配置环境变量(将 MinGW-w64 的 bin 目录地址添加到 Path 环境变量),在命令行输入 gcc -v 测试是否配置成功。
- 编译命令:在命令行进入源文件所在目录,使用 g++ 命令编译,如
g++ -o output main.cpp
,-o output 表示输出的可执行文件名为 output,main.cpp 是源文件名。
3. 编译过程解析
- 预处理:处理源代码中的预处理指令,如 #include、#define 等,但不进行编译。
- 编译:将预处理后的代码转换为目标文件(机器代码),生成.obj 或.o 文件。
- 链接:进行符号解析、重定位、库解析等,将多个编译单元组合成可执行程序或库。
4. 运行程序
编译完成后,在命令行中运行生成的可执行文件。在 Windows 上,若在当前目录,直接输入文件名(如 output.exe);若不在当前目录,需加上路径。
三、集成开发环境 IDE
使用 Visual Studio 开发工具,它自带 Microsoft Visual C++ 编译器。
- 下载地址:https://visualstudio.microsoft.com/zh-hans/free-developer-offers/
- 安装步骤:双击安装程序,选择使用 C++ 的桌面开发并指定安装目录;安装完成后跳过登录步骤;个性化 Visual Studio 体验(选择颜色主题等);启动 Visual Studio,创建项目(选择控制台应用),配置项目(设置项目名称、位置等),运行示例程序。
四、常用的语法与 C 语言区别
1、输入和输出
在 C 语言中,我们通常会使用 scanf、printf 函数进行输入输出操作。在 C++ 语言中,C 语言的这一套输入输出库我们仍然能使用,但是在 C++ 标准库中又提供了更易于使用的标准输入输出流。
(1)标准输出流对象
cout 是 ostream 类实例化的标准输出流对象,用于向标准输出设备 (显示器) 输出数据。可以通过重载运算符 << 进行输出操作。
基本用法:
cout << "hello";
<<符号表示该语句把这个字符串发送给 cout (只是发送该字符串的地址)。该符号指出了信息流动的路径。向左流动的信息流,它可以将其右侧的数据插入到流中。
可以用 << 符号拼接输出:
cout << "hello" << "world";
在 C++ 中,与 C 一样,<< 运算符的默认含义是左移运算符。ostream 类重新定义了 << 运算符,将其重载为输出。这种情况下,<< 叫做插入运算符。
另外,控制符 endl 表示换行,和 cout 一样也是在头文件 iostream 中定义的,且位于名称空间 std 中。
cout << "hello" << "world" << endl;
(2)标准输入流对象
cin 是 istream 类实例化的标准输入流对象,用于从标准输入设备 (键盘) 读取数据。可以通过重载运算符 >> 进行输入操作。
int a;
cin >> a;
数据从 cin 流向 a,C++ 将输出看作是流出程序的字符流,将输入看作是流入程序的字符流。与 cout 一样,cin 也是一个智能对象。它可以将通过键盘输入的一系列字符 (即输入) 转换为接收信息的变量能够接受的类型。
int main(void)
{int a;cout << "请输入一个数字" << endl;cin >> a;cout << "你输入的数字是:" << a << endl;cout << "请输入一个字符" << endl;char c;cin >> c;cout << "你输入的字符是:" << c << endl;cout << "请输入一个字符串" << endl;string s;cin >> s;
}
2、bool 类型
在 C++ 中提供了 bool 数据类型,只有两种取值 true 或 false,在内存中只需要 1 位就可以存储。但是因为内存是以字节为最小单位进行地址编码的,所以对该类型的变量仍然会分配 1 字节 (8 位) 的存储空间。
对于 false 内存中实际存储的值是 0,true 在内存中实际存储的值是 1。
布尔类型变量的定义:
bool b = false;
C++ 中将非零值解释为 true,将零解释为 false。
bool b1 = -100; // true
bool b2 = 0 ; // false
在算术逻辑表达式和位逻辑表达式中,bool 被自动转换成 int,编译器在转换后的值上执行整数算术运算以及逻辑运算。如果最终的计算结果需要转换回 bool,则 0 转换成 false,而非 0 值转换成 true。
bool a = true;
bool b = true;
bool x = a + b; // a+b的结果是2,因此x的最终取值是true
bool y = a || b; // a || b 的结果是1,因此y的值是true(||"的含义是"或")
bool z = a - b; // a-b的结果是0,因此z的最终取值是false
cout << x << endl;
cout << y << endl;
cout << std::boolalpha << z << endl; //输出falsestd::boolalpha 一个格式控制符,让布尔值输出为 true / false(文字形式),而不是数字 1 / 0
使用 cout 输出 bool 类型变量或常量的值时,默认输出的是数值 0 或 1,如果希望输出 false 或 true,可以在前面加上格式控制符 boolalpha。
3、变量初始化
在定义变量的同时可对其进行初始化。
数据类型 变量名 = 初始值;
(1)直接初始化
C++ 中对变量初始化的另一种形式,称为直接初始化。其语法如下:
数据类型 变量名(初始值);
示例:
int a(10);
(2)列表初始化
从 C++11 语言规范开始,引入了新的初始化方式列表初始化。采用一对花括号,语法如下:
数据类型 变量名 {初始值或空}; //列表初始化
或
数据类型 变量名 = {初始值或空};
int arr[5]{};
int a{2}, b={4};
4、基于范围的 for 循环
在 C++11 中引入了新的 for 语句形式,语法如下:
for (数据类型 迭代变量 : 范围)
{//循环体
}
//迭代变量:每次迭代时从数组 arr 中取出的元素的副本。因此在循环体对其进行的任何修改都不会影响原数组中的值
语法中的数据类型也可以使用关键字 auto,作用是让编译器自动推导出迭代变量的类型。和传统的 for 语句相比,基于范围的 for 循环不会出现数组下标越界的问题。
示例:
int arr[5] = {10, 20, 30, 40, 50};
for(auto i : arr){ //int 可以用autocout << "i=" << i << endl;
}
arr
是一个长度为 5 的数组。- 编译器会把它理解为从
arr[0]
到arr[4]
的所有元素。 i
是arr
中每一个元素的副本(不是引用!)。- 所以在循环体里修改
i
,并不会改变arr
的值。
for (auto i : arr) {i += 100; // 改的是副本,不会影响 arrstd::cout << "i = " << i << std::endl;
}for (int i = 0; i < 5; ++i) {std::cout << "arr[" << i << "] = " << arr[i] << std::endl; // 原数组没变
}
如果想修改数组内容,需要这样写:
cpp复制编辑for (auto& i : arr) { // 使用引用i += 100;
}
这时候 i
就是 arr
中每个元素的引用,可以真正修改原数组。
五、常量
常量是程序在运行的过程中,其值不能改变的量,称之为常量。
1、字面值常量
常量分为整型常量、实型常量、字符常量、字符串常量和其他常量。
字符串字面量 (如 “Hello”) 存储在只读的文字常量区 (或称为常量池),存储在这个区域中的数据不能被程序修改。
整型、浮点型和其他基本类型的字面量常量通常在编译时就被嵌入到代码段中,作为指令的一部分,而不是单独分配内存。
int main()
{cout << 100 << endl;cout << 3.14 << endl;cout << 'a' << endl;cout << "hello world" << endl;
}
2、#define 宏常量
宏定义常量,通过 #define 宏定义。#define 宏定义是 C++ 继承自 C 语言的预处理器特性。
#define 宏定义实际上并不分配内存,宏定义是在编译预处理阶段由预处理器执行的文本替换操作。也就是说,宏定义在编译过程开始之前就已经完成了文本替换,因此宏定义本身并不在程序的运行时内存中占据任何空间。
使用宏定义的这种方式可能导致一些潜在的问题,比如缺乏类型安全检查。
#include <iostream>
using namespace std;
// #define 常量名 常量值
#define LENGTH 10
#define WIDTH 5
int main()
{int area;area = LENGTH * WIDTH;cout << area << endl;return 0;
}
反例:
#include <iostream>
#define MAX_SIZE 100 //如果其他文件重新定义了该宏,那么就可能引起程序出错
void processArray(int arr[MAX_SIZE]) {// 处理数组...
}
int main() {int myArr[MAX_SIZE] = {0}; // 使用MAX_SIZE定义数组大小processArray(myArr);return 0;
}
3、const 常量
在 C++ 中,使用 const 修饰的变量称之为常量。常量的值一旦初始化后就不能被修改。使用常量有助于保护数据不被意外更改,提高程序的可维护性。
const 数据类型 常量名 = 常量值;
#include <iostream>
using namespace std;
int main()
{const int length = 10;//length = 20 报错,length是常量不能修改const int width = 5;int area;area = length * width;cout << area << endl;return 0;
}
const 常量的生命周期和作用域遵循变量的作用域规则,而 #define 宏在整个文件中有效。推荐使用 const 来定义常量,提供了更好的类型安全性和更清晰的语义。