向量与数组相关问题总结及相关代码

本文详细解释了商业交易中的买者自慎原则,探讨了C++中浅拷贝的概念及其在类对象中的应用,涉及浅拷贝、深拷贝、拷贝构造函数、拷贝赋值的区别,以及数组、指针、引用的使用和C风格字符串。还展示了如何检查字符串是否为回文。
摘要由CSDN通过智能技术生成

1. “买者自慎”(caveat emptor)是一句拉丁语法律术语,意思是“让买方小心”或“买方自行承担风险”。在商业和消费者交易中,它意味着买方有责任在购买商品或服务之前进行充分的调查和检查,以确保其满足自己的需求和期望。如果商品或服务存在问题或缺陷,买方通常不能追究卖方的责任,除非存在欺诈或其他违法行为。

```cpp // 示例:购买二手车 假设你正在购买一辆二手车。在这种情况下,“买者自慎”原则适用。 作为买方,你有责任在购买之前对车辆进行检查,包括检查车辆的外观、机械状况、行驶里程等。 如果你没有进行充分的检查,购买了一辆有问题的车辆,那么通常情况下你不能追究卖方的责任,除非卖方故意隐瞒了车辆的问题。 因此,在购买二手车时,你应该谨慎行事,进行充分的调查和检查,以避免购买到不符合期望的车辆。 ```

2. 对于类对象而言,拷贝的默认含义是进行浅拷贝。浅拷贝是指将对象的成员变量的值复制到新的对象中,但不复制成员变量本身。这意味着,如果类中存在指针或引用类型的成员变量,浅拷贝只会复制指针或引用的值,而不会创建新的指针或引用。

```cpp // 示例:浅拷贝的问题 class MyClass { public: int num; string str; vector<int>* ptr; MyClass(int n, string s, vector<int>* p) { num = n; str = s; ptr = p; } }; int main() { vector<int> vec = {1, 2, 3, 4, 5}; MyClass obj1(1, "Hello", &vec); MyClass obj2 = obj1; // 执行浅拷贝 // 修改 ptr 指向的内容 obj2.ptr->push_back(6); // 打印 obj1 和 obj2 的内容 cout << "obj1: " << obj1.num << ", " << obj1.str << ", " << *obj1.ptr << endl; cout << "obj2: " << obj2.num << ", " << obj2.str << ", " << *obj2.ptr << endl; return 0; } ```

在上述示例中,我们创建了一个 `MyClass` 类,其中包含了一个整数成员 `num`、一个字符串成员 `str` 和一个指向 `vector<int>` 对象的指针成员 `ptr`。我们创建了两个 `MyClass` 对象 `obj1` 和 `obj2`,并通过浅拷贝将 `obj1` 的值复制到 `obj2` 中。 然后,我们修改了 `obj2.ptr` 指向的 `vector<int>` 对象的内容,向其中添加了一个新元素。最后,我们打印了 `obj1` 和 `obj2` 的内容,可以看到 `obj1` 的 `ptr` 成员指向的内容也被修改了,因为浅拷贝只复制了指针的值。

3. 类对象拷贝的默认含义在某些情况下是合适的,例如当类的成员变量都是基本数据类型(如整数、浮点数、布尔值等)时,浅拷贝可以满足需求。因为基本数据类型的值是直接复制的,不会存在引用或指针的问题。

```cpp // 示例:基本数据类型的浅拷贝 class MyClass { public: int num; string str; MyClass(int n, string s) { num = n; str = s; } }; int main() { MyClass obj1(1, "Hello"); MyClass obj2 = obj1; // 执行浅拷贝 // 修改 obj2 的内容 obj2.num = 2; obj2.str = "World"; // 打印 obj1 和 obj2 的内容 cout << "obj1: " << obj1.num << ", " << obj1.str << endl; cout << "obj2: " << obj2.num << ", " << obj2.str << endl; return 0; } ```

在这个示例中,我们修改了 `obj2` 的成员变量的值,但 `obj1` 的内容不受影响,因为浅拷贝只复制了基本数据类型的值。

4. 拷贝构造函数是一种特殊的构造函数,用于创建一个对象,该对象是另一个对象的副本。拷贝构造函数在创建对象时使用已存在的对象进行初始化。

