C++ 基础部分 个人笔记

本人菜鸟,个人学习笔记,如有错误还请指教

array.empty()不是包括array[0].empty()了嘛?

不是的。在大多数编程语言中,包括 C++ 中,array.empty() 方法只会检查数组是否为空,而不会检查数组中的元素是否为空。

如果您想检查array[0]是否为空,您需要调用array[0].empty()方法,或使用其他方法来检查该元素是否为空。

请注意,如果您尝试在一个空数组中访问array[0],这可能会导致运行时错误,因为数组中没有任何元素。因此,在访问数组元素之前,请确保该数组不为空。

数组是否为空和数组中的元素是否为空,有什么区别,我对此产生疑惑,需要补充哪些相关知识,请据出并解释。

数组是否为空和数组中的元素是否为空是两个不同的概念,需要区分开来。

一个数组是否为空通常指的是它是否包含任何元素。例如,在 C++ 中,可以使用 array.empty() 方法来检查数组是否为空。如果数组中没有任何元素,该方法将返回 true,否则返回 false。

一个数组中的元素是否为空通常指的是该元素是否有实际值或存在某种特定的状态。具体来说,对于像 C++ 这样的静态类型语言,数组中的每个元素都必须具有某种类型,例如 int 或 std::string。如果数组中的某个元素没有赋值,则它可能被认为是“空”的。另外,在一些情况下,我们可能需要使用特殊值(例如 nullptr)来表示某个元素的“空”状态。

需要注意的是,一个非空的数组中仍然可能包含“空”的元素。因此,我们需要区分数组是否为空和数组中的元素是否为空这两个概念。

为了进一步理解这些概念,您可能需要了解数组的基本概念,如数组的定义、初始化和访问。您还可以学习特定编程语言中用于处理数组的函数和方法,例如 C++ 中的 array.empty() 和 array[0].empty() 方法。


什么时候 用while 什么时候用for

在C++中,for 和 while 循环都可以用来遍历数组、链表等数据结构中的元素。但是在不同的情况下,使用哪种循环更合适可能会有所不同。

一般来说,for 循环适合于已知循环次数的情况,而 while 循环适合于不知道循环次数的情况。具体来说,下面是一些使用场景的建议:

如果需要遍历一个已知长度的数组或容器,通常使用 for 循环,例如:
C++

for (int i = 0; i < n; i++) {
    // do something with nums[i]
}

其中 n 是数组或容器的长度,这种情况下使用 for 循环更加直观,因为循环次数已知。

如果需要对某个条件进行循环,但是不知道循环次数,或者循环次数非常大,可能需要使用 while 循环,例如:
C++

while (someCondition) {
    // do something
}

其中 someCondition 是一个布尔表达式,只有当其值为 true 时才会执行循环体中的代码。这种情况下使用 while 循环更加灵活,可以根据条件进行灵活的控制循环次数。

如果需要对某个容器中的元素进行遍历,而不关心遍历顺序,可以使用 for-each 循环,例如:
C++

vector<int> nums = {1, 2, 3, 4};
for (int x : nums) {
    // do something with x
}

这种情况下使用 for-each 循环更加简洁明了,不需要手动维护索引。

总的来说,使用 for 循环或 while 循环并没有严格的规定,具体取决于代码的需求和个人的习惯。在实际开发中,需要灵活地根据具体情况选择合适的循环语句。


if (s[i] == ' ') 和 if (s[i] ==" ") 有什么区别嘛? 关于双引号和单引号

在大多数编程语言中,单引号和双引号用于表示不同类型的数据。单引号用于表示一个字符(char),而双引号用于表示一个字符串(string)。

在C、C++、Java和许多其他编程语言中,单引号表示一个字符,而双引号表示一个字符串。因此,使用单引号时应该用单个字符,而使用双引号时应该用多个字符来表示一个字符串。

在C、C++、Java等语言中,如果您尝试使用双引号将一个字符串与一个字符进行比较,则会得到一个编译时错误,因为这是不允许的。因此,如果您想将一个字符与一个空格进行比较,应该使用单引号,而不是双引号。

因此,如果您想比较一个字符是否等于一个空格,应该使用单引号,如下所示:

if (s[i] == ' ') {
    // 执行某些操作
}

如果您使用双引号,则会编译时错误,如下所示:

if (s[i] == " ") {
    // 编译时错误
}


C++ 模板是什么

C++ 模板是一种基于类型参数化的编程技术,使用模板可以使得程序员编写独立于具体数据类型的通用代码。通过参数化类型,你可以创建一种可以在多种类型上执行相同操作的函数或类,从而提高代码的复用性和可读性。C++ 模板广泛应用于 STL (标准模板库)中,如容器、迭代器、算法等。
C++ 模板可以提供两种类型的参数化,即函数模板和类模板。函数模板可以让你定义一个通用函数,而类模板可以让你定义一个通用类。下面是一个函数模板的例子:


template <typename T>
T max(T x, T y) {
    return (x > y) ? x : y;
}

在上面的例子中,我们定义了一个模板函数 max,它可以用于比较两个同类型的数据,并返回其中较大的值。模板参数 T 表示要比较的数据类型,在函数体中,我们可以像使用普通函数一样使用 T 类型的变量,这样就将通用代码与特定的数据类型解耦开来。
对于类模板,也可以按照类似的方式来定义,例如:

template <typename T>
class Stack {
 private:
   T* elements;
   int size;
 public:
   Stack(int n) : size(n), elements(new T[n]) {}
   void push(T const& elem) { /* ... */ }
   T pop() { /* ... */ }
};

