一、c++auto定义的变量
在C++中,auto关键字用于自动类型推导,让编译器根据初始化表达式自动推断变量的类型。以下是关于auto的详细说明:
1. 基本用法
cpp
#include <iostream>
#include <vector>
#include <map>
int main() {
// 基本类型推导
auto i = 42; // int
auto d = 3.14; // double
auto c = 'A'; // char
auto b = true; // bool
auto s = "hello"; // const char*
// 引用和const
int x = 10;
auto& ref = x; // int&
const auto const_x = x; // const int
}
2. 函数返回类型推导(C++14)
cpp
// C++14允许函数返回类型使用auto
auto add(int a, int b) {
return a + b; // 返回类型推导为int
}
// 尾置返回类型(C++11)
auto multiply(int a, int b) -> int {
return a * b;
}
// 复杂的返回类型
auto create_vector() {
return std::vector<int>{1, 2, 3, 4, 5};
}
二、C++11 decltype 详解
decltype 是 C++11 引入的一个关键字,用于查询表达式的类型 ,而不会实际执行该表达式。它是类型推导的重要工具,与 auto 相辅相成。
📝 基本语法
cpp
decltype(表达式) 变量名 = 表达式;
// 或
decltype(表达式) 变量名;
🎯 核心用法与示例
1. 基本类型推导
cpp
#include <iostream>
#include <typeinfo>
int main() {
int x = 42;
const double y = 3.14;
int& ref = x;
const int* ptr = &x;
// 基本类型推导
decltype(x) a; // int
decltype(y) b = 3.14; // const double(保留const)
decltype(ref) c = x; // int&(保留引用)
decltype(ptr) d; // const int*(保留指针const属性)
// 表达式类型
decltype(x + y) e; // double(算术转换的结果类型)
decltype(*ptr) f = x; // const int&(解引用指针返回左值引用)
std::cout << "Type of a: " << typeid(a).name() << std::endl;
std::cout << "Type of b: " << typeid(b).name() << std::endl;
return 0;
}
C++11 基于范围的 for 循环详解
基于范围的 for 循环(Range-based for loop)是 C++11 引入的一个语法糖,它极大地简化了遍历容器元素的操作,让代码更简洁、更易读。
📝 基本语法
cpp
for (元素声明 : 容器或数组) {
// 循环体
}
🎯 基础用法
cpp
#include <iostream>
int main() {
int arr[] = {1, 2, 3, 4, 5};
// 只读遍历
for (int x : arr) {
std::cout << x << " ";
}
// 输出: 1 2 3 4 5
// 使用 auto 自动推导类型
for (auto x : arr) {
std::cout << x << " ";
}
return 0;
}
引用后循环会让数组元素加10
cpp
int main()
{
int arr[] = {1,2,3,4,5,6};
for (auto &x : arr)
{
cout << x << "\t";
x += 10;
}
cout << "\n";
for (auto x : arr)
{
cout << x << "\t";
}
cout << endl;
return 0;
}
三、stringstream
stringstream 是 C++ 中非常实用的字符串流处理类,让我详细介绍它的用法:
基本概念
stringstream 属于 <sstream> 头文件,可以把字符串当作流来处理,实现字符串和其他数据类型的转换。
主要功能
1. 字符串拼接
cpp
#include <sstream>
#include <iostream>
using namespace std;
int main() {
stringstream ss;
// 像cout一样使用
ss << "Hello" << " " << "World" << 123;
string result = ss.str(); // 获取拼接后的字符串
cout << result << endl; // 输出:Hello World123
return 0;
}
2. 类型转换
cpp
// 字符串转数字
stringstream ss;
ss << "123";
int num;
ss >> num; // num = 123
// 数字转字符串
stringstream ss2;
ss2 << 456;
string str = ss2.str(); // str = "456"
3. 解析字符串(类似split功能)
cpp
int main()
{
string data = "apple 123 45.6";
stringstream ss(data);
string fruit;
int number;
double value;
ss >> fruit >> number >> value;
cout << fruit << " "<<number << " " << value << endl;
return 0;
}
四、nullptr
nullptr 是 C++11 引入的空指针常量,用来替代传统的 NULL 或 0
为什么需要 nullptr?
传统 NULL 的问题
cpp
// 问题1:函数重载混淆
void func(int x) { cout << "调用int版本"; }
void func(char* p) { cout << "调用指针版本"; }
func(NULL); // 调用哪个?实际上调用 int 版本!
func(nullptr); // 明确调用指针版本 ✅
nullptr 的优点
cpp
int* p1 = NULL; // 可以,但实际上是0
int* p2 = 0; // 可以,但容易混淆
int* p3 = nullptr; // 明确表示空指针 ✅
// nullptr 有明确的类型
cout << typeid(nullptr).name(); // 输出:std::nullptr_t
基本用法
cpp
int* ptr = nullptr; // 初始化空指针
if (ptr == nullptr) {
cout << "指针为空" << endl;
}
// 检查指针是否为空
if (ptr) { // 等价于 ptr != nullptr
cout << "指针非空" << endl;
} else {
cout << "指针为空" << endl;
}
nullptr vs NULL
| 特性 | nullptr | NULL |
|---|---|---|
| C++11引入 | ✅ | ❌(传统) |
| 类型安全 | ✅ | ❌ |
| 明确表示指针 | ✅ | ❌(可能是整数0) |
| 可与任何指针类型转换 | ✅ | ✅ |
| 可用于模板推导 | ✅ | ❌ |
五、typedef 和 using
typedef 和 using 都是用来创建类型别名的关键字,让我详细介绍它们的区别和用法
基本语法对比
typedef (传统C++风格)
cpp
typedef 原类型 新别名;
typedef int Integer;
typedef void (*FuncPtr)(int, double); // 函数指针
using (C++11引入,更现代)
cpp
using 新别名 = 原类型;
using Integer = int;
using FuncPtr = void (*)(int, double); // 函数指针
简单类型别名
cpp
// typedef
typedef unsigned int uint;
typedef std::string String;
typedef std::vector<int> IntVector;
// using (更直观)
using uint = unsigned int;
using String = std::string;
using IntVector = std::vector<int>;
复杂类型 - 函数指针
cpp
// typedef (难读)
typedef void (*Callback)(int, const std::string&);
typedef int (&ArrayRef)[10];
// using (清晰)
using Callback = void (*)(int, const std::string&);
using ArrayRef = int (&)[10];
和模板结合
cpp
#include<iostream>
using namespace std;
template<class T,size_t N>
using Array = T[N];
int main()
{
Array<int, 5>ar, br, cr;
Array<double, 6>dr;
Array<int*, 10>par;
return 0;
}