```cpp // 示例:拷贝构造函数 class MyClass { public: int num; string str; MyClass(int n, string s) { num = n; str = s; } MyClass(const MyClass& other) : num(other.num), str(other.str) {} }; int main() { MyClass obj1(1, "Hello"); MyClass obj2(obj1); // 调用拷贝构造函数 // 修改 obj2 的内容 obj2.num = 2; obj2.str = "World"; // 打印 obj1 和 obj2 的内容 cout << "obj1: " << obj1.num << ", " << obj1.str << endl; cout << "obj2: " << obj2.num << ", " << obj2.str << endl; return 0; } ```

在上述示例中,我们定义了一个 `MyClass` 类,并在其中定义了一个拷贝构造函数。拷贝构造函数使用参数 `other` 的成员变量值来初始化新对象的成员变量。 在 `main()` 函数中,我们创建了一个 `obj1` 对象,并使用它来初始化 `obj2` 对象。这会调用拷贝构造函数,将 `obj1` 的内容复制到 `obj2` 中。

5. 拷贝赋值是一种赋值操作,用于将一个对象的内容复制到另一个对象中。拷贝赋值操作使用已存在的对象进行赋值。

```cpp // 示例:拷贝赋值 class MyClass { public: int num; string str; MyClass(int n, string s) { num = n; str = s; } MyClass& operator=(const MyClass& other) { num = other.num; str = other.str; return *this; } }; int main() { MyClass obj1(1, "Hello"); MyClass obj2 = obj1; // 调用拷贝赋值运算符 // 修改 obj2 的内容 obj2.num = 2; obj2.str = "World"; // 打印 obj1 和 obj2 的内容 cout << "obj1: " << obj1.num << ", " << obj1.str << endl; cout << "obj2: " << obj2.num << ", " << obj2.str << endl; return 0; } ```

在上述示例中,我们定义了一个 `MyClass` 类,并在其中定义了一个拷贝赋值运算符。拷贝赋值运算符将参数 `other` 的成员变量值复制到当前对象的成员变量中。 在 `main()` 函数中,我们创建了一个 `obj1` 对象,并使用它来初始化 `obj2` 对象。这会调用拷贝赋值运算符,将 `obj1` 的内容复制到 `obj2` 中。

6. 拷贝赋值与拷贝初始化之间的区别在于拷贝赋值是在已经存在的对象上进行赋值操作,而拷贝初始化是创建一个新的对象并进行初始化。

```cpp // 示例:拷贝赋值与拷贝初始化的区别 class MyClass { public: int num; string str; MyClass(int n, string s) { num = n; str = s; } MyClass& operator=(const MyClass& other) { num = other.num; str = other.str; return *this; } }; int main() { MyClass obj1(1, "Hello"); MyClass obj2 = obj1; // 拷贝初始化 MyClass obj3 = MyClass(obj1); // 拷贝构造函数 obj2 = obj1; // 拷贝赋值 // 打印 obj1、obj2 和 obj3 的内容 cout << "obj1: " << obj1.num << ", " << obj1.str << endl; cout << "obj2: " << obj2.num << ", " << obj2.str << endl; cout << "obj3: " << obj3.num << ", " << obj3.str << endl; return 0; } ```

在上述示例中,我们创建了一个 `MyClass` 类,并分别使用拷贝初始化、拷贝构造函数和拷贝赋值来复制对象的内容。

7. 浅拷贝是指在拷贝过程中只复制了对象的成员变量的值,而不复制对象的内部指针或引用所指向的内容。这意味着,如果原始对象中存在指向其他对象的指针或引用,浅拷贝只会复制指针或引用的值,而不会创建新的指向对象。

