C++是一种功能强大的高级编程语言,它融合了面向过程编程和面向对象编程的特性。由于其效率高、可移植性强等优点,广泛应用于系统开发、游戏编程、嵌入式系统等诸多领域。对于想要深入学习C++的人来说,需要全面掌握其语法、编程范式、数据结构、算法以及相关的开发工具等多方面的知识。
int
(通常为32位有符号整数)、short int
(短整型,通常16位)、long int
(长整型,至少32位)。例如: int num = 10;
short int small_num = 5;
long int large_num = 100000L; // 注意长整型常量后面加L或l
float
(单精度浮点数)、double
(双精度浮点数)。float pi = 3.14f; // 单精度常量后面加f或F
double euler = 2.71828;
char
类型用于存储单个字符。字符在内存中以ASCII码值存储。例如: char ch = 'A';
int a; // 声明一个整型变量a
a = 10; // 给a赋值,这是定义的一部分动作
int b = 20;
const
关键字定义常量。例如: const int max_count = 100;
constexpr
关键字定义编译期常量,这些常量的值可用于常量表达式求值。例如: constexpr int square(int x) {
return x * x;
}
constexpr int num_squared = square(5);
+
、减法 -
、乘法*
、除法/
、取余%
。例如: int result1 = 10 + 5;
int result2 = 10 / 3; // 结果为3(整数除法截断)
int remainder = 10 % 3; // 结果为1
==
、不等于!=
、大于>
、小于<
、大于等于>=
、小于等于<=
,返回布尔值。例如: bool is_equal = (5 == 5); // true
bool is_greater = (10 > 5); // true
&&
、逻辑或||
、逻辑非!
。例如: bool condition1 = true;
bool condition2 = false;
bool combined = condition1 && condition2; // false
C++程序默认按照顺序执行语句,自上而下依次进行操作。例如:
#include
int main() {
int num = 10;
std::cout << "The number is: " << num << std::endl;
num++;
std::cout << "After increment, the number is: " << num << std::endl;
return 0;
}
int age = 20;
if (age >= 18) {
std::cout << "You are an adult." << std::endl;
} else {
std::cout << "You are a minor." << std::endl;
}
int day = 3;
switch (day) {
case 1:
std::cout << "Monday" << std::endl;
break;
case 2:
std::cout << "Tuesday" << std::endl;
break;
case 3:
std::cout << "Wednesday" << std::endl;
break;
default:
std::cout << "Other day" << std::endl;
break;
}
int i = 1;
while (i <= 10) {
std::cout << i << " ";
i++;
}
std::cout << std::endl;
int j = 1;
do {
std::cout << j << " ";
j++;
} while (j <= 10);
std::cout << std::endl;
for (int k = 1; k <= 10; k++) {
std::cout << k << " ";
}
std::cout << std::endl;
int arr[5];// 初始化
arr[0]=1;arr[1]=2;arr[2]=3;arr[3]=4;arr[4]=5;
// 或者在声明时初始化
int arr2[5]={1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
std::cout << arr2[i] << " ";
}
std::cout << std::endl;
int matrix[3][3];
matrix[0][0]=1;matrix[0][1]=2;matrix[0][2]=3;
matrix[1][0]=4;matrix[1][1]=5;matrix[1][2]=6;
matrix[2][0]=7;matrix[2][1]=8;matrix[2][2]=9;
// 另一种初始化方式
int matrix2[3][3]={{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int num = 10;
int *p = #
p
是一个指向int
类型的指针,&num
表示取num
的地址。int arr3[5] = {1, 2, 3, 4, 5};
int *q = arr3;
q++; // 此时q指向arr3[1]
std::cout << *q << std::endl; // 输出2
int arr4[5] = {1, 2, 3, 4, 5};
int *r = arr4;
for
int add(int a, int b) {
return a + b;
}
int result = add(3, 5);
std::cout << "The result is: " << result << std::endl;
void increment(int num) {
num++;
std::cout << "Inside function: " << num << std::endl;
}
int main() {
int number = 10;
increment(number);
std::cout << "Outside function: " << number << std::endl;
return 0;
}
Inside function: 11
Outside function: 10
void increment(int &num) {
num++;
std::cout << "Inside function: " << num << std::endl;
}
int main() {
int number = 10;
increment(number);
std::cout << "Outside function: " << number << std::endl;
return 0;
}
Inside function: 11
Outside function: 11
int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
class Rectangle {
public:
int length;
int width;
int area() {
return length * width;
}
};
Rectangle rect;
rect.length = 5;
rect.width = 3;
int area = rect.area();
std::cout << "The area of the rectangle is: " << area << std::endl;
public
、private
和protected
来控制类成员的访问权限。class Circle {
private:
double radius;
public:
void setRadius(double r) {
radius = r;
}
double getRadius() {
return radius;
}
double area() {
return 3.14159 * radius * radius;
}
};
class Shape {
public:
virtual void draw() = 0;
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a circle" << std::endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a rectangle" << std::endl;
}
};
Shape *shape1 = new Circle();
Shape *shape2 = new Rectangle();
shape1->draw();
shape2->draw();
template
T add(T a, T b) {
return a + b;
}
int int_result = add(3, 5);
double double_result = add(3.14, 2.71);
template
class Stack {
private:
T data;
int top;
public:
Stack() {
top = -1;
}
void push(T value) {
data[++top] = value;
}
T pop() {
return data[top--];
}
};
Stack int_stack;
int_stack.push(10);
int_stack.push(20);
int popped_value = int_stack.pop();
vector
、list
、map
、set
等,用于存储和管理数据。例如: #include
int main() {
std::vector numbers;
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
std::vector::iterator it;
for (it = numbers.begin(); it!= numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
#include
int main() {
std::vector numbers = {30, 10, 20};
std::sort(numbers.begin(), numbers.end());
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
std::shared_ptr
、std::unique_ptr
和std::weak_ptr
,用于自动管理内存。例如: #include
int main() {
std::shared_ptr ptr = std::make_shared(10);
std::cout << *ptr << std::endl;
return 0;
}
int main() {
auto add = [](int a, int b) {
return a + b;
};
int result = add(3, 5);
std::cout << "The result is: " << result << std::endl;
return 0;
}
std::thread
、std::mutex
和std::condition_variable
,用于支持多线程编程。例如: #include
#include
std::mutex mutex_f;
void print_message(const char *message) {
std::lock_guard guard(mutex_f);
std::cout << message << std::endl;
}
int main() {
std::thread t1(print_message, "Hello from thread 1");
std::thread t2(print_message, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
auto
关键字进行类型推导。if
和switch
的初始化语句、内联变量等新特性。try
、catch
和throw
关键字来处理异常。例如: try {
int num1 = 10;
int num2 = 0;
if (num2 == 0) {
throw "Division by zero";
}
int result = num1 / num2;
std::cout << "Result: " << result << std::endl;
} catch (const char* error) {
std::cerr << "Error: " << error << std::endl;
}
class FileHandler {
public:
FileHandler(const char* filename) {
file = fopen(filename, "r");
if (file == NULL) {
throw "Could not open file";
}
}
~FileHandler() {
fclose(file);
}
private:
FILE* file;
};
int main() {
try {
FileHandler file("test.txt");
// 执行文件读取操作
} catch (const char* error) {
std::cerr << "Error: " << error << std::endl;
}
return 0;
}
int num = 10; // 栈上分配内存
int* ptr = new int; // 堆上分配内存
*ptr = 20;
delete ptr; // 释放堆内存
new
关键字用于在堆上分配内存,delete
关键字用于释放通过new
分配的内存。例如: int* arr = new int; // 分配一个包含5个整数的数组
for (int i = 0; i < 5; i++) {
arr[i] = i;
}
delete[] arr; // 释放数组内存
std::shared_ptr
、std::unique_ptr
和std::weak_ptr
,用于自动管理内存。例如: #include
int main() {
std::shared_ptr ptr = std::make_shared(10);
std::cout << *ptr << std::endl;
return 0;
}
std::thread
、std::mutex
和std::condition_variable
来支持多线程编程。例如: #include
#include
std::mutex mutex_f;
void print_message(const char *message) {
std::lock_guard guard(mutex_f);
std::cout << message << std::endl;
}
int main() {
std::thread t1(print_message, "Hello from thread 1");
std::thread t2(print_message, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::vector
在多线程环境下的使用,以及如何通过互斥锁来保护共享数据。fstream
、ifstream
和ofstream
类来进行文件的读写操作。例如: #include
int main() {
std::ofstream outfile("test.txt");
outfile << "This is a test file." << std::endl;
outfile.close();
std::ifstream infile("test.txt");
std::string line;
while (std::getline(infile, line)) {
std::cout << line << std::endl;
}
infile.close();
return 0;
}
stringstream
类允许将字符串作为流进行操作,常用于数据的格式化和解析。例如: #include
int main() {
std::stringstream ss;
ss << "10 20 30";
int num1, num2, num3;
ss >> num1 >> num2 >> num3;
std::cout << "Numbers: " << num1 << " " << num2 << " " << num3 << std::endl;
return 0;
}
-O2
或-O3
选项可以启用编译器的优化功能。g++ -O2 -o my_program my_program.cpp
g++ -pg -o my_program my_program.cpp
valgrind --tool=callgrind./my_program
callgrind_annotate callgrind.out.12345
constexpr
可以提高代码的执行效率。例如: inline int add(int a, int b) {
return a + b;
}
constexpr int square(int x) {
return x * x;
}
vcpkg install boost
find_package
命令来查找和使用Boost库。export module my_module;
import ;
export void hello() {
std::cout << "Hello, world!" << std::endl;
}
import my_module;
int main() {
hello();
return 0;
}
#include
#include
struct Generator {
struct promise_type {
int current_value;
std::experimental::suspend_always yield_value(int value) {
current_value = value;
return {};
}
std::experimental::suspend_always initial_suspend() { return {}; }
std::experimental::suspend_always final_suspend() { return {}; }
Generator get_return_object() { return Generator{this}; }
};
Generator(promise_type* p) : promise(p) {}
bool next() {
return coroutine_handle::from_promise(*promise).resume();
}
int value() { return promise->current_value; }
private:
promise_type* promise;
};
Generator generate_numbers() {
for (int i = 0; i < 5; ++i) {
co_yield i;
}
}
int main() {
Generator gen = generate_numbers();
while (gen.next()) {
std::cout << gen.value() << " ";
}
std::cout << std::endl;
return 0;
}
template
concept Integral = std::is_integral::value;
template
T add(T a, T b) {
return a + b;
}
// mylib.cpp
extern "C" {
int add(int a, int b) {
return a + b;
}
}
import ctypes
mylib = ctypes.CDLL('./mylib.so')
result = mylib.add(3, 5)
print(result)
#include
int main() {
Py_Initialize();
PyRun_SimpleString("print('Hello from Python!')");
Py_Finalize();
return 0;
}
// MyNativeLib.cpp
#include
#include
extern "C" JNIEXPORT jint JNICALL Java_MyClass_myNativeMethod(JNIEnv *env, jobject obj) {
return 42;
}
public class MyClass {
public native int myNativeMethod();
static {
System.loadLibrary("MyNativeLib");
}
public static void main(String[] args) {
MyClass myClass = new MyClass();
int result = myClass.myNativeMethod();
System.out.println(result);
}
}
网络编程
在网络编程中,协程可以显著简化异步操作的处理。例如,使用协程来处理网络请求,可以使代码逻辑更加清晰,避免了传统异步编程中回调函数嵌套的问题。以下是一个简单的示例,展示了如何使用 C++ 20 的协程来处理 HTTP 请求:
#include
#include
#include
boost::asio::io_context io_context;
// 定义一个简单的 HTTP 客户端协程
struct HttpClient {
struct promise_type {
HttpClient get_return_object() { return HttpClient{this}; }
std::experimental::suspend_never initial_suspend() { return {}; }
std::experimental::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
HttpClient(promise_type* p) {}
// 协程函数体,发送 HTTP 请求并等待响应
void operator()(const std::string& url) {
boost::asio::ip::tcp::resolver resolver(io_context);
boost::asio::ip::tcp::socket socket(io_context);
boost::asio::connect(socket, resolver.resolve("www.example.com", "80"));
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << url << " HTTP/1.1\r\n";
request_stream << "Host: www.example.com\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
boost::asio::write(socket, request);
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// 处理响应数据
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5)!= "HTTP/") {
std::cout << "Invalid response\n";
return;
}
if (status_code!= 200) {
std::cout << "Response returned with status code " << status_code << "\n";
return;
}
// 输出响应内容
std::stringstream content_stream;
content_stream << &response;
std::string content = content_stream.str();
std::cout << content << "\n";
}
};
int main() {
HttpClient client;
client("/");
io_context.run();
return 0;
}
文件读取与处理
协程也可以用于文件读取和处理,特别是在处理大型文件时,可以提高程序的性能和响应速度。例如,以下代码展示了如何使用协程来异步读取文件内容:
#include
#include
#include
#include
// 定义一个文件读取协程
struct FileReader {
struct promise_type {
FileReader get_return_object() { return FileReader{this}; }
std::experimental::suspend_never initial_suspend() { return {}; }
std::experimental::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
FileReader(promise_type* p) {}
// 协程函数体,异步读取文件内容
void operator()(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) {
std::cout << "Failed to open file: " << filename << "\n";
return;
}
std::stringstream buffer;
buffer << file.rdbuf();
std::string content = buffer.str();
// 处理文件内容
std::cout << "File content:\n" << content << "\n";
file.close();
}
};
int main() {
FileReader reader;
reader("test.txt");
return 0;
}
代码组织与编译优化
在大型项目中,模块可以显著提高代码的组织性和编译速度。例如,将一个大型项目划分为多个模块,可以减少编译时间,提高代码的可维护性。以下是一个简单的示例,展示了如何在 C++ 20 中使用模块来组织代码:
// math.ixx 模块声明
export module math;
export int add(int a, int b) {
return a + b;
}
// main.cpp 主程序
import math;
int main() {
int result = add(3, 4);
std::cout << "Result: " << result << "\n";
return 0;
}
依赖管理与命名空间隔离
模块还可以帮助管理依赖关系,避免命名空间污染。例如,在一个大型项目中,不同的模块可以有自己的命名空间,从而避免了全局命名空间的污染。以下是一个示例,展示了如何在 C++ 20 中使用模块来隔离命名空间:
// geometry.ixx 几何模块声明
export module geometry;
export class Point {
public:
int x;
int y;
Point(int x, int y) : x(x), y(y) {}
};
// main.cpp 主程序
import geometry;
int main() {
geometry::Point p(3, 4);
std::cout << "Point: (" << p.x << ", " << p.y << ")\n";
return 0;
}
数据过滤与转换
范围库可以简化数据处理流程,特别是在处理容器中的数据时。例如,以下代码展示了如何使用范围库来过滤和转换一个向量中的数据:
#include
#include
#include
int main() {
std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用范围库过滤偶数并进行平方转换
auto even_squares = numbers | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * n; });
// 输出结果
for (int n : even_squares) {
std::cout << n << " ";
}
std::cout << "\n";
return 0;
}
惰性求值与性能优化
范围库的惰性求值特性可以显著提高性能,特别是在处理大型数据集时。例如,以下代码展示了如何使用范围库的惰性求值特性来处理一个大型数据集:
#include
#include
#include
int main() {
std::vector large_dataset(1000000, 1); // 假设这是一个大型数据集
// 使用范围库进行数据处理
auto processed_data = large_dataset | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * n; });
// 由于惰性求值,数据处理不会立即执行
// 只有在需要结果时才会计算
// 假设我们只需要前10个结果
int count = 0;
for (int n : processed_data) {
std::cout << n << " ";
count++;
if (count >= 10) {
break;
}
}
std::cout << "\n";
return 0;
}
反射的概念与应用场景
预期的反射特性在 C++ 中的实现方式
模式匹配的概念与优势
模式匹配在 C++ 中的潜在应用场景
线性代数库的重要性与应用领域
预期的线性代数库特性
网络库的功能与必要性
预期的网络库特性
事务内存的概念与优势
事务内存可能在 C++ 中的实现方式
C++ 在深度学习框架中的应用
高性能计算需求
大型项目中的模块划分与依赖管理
模块系统对编译速度的影响
编写更通用和约束性更强的模板函数
概念在编译时错误检查的优势
结合异常和错误码优点的错误处理方式
链式调用在错误处理流程中的应用
多维下标运算符在科学计算中的应用
constexpr增强在编译时计算的应用
反射的概念与应用场景
预期的反射特性在C++中的实现方式
模式匹配的概念与优势
模式匹配在C++中的潜在应用场景
线性代数库的重要性与应用领域
预期的线性代数库特性
网络库的功能与必要性
预期的网络库特性
事务内存的概念与优势
事务内存可能在C++中的实现方式
C++ 在深度学习框架中的应用
高性能计算需求
嵌入式系统开发
资源受限环境下的编程
量子算法实现
与量子计算硬件的交互
常用编译器(如 GCC、Clang、Visual C++)
IDE 推荐(如 Visual Studio、CLion、Eclipse CDT)
GDB 与 LLDB
性能分析工具(如 Valgrind、Perf)
vcpkg 与 Conan
CMake 与 Make
大型项目中的模块划分与依赖管理
模块系统对编译速度的影响
编写更通用和约束性更强的模板函数
概念在编译时错误检查的优势
结合异常和错误码优点的错误处理方式
链式调用在错误处理流程中的应用
多维下标运算符在科学计算中的应用
constexpr增强在编译时计算的应用
反射的概念与应用场景
预期的反射特性在C++中的实现方式
模式匹配的概念与优势
模式匹配在C++中的潜在应用场景
线性代数库的重要性与应用领域
预期的线性代数库特性
网络库的功能与必要性
预期的网络库特性
事务内存的概念与优势
事务内存可能在C++中的实现方式
C++ 在深度学习框架中的应用
高性能计算需求
嵌入式系统开发
资源受限环境下的编程
量子算法实现
与量子计算硬件的交互
常用编译器(如 GCC、Clang、Visual C++)
IDE 推荐(如 Visual Studio、CLion、Eclipse CDT)
GDB 与 LLDB
性能分析工具(如 Valgrind、Perf)
vcpkg 与 Conan
CMake 与 Make