c++学习笔记(7)

本文详细介绍了C++中的substr()函数用于字符串截取,结构体和Node在数据组织中的应用,迭代器和for_each的使用,以及容器如vector、list、map的insert和find操作。还涵盖了lambda表达式的简洁语法和用法。
摘要由CSDN通过智能技术生成

1.在C++中,substr() 是一个用于截取字符串的成员函数。

substr()函数是std::string类的一部分,它用于从原始字符串中提取子字符串。这个函数接受两个参数:

  • 起始位置(pos):指定子字符串在原始字符串中的开始位置。这个位置是从0开始计数的,即字符串的第一个字符的位置是0。如果指定的起始位置超出了源字符串的长度,substr()将抛出一个std::out_of_range异常。

  • 长度(len):指定要截取的子字符串的长度。这个长度是可选的,如果不提供,substr()将返回从起始位置到原始字符串末尾的所有字符。

substr()函数的使用示例如下:

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::string sub = str.substr(0, 5); // 截取从位置0开始的5个字符
    std::cout << sub << std::endl; // 输出 "Hello"
    return 0;
}

                          

2.在C++中,struct(结构体)是一种用户定义的数据类型,它允许将多个不同数据类型的变量组合在一起作为一个单一的实体。

结构体的定义语法如下:

struct StructName {
    // 成员变量声明
};

其中,StructName是为结构体选择的名称,而花括号内部则是该结构体的成员变量。

例如,定义一个表示学生信息的结构体可以这样写:

struct Student {
    std::string name;   // 字符串类型,用于存储学生姓名
    int age;            // 整型,用于存储学生年龄
    double grade;       // 浮点型,用于存储学生成绩
};

一旦定义了结构体,可以像使用内置类型一样创建结构体变量:

Student student1; // 创建一个名为student1的Student结构体变量

可以通过.运算符访问结构体的成员变量:

student1.name = "Alice";  // 设置学生名字
student1.age = 20;        // 设置学生年龄
student1.grade = 85.5;    // 设置学生成绩

结构体还可以包含函数指针、嵌套的结构体、枚举等复杂的成员。

结构体与类非常相似,主要区别在于默认的访问权限:结构体的成员默认是公开的(public),而类的成员默认是私有的(private)。然而,你仍然可以在结构体中使用访问修饰符来指定成员的访问级别。

结构体通常用于组织和管理相关的数据项,使代码更加模块化和易于理解,特别是在需要处理复杂数据时。

             

3.在C++中,Node通常指的是链表中的一个节点的结构体定义。

Node结构体通常包含两个主要部分:数据域和指针域。数据域用于存储节点的值,而指针域则包含一个指向链表中下一个节点的指针。这种结构使得链表成为一种动态的数据结构,可以在运行时动态地添加或删除节点。

以下是一个简单的Node结构体定义的例子:

struct Node {
    int value; // 数据域,用于存储节点的值
    Node* next; // 指针域,指向链表中的下一个节点
};

在这个例子中,value是一个整数类型的成员,用于存储节点的数据,而next是一个指向同类型结构体的指针,用于链接到链表中的下一个节点。这种结构体定义可以用于构建单向链表或双向链表,具体取决于是否还包括指向前一个节点的指针。

此外,Node结构体也可以用于其他数据结构,如树或图,其中节点可能包含多个指针,分别指向子节点或相邻节点。

总的来说,Node在C++中是一种复合数据类型,用于表示数据结构中的单个元素,它通过包含数据和指针来建立元素之间的关系。

              

4.在C++中,iterator(迭代器)是一种设计模式,用于访问容器(如数组、列表、集合等)中的元素。迭代器提供了一种统一的方法来遍历不同类型的容器,而不需要了解容器的内部实现。

迭代器通常具有以下特点:

  1. 迭代器类型:每种容器都有自己的迭代器类型。例如,std::vector<int>的迭代器类型是std::vector<int>::iterator。

  2. 迭代器操作:迭代器支持几种基本操作,包括解引用(*)、递增(++)和递减(--)。解引用操作用于获取当前指向的元素的值,递增和递减操作用于移动迭代器到下一个或上一个元素。

  3. begin() 和 end() 函数:每个容器都提供begin()和end()成员函数,分别返回指向第一个元素和“超出”最后一个元素的迭代器。

  4. 范围for循环:C++11引入了范围for循环,允许直接遍历容器中的元素,而无需显式使用迭代器。

  5. 兼容性:某些算法(如std::sort)接受迭代器作为参数,可以对任何提供相应迭代器的容器进行操作。

