1. 字符串流与格式化输出
C++ 中的std::stringstream提供了一种灵活的方式来格式化字符串,类似于 C 语言的sprintf。
#include <iostream> #include <sstream> #include <cstdio> int main() { std::stringstream ss; ss << 12 << ":"; ss << 12.23 << ":"; ss << "yhping"; std::string str = ss.str(); std::cout << str << std::endl; char stra[128]; sprintf(stra, "%d : %lf : %s", 12, 12.23, "yhping"); std::cout << stra << std::endl; }2. 基于范围的 for 循环
C++11 引入了基于范围的 for 循环,可以简化数组和容器的遍历。
#include <iostream> #define ArSize(x) (sizeof(x)/sizeof(x[0])) int main() { int ar[] = { 12, 23, 34 }; double dx[] = { 1.2, 2.3, 3.4, 4.5, 5.6, 6.7 }; int* p = ar; // 1. 遍历数组 for (auto& x : ar) // elemtype + elemcount { std::cout << x << " "; } std::cout << std::endl; // 2. 遍历初始化列表 for (auto& x : { "yhping", "hello", "word" }) { std::cout << x << " "; } std::cout << std::endl; }3. 引用与值传递的遍历
使用引用遍历可以修改原数组元素,使用值遍历则不会影响原数组。
#include <iostream> int main() { int ar[] = { 12, 23, 34 }; double dx[] = { 1.2, 2.3, 3.4, 4.5, 5.6, 6.7 }; for (auto &x : ar) { std::cout << x << "\t"; x += 100; } std::cout << std::endl; for (auto x : dx) { std::cout << x << "\t"; } std::cout << std::endl; }4. 传统数组遍历
使用宏计算数组大小进行传统遍历。
#include <iostream> #define ArSize(x) (sizeof(x)/sizeof(x[0])) int main() { int ar[] = { 12, 23, 34 }; double dx[] = { 1.2, 2.3, 3.4, 4.5, 5.6, 6.7 }; for (int i = 0; i < ArSize(ar); ++i) { std::cout << ar[i] << " "; } }5. 内存管理对比
C 语言使用malloc、calloc、realloc和free,而 C++ 使用new和delete。
6. auto 类型推导
auto定义的变量可以根据初始化值在编译时推导出类型,但会自动剥离引用和 const 限定。
int main() { auto a = 10; // a = int; auto int auto dx = 12.25; // dx = double auto double auto p = &a; // p = int*; auto int* auto* s = &a, b = 10; // s => int *; auto int ; b => int; auto int // auto x; // 错误:auto 变量必须初始化 }7. decltype 类型推导
decltype会保持 const 限定,可以用于推导表达式类型而不实际执行。
#include <iostream> int main() { int x = 10; decltype(x) a = x; // int // decltype(变量名) → 取变量本身的类型 decltype((x)) rx = x; // int & // decltype((表达式)) → 表达式是左值时,会推导为引用类型 }8. decltype 与函数调用
decltype中的函数调用不会实际执行,只用于推导返回值类型。
#include <iostream> int Add(int a, int b) { std::cout << "Add(int a, int b)" << std::endl; return a + b; } int main() { std::cout << sizeof(Add(1, 2)) << std::endl; // Add(1, 2) 只是作为类型上下文被 sizeof 计算,函数并不会真的被调用 typedef decltype(Add(1, 2)) RetType; // decltype 里的函数调用不会实际执行,只是用来推导返回值类型 RetType x; x = Add(1, 2); // 只有这个才会真正调用函数并执行里面的 cout return 0; }9. decltype 与结构体
#include <iostream> struct Student { char s_name[20]; int s_age; }; int main() { int x = 10; int* p = &x; Student st{ "20204001", 12 }; typedef decltype(x) y; // int sizeof(x); y a, b; typedef decltype(st) sa; sa z, w; }10. 模板函数与 auto 返回值
使用auto作为函数返回值类型,实现通用最大值函数。
#include <iostream> #include <typeinfo> template<class T, class U> auto my_max(T a, U b) { return a > b ? a : b; } int main() { std::cout << my_max(12, 23) << std::endl; std::cout << my_max('a', 'b') << std::endl; std::cout << my_max(12, 34.23) << std::endl; auto x = my_max(12, 34.45); std::cout << typeid(x).name() << std::endl; std::cout << x << std::endl; // double auto y = my_max(100, 3.45); std::cout << typeid(y).name() << std::endl; std::cout << y << std::endl; // auto 会把两个操作数提升为 double }11. auto 的限制
auto不能用于非静态成员变量,也不能用于未初始化的变量。
struct Student { // auto age = 0; // 错误:C++11 不允许非静态成员变量使用 auto }; int main() { auto age = 0; // 正确 }12. 初始化列表与 auto
#include <iostream> struct Student { char s_id[10]; int s_age; }; struct Emp { char id[10]; int age; }; int main() { auto ax = { "2024", 12 }; // 初始化列表 }13. auto 参数函数
C++17 支持使用auto作为函数参数类型。
#include <iostream> void funa(auto ar) // C++17 { std::cout << typeid(ar).name() << std::endl; std::cout << "funa(auto ar): " << sizeof(ar) << std::endl; // 4 } void funb(auto& ar) { std::cout << typeid(ar).name() << std::endl; std::cout << "funa(auto &ar): " << sizeof(ar) << std::endl; // 40 } int main() { int ar[10] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 }; funa(ar); funb(ar); auto rb = ar; // rb int* auto& rc = ar; // rc int(&)[10] }14. auto 与 const 引用
int main() { int a = 10; const int& ra = a; // const int & auto rb = ra; // int (剥离了 const 和引用) auto rx = a; // int auto& crb = ra; // crb const int & auto* p = &ra; // const int * }15. 动态内存分配
展示 C++ 中new和delete的使用,以及 placement new 的用法。
#include <iostream> int main() { char str[10]; int* p = new int(10); delete p; p = (int*)::operator new(sizeof(int)); // p = (int*)malloc(sizeof(int)); ::operator delete(p); p = NULL; new (str) int(100); new (str + 4) int(20); }16. 数组的动态分配
#include <iostream> int main() { int n = 10; int* p = (int*)malloc(sizeof(int) * n); free(p); p = NULL; int* s = new int[n] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; // new int[n] // 1) sizeof(int[n]); 2) 调用构造函数; 3) 返回指针 for (int i = 0; i < n; ++i) { std::cout << s[i] << " "; } std::cout << std::endl; delete[] s; s = NULL; return 0; }