大二上 数据结构与算法笔记 20241024

一.inline

在 C 和 C++ 编程语言中,inline 关键字是一种函数修饰符,用于建议编译器在编译时将函数的代码直接插入到每个函数调用的地方,而不是进行常规的函数调用。这样做的目的是减少函数调用的开销,尤其是在函数体较小且调用频繁的情况下。

作用和优点:

  1. 减少函数调用开销:通过将函数代码直接插入到调用点,避免了函数调用的额外开销,如参数传递、栈帧的创建和销毁等。
  2. 提高程序运行效率:对于小型函数,inline 可以提高程序的运行效率,因为编译器可以优化掉函数调用的额外开销。
  3. 编译器优化:使用 inline 函数可以让编译器有更多的机会进行优化,因为它可以在编译时看到函数的完整定义。

注意事项:

  1. 编译器的自由裁量:尽管你可以使用inline来建议编译器内联函数,但编译器有权决定是否实际进行内联。编译器会根据函数的大小、复杂度以及调用频率等因素来决定是否内联。
  2. 代码膨胀:过度使用inline可能会导致代码膨胀,因为函数的代码会在每个调用点被复制,这可能会增加程序的总大小。
  3. 调试:使用 inline 函数可能会使得调试变得更加复杂,因为函数的代码在多个地方被复制,这可能会影响调试器的断点设置和错误定位。

使用示例:

inline int add(int a, int b) {
return a + b;
}

在这个例子中,add 函数被声明为 inline 函数,编译器会尝试在每个调用 add 的地方直接插入其代码,而不是进行常规的函数调用。

结论:

inline 是一种有用的函数修饰符,可以在适当的场景下提高程序的运行效率。然而,它并不是银弹,需要根据实际情况谨慎使用。在现代编译器中,即使没有显式声明 inline,编译器也会自动进行内联优化。

二.递归函数中用局部变量

写递归函数的时候,递归时尽量在函数内部定义一个局部变量来用,不使用整体变量进行递归。
全局变量在递归调用中被修改,可能导致在不同的递归层次中出现冲突。每次递归调用都应该使用局部变量来避免这种情况。

三.register int的应用

register int 是 C 和 C++ 编程语言中的一个概念,用于建议编译器将变量存储在 CPU 的寄存器中,而不是内存中。寄存器是 CPU 内部的一小部分高速存储区域,访问速度远远快于主内存。因此,将频繁访问的变量存储在寄存器中可以提高程序的运行效率。

组成部分:
register:这是一个存储类说明符,用于建议编译器将变量存储在寄存器中。
int:这是一个数据类型,表示整数。
使用场景:
在早期的 C 和 C++ 程序中,程序员可能会使用 register int 来声明那些在循环或频繁操作中使用,且对性能有较高要求的变量。例如:

register int i;
for (i = 0; i < 1000; i++) {
// 循环体
}
注意事项:
编译器的自由裁量:尽管程序员可以使用 register 来建议编译器将变量存储在寄存器中,但编译器有权忽略这个建议,因为编译器会根据实际情况决定如何最优化代码。

现代编译器的优化:随着编译器技术的发展,现代编译器已经非常智能,能够自动决定哪些变量应该存储在寄存器中。因此,显式使用 register 的需求已经大大降低。

C++17 弃用:在 C++17 标准中,register 已经被标记为弃用,这意味着在未来的 C++ 版本中,这个关键字可能会被完全移除。

现代硬件的影响:现代 CPU 拥有更多的寄存器,以及更复杂的缓存系统,这使得编译器的自动优化更加有效,减少了程序员手动优化的必要性。

总的来说,register int 是一个遗留自早期编程实践的概念,它反映了程序员试图通过手动优化来提高程序性能的努力。然而,在现代编程实践中,这种优化方式已经不再常见,编译器的自动优化通常更加有效。

register int即RI。
在 C++ 代码中,RI 是一个宏定义(macro),用于声明一个 register int 类型的变量。register 是 C++ 中的一个关键字,用于建议编译器将变量存储在寄存器中而不是内存中。这样做的目的是为了提高访问变量的速度,因为寄存器的访问速度通常比内存快得多。

然而,需要注意的是,在现代编译器中,register 关键字的影响已经非常有限,因为编译器通常能够自动做出最优化的决策。此外,从 C++11 开始,register 关键字已经不再被推荐使用,并且在 C++17 中被标记为弃用。

在提供的代码中,RI 被定义为 register int,这通常用于声明一个局部变量,例如:

RI i; // 使用 RI 宏定义声明一个 register int 类型的变量 i

这行代码的作用等同于直接声明一个 register int 类型的变量 i。在某些情况下,使用 register 关键字可能会对编译器的优化产生一定的影响,但这种影响通常很小,而且在现代编程实践中,通常不再使用 register 关键字。

四.getline

getline 是 C++ 标准库中的一个函数,用于从输入流中读取一行字符串。这个函数可以处理空格和换行符,与 cin >> 不同的是,getline 会读取并包含字符串中的空格,直到遇到换行符。

函数的基本用法如下:

getline(istream& is, string& str);
  • is 是输入流的引用,可以是 cin、文件流(如 ifstream)或任何其他输入流对象。
  • str 是一个字符串变量的引用,用于存储从输入流中读取的行。

函数从输入流中读取字符,直到遇到换行符('\n')为止。换行符不会被存储在字符串中,但会在字符串末尾添加一个空字符('\0')以形成一个正确的字符串终止符。

示例用法:

  1. cin 读取一行:
#include <iostream>
#include <string>

int main() {
    std::string line;
    std::cout << "请输入一行文本:" << std::endl;
    std::getline(std::cin, line);
    std::cout << "你输入的行是:" << line << std::endl;
    return 0;
}
  1. 从文件流中读取一行:
#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::ifstream file("example.txt");
    std::string line;
    if (file.is_open()) {
        while (std::getline(file, line)) {
            std::cout << line << std::endl;
        }
        file.close();
    } else {
        std::cout << "无法打开文件" << std::endl;
    }
    return 0;
}

注意事项:

  • 如果输入流已经处于错误状态(如文件未打开),getline 将不会读取任何内容,并返回 false。
  • getline 可以正确处理包含空格的行,这与 cin >> 形成对比,后者会在遇到空格时停止读取。
  • 如果需要从 cin 读取多个值,并且希望包括空格,可以使用 getline 读取整行,然后使用 std::istringstream 来分割该行。

五.istringstream的用法

istringstream iss1(line); 这行代码在C++中创建了一个名为 iss1istringstream 对象。istringstream 是定义在 <sstream> 头文件中的一个类,它是标准库中的一个字符串流(string stream)类,用于将字符串作为流来处理。

这里的 istringstream 被用来从字符串中读取数据,就像从一个文件或标准输入流中读取数据一样。你可以使用流提取操作符 >>istringstream 对象中提取数据,这与从 cin 或文件流中提取数据的方式相同。

具体来说,istringstream iss1(line); 这行代码做了以下几件事:

  1. 创建了一个 istringstream 类型的对象 iss1
  2. line 字符串作为参数传递给 iss1 的构造函数,这样 iss1 就包含了 line 字符串的内容。
  3. 现在,iss1 可以像处理标准输入流 cin 一样被用来读取数据。例如,你可以使用 iss1 >> num; 来从 iss1 中读取整数到变量 num

这种方式常用于需要从单个字符串中多次读取多个数据值的场景。通过将字符串转换为流,你可以使用标准的输入流操作符来逐个提取字符串中的值。

posted @   陆舟LandBoat  阅读(33)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示