下面是一个简单的使用迭代器遍历std::vector的例子:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用迭代器遍历vector
    for (std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 使用范围for循环遍历vector
    for (const auto& num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

在这个例子中,我们首先使用迭代器遍历了numbers向量,然后使用范围for循环再次遍历。

迭代器是C++标准库中的一个重要概念,它提供了一种通用和灵活的方法来处理集合中的数据。

           

5.在C++11中,for_each是一种算法函数,用于遍历容器(如数组、列表、集合等)中的元素并对每个元素执行指定的操作。

for_each函数的语法如下:

template <typename InputIterator, typename Function>
Function for_each(InputIterator first, InputIterator last, Function f);

其中,first和last是迭代器,表示要遍历的容器的范围;f是一个可调用对象(如函数指针、函数对象或lambda表达式),用于对每个元素执行操作。

for_each函数会依次将容器中的每个元素传递给f,并返回f的最后一个调用结果。

下面是一个简单的使用for_each的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用for_each打印vector中的每个元素
    std::for_each(numbers.begin(), numbers.end(), [](int num) {
        std::cout << num << " ";
    });
    std::cout << std::endl;
    return 0;
}

在这个例子中,我们使用for_each遍历了numbers向量,并使用lambda表达式打印每个元素

      

6.在C++中,lambda表达式是一种创建匿名函数对象的简洁语法。Lambda表达式通常用于定义简单的函数逻辑,尤其是在需要将函数作为参数传递给其他函数(如算法)时。

Lambda表达式的基本语法如下

[capture](parameters) -> return_type { function_body }

其中:

  1. capture:捕获列表,用于指定哪些外部变量可以在lambda表达式中使用。可以省略不写。

  2. parameters:参数列表,与普通函数的参数列表类似,可以省略不写。

  3. return_type:返回类型,可以省略不写,编译器会自动推导。

  4. function_body:函数体,包含lambda表达式的实现代码。

下面是一个简单的lambda表达式的例子:

auto sum = [](int a, int b) { return a + b; };

这个lambda表达式接受两个整数参数a和b,并返回它们的和。使用auto关键字可以让编译器自动推导lambda表达式的类型。

Lambda表达式还可以使用尾返回类型优化(C++14引入),即在函数体中直接返回一个表达式的结果,例如:

auto sum = [](int a, int b) -> int { return a + b; };

此外,lambda表达式还支持泛型编程,可以使用模板参数来定义更通用的函数逻辑,例如

template<typename T>
auto sum = [](T a, T b) -> T { return a + b; };

在这个例子中,sum是一个泛型的lambda表达式,可以接受不同类型的参数,并返回相同类型的结果。

      

7.在C++中,insert() 是一个成员函数,用于向容器(如 std::vector、std::list、std::map 等)中插入元素。不同的容器类型提供了不同版本的 insert() 函数,以适应各自的数据结构和操作方式。

以下是一些常见容器类型的 insert() 函数的用法:

  1. 对于 std::vector:

    在 std::vector 中,insert() 可以用于在指定位置插入一个元素或多个元素。

             插入单个元素:

std::vector<int> vec = {1, 2, 3};
vec.insert(vec.begin() + 1, 4); // 在位置 1 插入元素 4
// vec 现在为 {1, 4, 2, 3}

              插入多个元素:

std::vector<int> vec = {1, 2, 3};
vec.insert(vec.begin() + 1, std::initializer_list<int>{4, 5, 6});
// vec 现在为 {1, 4, 5, 6, 2, 3}

     2.对于 std::list:

             在 std::list 中,insert() 也可以用于在指定位置插入元素。

                     插入单个元素:

std::list<int> lst = {1, 2, 3};
lst.insert(lst.begin(), 4); // 在位置 0 插入元素 4
// lst 现在为 {4, 1, 2, 3}

                      在迭代器指向的位置插入多个元素:

std::list<int> lst = {1, 2, 3};
auto it = lst.begin();
++it; // 指向位置 1
lst.insert(it, std::initializer_list<int>{4, 5});
// lst 现在为 {1, 4, 5, 2, 3}

      3.对于 std::map 和 std::unordered_map:

        在这些关联容器中,insert() 用于插入键值对。返回的迭代器指向插入的元素。

std::map<int, std::string> m = {{1, "one"}, {2, "two"}};
m.insert({3, "three"}); // 插入新的键值对 {3, "three"}

注意,对于 std::map 和 std::unordered_map,如果尝试插入的键已经存在,insert() 不会改变已有的值,而是保留原来的值。

     

8.

在C++中,find()是一个常用的函数,它有多种用法和形式。

  1. 对于字符串:std::string::find()是std::string类的成员函数,用于查找子字符串或字符在字符串中的位置。如果查找成功,它会返回目标字符或子字符串的起始位置;如果未找到,则返回std::string::npos(通常是-1)。

  2. 对于序列式容器:find()是一个模板函数,通常位于<algorithm>头文件中。它用于在指定范围内查找与目标元素值相等的第一个元素。这个函数适用于所有支持输入迭代器和==运算符的序列式容器。如果找到目标元素,find()会返回一个指向该元素的迭代器;如果未找到,则返回的迭代器与结束迭代器last相同。

  3. 对于关联式容器:如std::map和std::unordered_map,它们也提供了find()成员函数,用于查找特定的键。如果找到了对应的键,find()会返回一个指向该键值对的迭代器;如果未找到,则返回end()迭代器。

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值