1.普通数组、array、vector的相关性,以及,区别
相关性
存储多个元素:
1. 普通数组: 使用 C 风格数组声明和定义,大小固定。
2. array: 是 C++11 引入的标准库容器,提供了数组的替代,大小固定。
3. vector: 是 C++ 标准库中的动态数组,大小可以动态调整。
元素访问:
1. 普通数组和array: 使用索引进行元素访问,支持随机访问。
2. vector: 也支持随机访问,但由于其动态性,访问元素时可能涉及到额外的性能开销。
内存管理:
1. 普通数组: 需要手动管理内存。
2. array: 不需要手动管理内存,大小固定。
3. vector: 不需要手动管理内存,大小可变。
实验中也可以发现,vector通常根据你存的大小分配2^n的内存空间确保足够存储切留有空余
区别
大小是否固定:
1. 普通数组: 大小固定。
2. array: 大小固定,提供了更多的成员函数和类型安全。
3. vector: 大小可变。
成员函数和类型安全:
1. 普通数组: 基本数组,仅支持数组的基本操作。
2. array: 提供了成员函数,如 `at()` 和 `front()`,并在编译时进行类型安全检查。
3. vector: 提供了丰富的成员函数,但在运行时执行类型安全检查。
内存分配方式:
1. 普通数组: 在栈上分配内存。
2. array: 在栈上分配内存,大小固定。
3. vector: 在堆上分配内存,大小可变。
这里两种方式的区别是
-
在栈上分配内存:
- 适用于相对较小的、生命周期短暂的局部变量。
- 自动管理生命周期,不需要显式释放。
-
在堆上分配内存:
- 适用于较大的数据结构、需要长时间存活的对象、动态数据结构等。
- 需要程序员显式管理内存的生命周期,避免内存泄漏。
灵活性和性能:
1. 普通数组和array: 大小在编译时确定,具有较高的性能。
2. vector: 大小在运行时确定,具有更大的灵活性,但可能涉及性能开销。
迭代器与指针相关性,以及,区别
-
抽象级别:
- 指针: 是一种直接操作内存地址的低级别工具,常用于 C 语言等。
- 迭代器: 是 C++ 中的一种高级抽象,提供了更丰富的接口,适用于各种数据结构。
-
语法:
- 指针: 使用 运算符来解引用,可以直接对指针进行算术运算。
- 迭代器: 通常通过 来解引用,提供了更高层次的抽象,不一定支持指针的所有算术运算。
- 指针: 使用 运算符来解引用,可以直接对指针进行算术运算。
-
泛型性:
- 指针: 不具备泛型性,通常与具体的数据类型关联。
- 迭代器: 是泛型的,可以适用于不同类型的容器,提供了一致的接口。
-
容器访问:
- 指针: 不天然支持容器的直接访问。
- 迭代器: 是容器的一部分,可以通过容器提供的 和 等函数获取迭代器。
begin()
end()
这里给出ai写的一些代码方便理解复习
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
相互转换: 指针和迭代器之间可以进行相互转换: cpp Copy code int arr[] = {1, 2, 3, 4}; int* ptr = arr; std::vector<int> vec(arr, arr + 4); std::vector<int>::iterator it = vec.begin(); int* ptr_from_iterator = &(*it); 函数参数: 函数参数中可以接受指针或迭代器: cpp Copy code void processArray(int* begin, int* end) { // Process elements in the range [begin, end) } void processVector(std::vector<int>::iterator begin, std::vector<int>::iterator end) { // Process elements in the range [begin, end) } 遍历: 在循环中使用指针或迭代器进行遍历: cpp Copy code int arr[] = {1, 2, 3, 4}; for (int* ptr = arr; ptr < arr + 4; ++ptr) { // Process each element using the pointer } std::vector<int> vec = {1, 2, 3, 4}; for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) { // Process each element using the iterator }View Code
C风格字符串和string类型区别
C 风格字符串:
-
存储方式:
- C 风格字符串: 使用字符数组( 数组)来存储字符串。字符串的结束由 null 字符()标志。
- C++ 中的
std::string
: 使用动态分配的内存来存储字符串,而不需要显式地处理字符串的结束标志。
- C 风格字符串: 使用字符数组( 数组)来存储字符串。字符串的结束由 null 字符()标志。
-
内存管理:
- C 风格字符串: 需要手动分配和释放内存,开发者负责确保字符数组足够大,防止溢出。
- C++ 中的
string
: 内存管理由 类自动处理,无需手动分配或释放内存。 会动态调整大小,更加方便和安全。
-
长度信息:
- C 风格字符串: 长度信息通常由字符串结束的 null 字符来表示,需要使用 等函数来获取长度。
strlen
- C++ 中的
std::string
: 类型内部包含了字符串的长度信息,可以使用 或 成员函数获取长度。std::string
size()
length()
- C 风格字符串: 长度信息通常由字符串结束的 null 字符来表示,需要使用 等函数来获取长度。
-
字符串拼接:
- C 风格字符串: 需要使用 等函数进行字符串拼接。
strcat
- C++ 中的
std::string
: 可以直接使用 运算符或 成员函数来进行字符串拼接。+
append
- C 风格字符串: 需要使用 等函数进行字符串拼接。
-
字符串操作:
- C 风格字符串: 需要使用一系列函数如 、、 等进行字符串操作。
strcmp
strcpy
strncpy
- C++ 中的
std::string
: 提供了丰富的成员函数,如 、、、 等,方便进行各种字符串操作。find
substr
erase
replace
- C 风格字符串: 需要使用一系列函数如 、、 等进行字符串操作。
-
编译时类型:
- C 风格字符串: 字符数组是原始的 C 数据类型,不具备面向对象的特性。
- C++ 中的
std::string
: 是一个类,具有面向对象的封装和功能。
总体而言,C++ 中的 提供了更加安全和方便的字符串处理方式,免去了手动内存管理和数组越界等问题。
实验任务五![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string> #pragma once using namespace std; class TextCoder { private: string text; void encoder(); void decoder(); public: TextCoder(const string &Text); string get_ciphertext(); string get_deciphertext(); }; TextCoder::TextCoder(const string &Text) : text{Text} {} void TextCoder::encoder() { for (char &ch : text) { if (isalpha(ch))//判断是否是字符 { char base = islower(ch) ? 'a' : 'A'; ch = (ch - base + 7) % 26 + base; } } } void TextCoder::decoder() { for (char &ch : text) { if (isalpha(ch)) { char base = isupper(ch)?'A':'a'; ch = (ch - base + 26 - 7) % 26 + base; } } } string TextCoder::get_ciphertext() { encoder(); return text; } string TextCoder::get_deciphertext() { decoder(); return text; }View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "textcoder.hpp" #include <iostream> #include <string> void test() { using namespace std; string text, encoded_text, decoded_text; cout << "输入英文文本: "; while (getline(cin, text)) { encoded_text = TextCoder(text).get_ciphertext(); // 这里使用的是临时无名对象 cout << "加密后英文文本:\t" << encoded_text << endl; decoded_text = TextCoder(encoded_text).get_deciphertext(); // 这里使用的是临时无名对象 cout << "解密后英文文本:\t" << decoded_text << endl; cout << "\n输入英文文本: "; } } int main() { test(); }View Code
实验任务六
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <vector> #include <string> using namespace std; class Info { private: string nickname; string contact; string city; int n; public: Info(const string &nickname, const string &contact, const string &city, int n) : nickname(nickname), contact(contact), city(city), n(n) {} void output() const { cout << "昵称: " << nickname << endl; cout << "联系方式: " << contact << endl; cout << "所在城市: " << city << endl; cout << "预定人数: " << n << endl<<endl; } }; int main() { const int limitsum = 100;//const常量安全性 vector<Info> audience_info_list; cout << "录入信息:" << endl << endl; cout << "昵称 联系方式(邮箱/手机号) 所在城市 预约参加人数" << endl; int totalNumber = 0; while (1) { string nickname, contact, city; int n; if (!(cin >> nickname >> contact >> city >> n)) { break; //ctrl+z退出循环 } if (n <= 0) { cout << "预定参加人数必须大于0,请重新输入。\n"; continue; } if (n > limitsum) { char choice; cout << "对不起,只剩" << limitsum - totalNumber << "个名额。" << endl; cout << "1.输入 u,更新(update)预定信息" << endl; cout << "2.输入 q,退出预定" << endl; cout << "你的选择:"; cin >> choice; cout<<endl; if (choice == 'q') { break; } else if (choice == 'u') { cout << "请重新输入信息:\n"; continue; } } totalNumber += n; audience_info_list.emplace_back(nickname, contact, city, n); //.emplace_back()从尾部直接构造对象,而不需要用push_back把一个个对象构造出来再插入, //避免拷贝更加高效 } cout << "截止目前,一共有" << totalNumber << "位预约人数预定参加。预定听众信息如下:" << endl; for (const auto &info : audience_info_list) { info.output(); } //迭代器遍历输出 }View Code
前四个验证性实验体会
1.了解到了getline函数的使用方法和场景
2.了解到了清楚缓冲区的操作,优点和用处实验例子中给的是为了在cin之后回车键(换行符)会留在输入缓冲区中。接着,使用 getline(cin, s1);
读取一行字符串,如果输入缓冲区中有残留的换行符,getline
可能会立即读取到这个换行符,导致用户无法输入。也就是说,getline
可能在没有输入的情况下直接结束,因为它会读取到留在输入缓冲区中的换行符。
3.了解到了string类里面的许多个成员函数以及cctype内的函数如(isupper(),islower(),isalpha(),isdigit(),tolower(),toupper())
其中有一些注意事项比如,string和vector .end()返回位置是end后一位的迭代器,很多函数跟随着遵循相同的左闭右开的格式,比如.substr(),和遍历数组的时候迭代器循环同样也是。
4.了解了标准库中string和int和double相互转化的函数。
标签:std,string,c++,vector,实验,内存,数组,字符串,模板 From: https://www.cnblogs.com/xiaochengxiatian/p/17868489.html