在上述例子中,我们定义了一个模板类 Stack,它用于创造一个通用的堆栈数据结构。与函数模板一样,模板参数 T 可以被用于类中的函数、变量等地方来表示数据类型。
总体来说,C++ 模板为程序员提供了非常强大的编程工具和技术手段,尤其是在创建通用库和算法时,可大大提高代码的复用性和可读性,同时也去除了代码的冗余,节约了编码的时间。

C++的模板是不是像C#中的泛型?

是的,C++ 的模板与 C# 的泛型有很多相似之处。实际上,C# 的泛型部分就是受到了 C++ 模板的启发。下面是一些两者之间的相似之处:

  1. 参数化:C++ 模板和 C# 泛型都允许参数化类型,这意味着允许编写一些通用的代码,使之能够适用于不同的数据类型。
  2. 反省机制:C++ 模板和 C# 泛型都使用反省(reflection)机制,允许编译器在编译时生成特定的代码,而不是在执行时根据参数生成代码。
  3. 安全性:C++ 模板和 C# 泛型都提供了类型安全,可以预先规定类型,从而减少程序员在程序开发过程中可能引发的类型错误。
  4. 通用性:C++ 模板和 C# 泛型都允许在常规的数据类型和自定义类型上使用。
    当然,两者也有一些不同之处。首先,C++ 模板是一种更底层的机制,它可以非常细粒度地控制生成的代码,并提供了更大的灵活性。其次,C++ 模板中有一些语法和细节问题需要注意,例如 typename 关键词和非类型形参的使用。
    综上所述,尽管 C++ 模板和 C# 泛型有许多相似之处,但它们仍然是两种不同的技术,每种技术都有其优缺点,可根据需要来选择。


    int m;
    cin >> m;
    getchar(); 
    while (m--) 
    { ...} 

🙆‍♀️我想问:getchar(); 它的用法


🦸‍♀️在这段代码中,getchar() 函数用于读取键盘输入缓冲区中的换行符。这是因为,在使用 cin >> m; 从标准输入流中读取输入值时,如果用户在输入m的同时按下了 Enter 键(即回车键),则缓冲区中就会存储一个 '\n'(换行符)字符。

当后续程序尝试读取 m-- 次输入时,原本应该被用作输入的换行符会被视为新一轮输入的起始字符从而导致错误,因此需要先通过调用 getchar() 函数来把缓冲区中的换行符读入消耗掉,以便后续程序能够正常获取键盘输入。

需要注意的是,当我们使用 cin 进行输入时,它会自动忽略输入数据中的空格、制表符和换行符等空白字符,而 getchar() 则会把这些字符全部读取进去,包括最后的换行符。因此,我们在使用 getchar() 函数时需要注意控制输入缓冲区中的字符数量,避免不必要的错误发生。


🙆‍♀️ "它会自动忽略输入数据中的空格、制表符和换行符等空白字符,而 getchar() 则会把这些字符全部读取进去,包括最后的换行" 这是怎么做到的?getchar()函数在cin>> 操作后面呀
🦸‍♀️`cin` 和 `getchar()` 两个函数在读取字符时的处理方式确实是有所不同的。

当使用 cin 进行输入时,它会从标准输入流中依次读取字符,并忽略其中的空白字符(包括空格、制表符和换行符等),只把有效字符部分存储到变量中。举个例子,如果用户输入了 "12 34",则第一次调用 cin 时会读取整个字符串 "12" 并将其转换成一个整数存储到内存中,而第二次调用 cin 时则会忽略输入中的空格,重新读取下一个整数部分 "34" 并做相同的转换。

getchar() 函数则会从标准输入流中读取一个字符,不会自动忽略空白字符,包括其中的换行符。在上面代码示例中,getchar() 函数在 cin 后使用是为了消耗掉输入缓冲区中残留的换行符,避免它影响后续程序的读入操作。如果不使用 getchar() 调用来清除缓冲区,这些错误的换行符可能会被当作有效的输入数据被程序误解析。

总结来说,getchar()cin 在读取字符时处理方式的不同主要源于它们对于空白字符的不同处理方式。cin 会忽略空白字符,只把有效字符部分存储到变量中,而 getchar() 则会读取空白字符及其中的换行符等所有字符,并且这些字符会被直接传递给后续程序,需要根据实际情况进行相应地处理。


🙆‍♀️“如果用户输入了 "12 34",则第一次调用 cin...而第二次调用 cin 时...” 你说的第一次第二次是指 两次cin>>嘛? 还是 cin>>输入的时候 输入一次“12 34”

🦸‍♀️对不起,我的表达可能有些模糊。我这里说的第一次和第二次调用 cin,是指在读取 "12 34" 这个字符串时发生的两个操作。实际上只需要单次调用 cin 就可以完成整个数据读取过程。

举个例子,如果输入是 "12 34",那么使用 cin 进行数据读取的代码应该是:

int num1, num2;
cin >> num1 >> num2;

在这段代码中,cin 会自动忽略掉输入字符串中的空格字符,同时将输入分别存储到 num1num2 两个变量中,即 num1 的值为 12,num2 的值为 34。

而使用 getchar() 函数则需要显式地读取完整的输入字符串,然后逐个字符进行处理:

char c;
while ((c = getchar()) != '\n') {
    // do something with 'c'
}

在这段代码中,程序会依次读取输入字符串中的每个字符,并在遇到换行符 \n 后跳出循环。在每次循环中,我们可以对读取到的字符 c 进行相应的处理,例如统计字符数量、判断是否为数字等等。

posted @ 2023-03-14 18:28  专心Coding的程侠  阅读(34)  评论(0编辑  收藏  举报