```cpp // 示例:浅拷贝的问题 class MyClass { public: int num; string str; vector<int>* ptr; MyClass(int n, string s, vector<int>* p) { num = n; str = s; ptr = p; } }; int main() { vector<int> vec = {1, 2, 3, 4, 5}; MyClass obj1(1, "Hello", &vec); MyClass obj2 = obj1''

12. 数组是一种用于存储多个相同类型元素的数据结构。在 C++ 中,可以使用数组来存储一系列整数、字符或其他数据类型的元素。 示例代码如下:

```cpp #include <iostream> int main() { // 定义一个整数数组 arr int arr[5] = {10, 20, 30, 40, 50}; // 使用循环遍历数组并打印每个元素 for (int i = 0; i < 5; i++) { std::cout << arr[i] << " "; } std::cout << std::endl; return 0; } ```

在上面的示例中,我们定义了一个包含 5 个整数的数组 `arr`,并使用循环遍历数组并打印每个元素。

13. 拷贝一个数组可以使用 `std::copy` 函数。该函数接受三个参数:目标数组、源数组的起始位置和源数组的结束位置。 示例代码如下:

```cpp #include <iostream> #include <vector> int main() { // 定义源数组 int arr[5] = {10, 20, 30, 40, 50}; // 定义目标数组 int dest[5]; // 使用 std::copy 函数拷贝数组 std::copy(arr, arr + 5, dest); // 打印目标数组 for (int i = 0; i < 5; i++) { std::cout << dest[i] << " "; } std::cout << std::endl; return 0; } ```

在上面的示例中,我们定义了一个源数组 `arr` 和一个目标数组 `dest`。然后,使用 `std::copy` 函数将源数组拷贝到目标数组中。

14. 数组的初始化可以在定义数组时进行。可以使用花括号 `{}` 来指定数组的初始值。 示例代码如下:

```cpp #include <iostream> int main() { // 定义一个整数数组并初始化 int arr[5] = {10, 20, 30, 40, 50}; // 打印数组的每个元素 for (int i = 0; i < 5; i++) { std::cout << arr[i] << " "; } std::cout << std::endl; return 0; } ```

在上面的示例中,我们在定义数组时使用花括号指定了数组的初始值。

15. 指针参数和引用参数在函数调用时的行为不同。使用指针参数时,函数会接收指向实际参数的指针,这意味着函数可以修改原始参数的值。而使用引用参数时,函数会接收原始参数的别名,这意味着函数可以直接修改原始参数的值。 示例代码如下:

```cpp #include <iostream> void modifyValue(int* valuePtr) { // 使用指针修改原始参数的值 *valuePtr = 100; } void modifyValue(int& value) { // 使用引用来修改原始参数的值 value = 100; } int main() { int num = 42; std::cout << "Before modification: " << num << std::endl; // 使用指针参数调用函数 modifyValue(&num); // 使用引用参数调用函数 modifyValue(num); std::cout << "After modification: " << num << std::endl; return 0; } ```

在上面的示例中,我们定义了两个函数 `modifyValue`,一个使用指针参数,一个使用引用参数。然后,我们将原始变量 `num` 分别作为指针和引用传递给函数,并观察它们的行为。

16. C 风格字符串是一种以 `\0` 结尾的字符数组,用于表示字符串。 示例代码如下:

```cpp #include <iostream> int main() { // 定义一个 C 风格字符串 char cString[] = "Hello, World!"; // 打印 C 风格字符串 std::cout << cString << std::endl; return 0; } ```

在上面的示例中,我们定义了一个 C 风格字符串 `cString`,并使用 `std::cout` 打印该字符串。

17. 回文是指一个字符串在正序和逆序读取时都具有相同的字符序列。例如,"madam" 是一个回文。 示例代码如下:

```cpp #include <iostream> #include <string> bool isPalindrome(const std::string& str) { // 检查字符串是否为空或长度为 1 if (str.empty() || str.length() == 1) { return true; } // 比较字符串的前半部分和后半部分是否相等 for (int i = 0; i < str.length() / 2; i++) { if (str[i] != str[str.length() - i - 1]) { return false; } } return true; } int main() { std::string str = "radar"; if (isPalindrome(str)) { std::cout << str << " 是回文" << std::endl; } else { std::cout << str << " 不是回文" << std::endl; } return 0; } ```

在上面的示例中,我们定义了一个函数 `isPalindrome`,用于检查字符串是否是回文。然后,在 `main` 函数中调用该函数来检查字符串 `str` 是否是回文,并打印相应的结果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值