首页 > 编程语言 >实验四 现代c++ 标准库与类的模板

实验四 现代c++ 标准库与类的模板

时间:2023-11-30 22:55:06浏览次数:40  
标签:std string c++ vector 实验 内存 数组 字符串 模板

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: 大小在运行时确定,具有更大的灵活性,但可能涉及性能开销。

 

迭代器与指针相关性,以及,区别

 

  1. 抽象级别:

    • 指针: 是一种直接操作内存地址的低级别工具,常用于 C 语言等。
    • 迭代器: 是 C++ 中的一种高级抽象,提供了更丰富的接口,适用于各种数据结构。
  2. 语法:

    • 指针: 使用 运算符来解引用,可以直接对指针进行算术运算。
    • 迭代器: 通常通过 来解引用,提供了更高层次的抽象,不一定支持指针的所有算术运算。
  3. 泛型性:

    • 指针: 不具备泛型性,通常与具体的数据类型关联。
    • 迭代器: 是泛型的,可以适用于不同类型的容器,提供了一致的接口。
  4. 容器访问:

    • 指针: 不天然支持容器的直接访问。
    • 迭代器: 是容器的一部分,可以通过容器提供的 和 等函数获取迭代器。begin()end()

这里给出ai写的一些代码方便理解复习

 

相互转换:

指针和迭代器之间可以进行相互转换:
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 风格字符串:

  1. 存储方式:

    • C 风格字符串: 使用字符数组( 数组)来存储字符串。字符串的结束由 null 字符()标志。
    • C++ 中的 std::string: 使用动态分配的内存来存储字符串,而不需要显式地处理字符串的结束标志。
  2. 内存管理:

    • C 风格字符串: 需要手动分配和释放内存,开发者负责确保字符数组足够大,防止溢出。
    • C++ 中的 string: 内存管理由 类自动处理,无需手动分配或释放内存。 会动态调整大小,更加方便和安全。
  3. 长度信息:

    • C 风格字符串: 长度信息通常由字符串结束的 null 字符来表示,需要使用 等函数来获取长度。strlen
    • C++ 中的 std::string: 类型内部包含了字符串的长度信息,可以使用 或 成员函数获取长度。std::stringsize()length()
  4. 字符串拼接:

    • C 风格字符串: 需要使用 等函数进行字符串拼接。strcat
    • C++ 中的 std::string: 可以直接使用 运算符或 成员函数来进行字符串拼接。+append
  5. 字符串操作:

    • C 风格字符串: 需要使用一系列函数如 、、 等进行字符串操作。strcmpstrcpystrncpy
    • C++ 中的 std::string: 提供了丰富的成员函数,如 、、、 等,方便进行各种字符串操作。findsubstrerasereplace
  6. 编译时类型:

    • C 风格字符串: 字符数组是原始的 C 数据类型,不具备面向对象的特性。
    • C++ 中的 std::string: 是一个类,具有面向对象的封装和功能。

总体而言,C++ 中的 提供了更加安全和方便的字符串处理方式,免去了手动内存管理和数组越界等问题。

    实验任务五
#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
#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

 实验任务六

 

#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

相关文章

  • C++ 泛型编程之可变参数包
    C++泛型编程之可变模板参数·variadictemplates可以表示0到任意个数、任意类型的参数1.可变模板参数的展开:template<typename...Args> //可以将参数包展开一个个独立的参数voidfunc(Args...args); //声明一个参数包Args...args这个参数包可以包括0到任意个模板参数......
  • 实验4
    #include<iostream>#include<string>usingstd::string;classTextCoder{private:stringtext;voidencoder();voiddecoder();public:TextCoder(string&str);TextCoder(constTextCoder&......
  • C++20语言核心特性的变化
    usingforEnumerationValues  对比一下C++20前后的区别:enumclassState{open,progress,done=9};//BeforeC++20voidprint(States){switch(s){caseState::open:std::cout<<"open\n";brea......
  • 实验4 现代C++标准库与类模板
    实验任务5task5.cpp#include"Textcoder.hpp"#include<iostream>#include<string>voidtest(){ usingnamespacestd; stringtext,encoded_text,decoded_text; cout<<"输入英文文本:"; while(getline(cin,text)) { encoded_t......
  • 实验四
    实验任务5实验代码:textcoder.hpp#pragmaonce#include<iostream>#include<vector>#include<array>#include<string>usingnamespacestd;classTextCoder{private:stringtext;voidencoder(){for(autoi=......
  • 实验4 现代C++标准库与类模板
    四、实验内容1.实验任务1//在C++中定义和使用类模板task1_1.cpp#include<iostream>usingnamespacestd;//类A的定义classA{public:A(intx0,inty0):x{x0},y{y0}{}voidshow()const{cout<<x<<","<<y<<endl;}p......
  • 实验4 现代C++标准库与类模板
    实验任务1task1task1_1.cpp#include<iostream>usingstd::cout;usingstd::endl;classA{public:A(intx0,inty0):x{x0},y{y0}{}voidshow()const{cout<<x<<","<<y<<endl;}private:in......
  • 第三方实验室LIMS管理系统源码
    LIMS实验室信息管理系统源码LIMS系统的功能根据实验室的规模和任务而有所不同,其系统主要功能包括:系统维护、基础数据编码管理,样品管理、数据管理、报告管理、报表打印、实验材料管理、设备管理等。它可以取代传统的手工管理模式而给检测实验室带来巨大的变化,提高检测实验室的整体......
  • SSL——ASA防火墙——Cisco实验(详解)
    SSLVPN一、理论部分定义:SSLVPN,操作在OSI模型的会话层,可以使用户通过浏览器对VPN进行连接,但是没有隧道。使用https加密的范式进行数据传输,跨平台性强,只要终端设备有浏览器,能够上网,就可以进行VPN连接,并访问资源。扩展:可以通过DNS进行访问,或者使用花生壳注册免费域名进行访问ssl(......
  • C/C++ 实现FTP文件上传下载
    FTP(文件传输协议)是一种用于在网络上传输文件的标准协议。它属于因特网标准化的协议族之一,为文件的上传、下载和文件管理提供了一种标准化的方法,在Windows系统中操作FTP上传下载可以使用WinINet库,WinINet(WindowsInternet)库是Windows操作系统中的一个网络API库,用于访问Interne......