C++基础容器 -- C的数组和字符串和C++的数组和字符串

这篇具有很好参考价值的文章主要介绍了C++基础容器 -- C的数组和字符串和C++的数组和字符串。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++基础容器

序列型容器

数组

  • 概念

    • 代表内存里一组连续的同类型存储区
    • 可以用来把多个存储区合并成一个整体
  • 数组声明

    • int arr[10];
    • 类型名称int表述数组里面所有元素的类型
    • 名称arr是数组的名称
    • 整数10表示数组里面的元素个数
    • 数组里元素个数不可以改变
  • 使用

    • 每个元素都有下标,通过下标可以直接访问任意一个元素
    • 下标从0开始到元素个数减一为止
    • 超过范围的下标不可以使用
    • 数组名称和下标一起可以表述数组里面的元素。arr[4]
  • 优点

    • 可以编写循环依次处理数组里面所有的元素
    • 循环变量可以依次代表所有有效下标
    • 下标标识了一个元素在数组的位置
off-by-one error(差一错误)
  • 考虑问题原则
    • 首先考虑最简单的情况的特例,然后将结果外推
    • 仔细计算边界
    • 一般使用左闭右开的区间来表示范围

C语言中设计数组下标的原则:从0开始使用非堆成区间;

  1. 让这个区间是非对称区间
  2. 让下界可以取到,让上界取不到

这样设计的好处:

  1. 取值范围:下界到上界
  2. 如果这个取值范围为空,上界值==下界值
  3. 即使取值范围为空,上界值永远不可能小于下界值
数组的增删改查
  1. 在尾部添加和删除时间复杂度为O(1);

  2. 不在尾部添加和删除时间复杂度为O(n);

  3. 数组遍历高效,时间复杂度为O(1);

  4. 数组查找的时间复杂度为O(n),取决于数组容量;

二维数组的访问
  1. 在一个小的时间窗内访问的变量地址越接近越好,这样执行速度快;
  2. 也就是说一般情况下需要将长循环放在内层,最短的循环放在外层以减少cpu跨切循环层的次数;

代码展示:

#include <iostream>
using namespace std;
#include <vector>
int main()
{
    // 数组访问
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 0, 0};
    // 推荐方式  ++ 写在前面避免拷贝构造 提速
    for (int index = 0; index < 10; ++index)
    	cout << a[index] << " ";
    cout << endl;
    // 不推荐方式
    for (int index = 0; index <= 9; ++index)
    	cout << a[index] << " ";
    // 数组的查找
    int b[] = { 1, 2, 3, 4 };
    int len = sizeof(b) / sizeof(b[0]);//得到数组容量
    for (int index = 0; index < len; ++index)
    {
    	if (b[index] == 5)
    	{
    		cout << index << endl;
    		return 0;
    	}
    }
    //二维数组的访问:
    int c[2][4] = { { 1, 2, 3, 4 },{ 5,6,7,8 } };
    for (int row = 0; row < 2; ++row)
    {
        for (int col = 0; col < 4; ++col)
        {
            cout << c[row][col] << " ";
        }
        cout << endl;
    }
    return 0;
}

动态数组 std::vector

vector是面向对象的动态数组 – 使用简单的数组是无法动态扩容插入元素,因为容量有限

vector插入操作
  • vec.insert(–vec.end(), 6);

  • vec.push_back(5);

vector删除操作
  • vec.pop_back();
  • vec.erase(vec.end() - 2);

示例代码:文章来源地址https://www.toymoban.com/news/detail-458600.html

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    // 创建动态数组vector
    vector<int> vec = { 1,2,3,4 };
    cout << "size is " << vec.size() << endl;
    cout << "capacity is " << vec.capacity() << endl;
    // 遍历所有元素
    for (int index = 0; index < vec.size(); ++index)
    {
        cout << vec[index] << endl;
    }
    // 在尾部插入一个元素5
    vec.push_back(5);
    cout << "size is " << vec.size() << endl;
    cout << "capacity is " << vec.capacity() << endl;
    // 遍历所有元素

    for (int index = 0; index < vec.size(); ++index)
    {
        cout << vec[index] << endl;
    }
    // 在中间插入一个元素6
    vec.insert(--vec.end(), 6);
    cout << "size is " << vec.size() << endl;
    cout << "capacity is " << vec.capacity() << endl;
    // 遍历所有元素
    for (int index = 0; index < vec.size(); ++index)
    {
        cout << vec[index] << endl;
    }
    // 在尾部移除一个元素
    vec.pop_back();
    cout << "size is " << vec.size() << endl;
    cout << "capacity is " << vec.capacity() << endl;
    // 遍历所有元素
    for (int index = 0; index < vec.size(); ++index)
    {
        cout << vec[index] << endl;
    }
    // 在任意位置移除一个元素
    vec.erase(vec.end() - 2);
    cout << "size is " << vec.size() << endl;
    cout << "capacity is " << vec.capacity() << endl;
    // 遍历所有元素
    for (int index = 0; index < vec.size(); ++index)
    {
        cout << vec[index] << endl;
    }
    return 0;
}

字符串和字符数组

  • 字符串变量

    • 字符串是以空字符{‘\0’}结束的字符数组
    • 空字符’\0’自动添加到字符串的内部表示中
    • 在声明字符串变量时,应该为这个空结束符预留一个额外的元素空间 char str[11] = {“helloworld”};
  • 字符串常量

    • 字符串常量是一对双引号括起来的字符序列
    • 字符串中每个字符作为一个数组元素存储 “helloworld”

ASCII码一览表,ASCII码对照表 (biancheng.net)

Unicode编码
  • 最初目的是把世界上的文字都映射到一套字符空间中

  • 为了表示Unicode字符集,有五种Unicode编码方式,这里说3中

    • utf-8 : 1byte 表示,可以兼容ascii
      • 存储效率高,变长,无字节序问题
    • utf-16
      • 特点是定长,有字节序的问题(不可作为外部编码)
    • utf-32
      • 特点是定长,有字节序问题(不可作为外部编码)
  • 编码错误的根本原因是在于编码方式和解码方式的不统一

windows文件可能有Bom 如果在其他平台可以去掉bom

字符串的指针表示方法
  • 指针表示方法 – char* pStrHelloWrold = “helloworld”;
字符串的常见操作
  • 字符串长度:strlen(s);

  • 字符串比较:strcmp(s1, s2);

  • 字符串拷贝:strcpy(s1, s2); 复制s2到s1s

  • 复制指定长度字符串:strncpy(s1, s2, n);

  • 字符串拼接:strcat(s1, s2);

  • 查找字符:strchr(s1, ch);

  • 查找字符串:strstr(s1, s2);

字符串操作的问题
  • C中原始字符串操作在安全性和效率存在一定的问题
    • 缓冲区溢出问题
    • strlen的效率可以提升:空间换时间
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
    // 定义一个数组
    char strHelloWorld[11] = { "helloworld" };     // 这个定义可以
    char* pStrHelloWrold = "helloworld";
    pStrHelloWrold = strHelloWorld;
    //strHelloWorld = pStrHelloWrold;               // 数组变量的值不允许改变
    // 字符0, '\0', '0'的区别
    char c1 = 0;
    char c2 = '\0';
    char c3 = '0';
    // 通过数组变量遍历修改数组中的元素值
    for (int index = 0; index <  strlen(strHelloWorld); ++index)
    {
        strHelloWorld[index] += 1;
        std::cout << strHelloWorld[index] << std::endl;
    }
    // 通过指针变量遍历修改数组中的元素值
    for (int index = 0; index < strlen(strHelloWorld); ++index)
    {
        pStrHelloWrold[index] += 1;
        std::cout << pStrHelloWrold[index] << std::endl;
    }
    cout << endl;  // 换行
    // 计算字符串长度
    cout << "字符串长度为: " << strlen(strHelloWorld) << endl;
    cout << "字符串占用空间为:  " << sizeof(strHelloWorld) << endl;
    return 0;
}
#include <string.h>                    //使用C库的头文件
#include <iostream>
using  namespace std;
const unsigned int MAX_LEN_NUM = 16;
const unsigned int STR_LEN_NUM = 7;
const unsigned int NUM_TO_COPY = 2;
int main()
{
	char strHelloWorld1[ ] = { "hello" }; 
	char strHelloWorld2[STR_LEN_NUM] = { "world1" };
	char strHelloWorld3[MAX_LEN_NUM] = {0};
	//strcpy(strHelloWorld3, strHelloWorld1);                                    // hello
	strcpy_s(strHelloWorld3, MAX_LEN_NUM, strHelloWorld1);
	//strncpy(strHelloWorld3, strHelloWorld2, NUM_TO_COPY);      // wollo
	strncpy_s(strHelloWorld3, MAX_LEN_NUM,  strHelloWorld2, NUM_TO_COPY);
	//strcat(strHelloWorld3, strHelloWorld2);                                    //  wolloworld1
	strcat_s(strHelloWorld3, MAX_LEN_NUM, strHelloWorld2);
	//unsigned int len = strlen(strHelloWorld3);
	unsigned int len = strnlen_s(strHelloWorld3, MAX_LEN_NUM);
	for (unsigned int index = 0; index < len; ++index)
	{
		cout << strHelloWorld3[index] << " ";
	}
	cout << endl;	
	// 小心缓冲区溢出
	//strcat(strHelloWorld2, "Welcome to C++");
	strcat_s(strHelloWorld2, STR_LEN_NUM, "Welcome to C++");
    return 0;
}

C++中的std::string

  • C++中提供了string类型专门表示字符串
  • 使用string可以更加安全方便的管理字符串

使用起来比原始的C风格的方法更安全和方便,对性能要求不是特别高的常见可以使用。

示例代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    // 字符串定义
    string s1;//定义空字符串
    string s2 = "helloworld";//定义并初始化
    string s3("helloworld");
    string s4 = string("helloworld");
    // 获取字符串长度
    cout << s1.length() << endl;
    cout << s1.size() << endl;
    cout << s1.capacity() << endl;
    //  字符串比较
    s1 = "hello", s2 = "world";
    cout << (s1 == s2) << endl;
    cout << (s1 != s2) << endl;
    //  转换成C风格的字符串
    const char *c_str1 = s1.c_str();
    cout << "The C-style string c_str1 is: " << c_str1 << endl;
    //  随机访问
    for (unsigned int index = 0; index < s1.length(); ++index)
    {
        cout << c_str1[index] << " ";
    }
    cout << endl;
    for (unsigned int index = 0; index < s1.length(); ++index)
    {
        cout << s1[index] << " ";
    }
    cout << endl;
    // 字符串拷贝
    s1 = "helloworld";
    s2 = s1;
    // 字符串连接
    s1 = "helllo", s2 = "world";
    s3 = s1 + s2;               //s3: helloworld
    s1 += s2;                    //s1: helloworld
    return 0;
}

到了这里,关于C++基础容器 -- C的数组和字符串和C++的数组和字符串的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串

    字符数组的定义方法与前面介绍的一维数组类似.例如, 字符数组的初始化可以采用以下方式. (1)对每个字符单独赋值进行初始化.例如, (2)对整个数组进行初始化.例如, 但工作中一般不用以上两种初始化方式,因为字符数组一般用来存取字符串.通常采用的初始化方式是

    2024年01月25日
    浏览(53)
  • 【编码狂想】LeetCode 字符串和数组篇:挑战算法精髓,深化程序设计基础

    ​ 🌈 个人主页: Sarapines Programmer  🔥 系列专栏: 本期文章收录在《C语言闯关笔记》,大家有兴趣可以浏览和关注,后面将会有更多精彩内容!  ⏰翰墨致赠:翩翩风华激彩虹,豪情壮志醉长空。 剑指星河舞红尘,梦驰烈马向未来。 ​ ​ 🎉欢迎大家关注🔍点赞👍收藏

    2024年02月04日
    浏览(44)
  • 【华为OD机考 统一考试机试C卷】字符串序列判定/最后一个有效字符( C++ Java JavaScript python C语言)

    2023年11月份,华为官方已经将 华为OD机考:OD统一考试(A卷 / B卷)切换到 OD统一考试(C卷)和 OD统一考试(D卷) 。 真题目录:华为OD机考机试 真题目录(C卷 + D卷 + B卷 + A卷) + 考点说明 专栏:2023华为OD机试( B卷+C卷+D卷)(C++JavaJSPy) 华为OD面试真题精选:华为OD面试真题精

    2024年02月05日
    浏览(48)
  • Js水几个基础知识点:数组的操作,字符串和数组之间的互转,持续补充,欢迎关注

    一、插入 / 删除元素: 我们就不从创建开始讲了,那个太基础了,js创建数组一般都直接let arr = […,…,…],有部分仁兄喜欢new Array(…, …, …),这样看起来可能高级点,结果是一样的哈。 这里我们直接来讨论插入元素: 1、在末尾插入 / 删除元素(push / pop,操作原数组)

    2024年02月09日
    浏览(50)
  • C++字符串题基础(进阶请看下一个文章)

    打印小写字母表 时间的差 数字和 国王的魔镜 简单解密 查字典码中最小的字符串 出现最多的小写字母 判断是否构成回文 移动个空格 删除* 字符串反码 看完动漫要几天?不会 时钟旋转不会 字符串加密

    2024年02月15日
    浏览(33)
  • 【力扣·每日一题】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)

    题目链接 给你一个字符串 word ,你可以向其中任何位置插入 “a”、“b” 或 “c” 任意次,返回使 word 有效 需要插入的最少字母数。 如果字符串可以由 “abc” 串联多次得到,则认为该字符串 有效 。 提示: 1 = w o r d . l e n g t h = 50 1 = word.length = 50 1 = w or d . l e n g t h = 50 w

    2024年01月16日
    浏览(42)
  • C++ 字符串完全指南:学习基础知识到掌握高级应用技巧

    字符串用于存储文本。 一个字符串变量包含由双引号括起来的一组字符: 示例 创建一个 string 类型的变量并为其赋值: 字符串连接可以使用 + 运算符来实现,生成一个新的字符串。 示例: 在上面的示例中,我们在 firstName 后面添加了一个空格,以便在输出时在 \\\"John\\\" 和 \\\"D

    2024年04月08日
    浏览(47)
  • mysql 解析json字符串、数组字符串、json数组字符串

    笔者使用mysql 5.7进行了一次json字符串的解析,因为一直在搞大数据相关的数据库、olap等,太久没有用mysql5.x的版本,一些函数已经不知道支不支持,我的同事建议我使用like、rlike模糊匹配的方式,身为数据人我不太喜欢用这种手段,因为他们比较低效。于是我想这里总结一下

    2024年02月16日
    浏览(48)
  • JS中字符串切割为数组/数组拼接为字符串

    (1)语法格式: 其中所选分隔符使用双引号(“”)或者单引号(‘’)括起来; 所生成的数组会存放于前面定义的数组变量中。 (2)样例: JS代码: 运行结果: (3)其他用法: ①当所选分隔符为空时,返回的数组即将每个字符分割出来: JS代码: 运行结果: ②分隔

    2024年02月12日
    浏览(46)
  • vue使用split()将字符串分割数组join()将数组转字符串reverse()将数组反转

    1.split() 将字符串切割成数组 输出如下 1.split()不传参数默认整个字符串作为数组的一个元素,返回包含原始字符串的数组 2.split(‘’)单引号不传参数默认将字符串拆分成一个个字符数组 如输入参数: const str = 123456789’ 拆分后:[‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’

    2023年04月08日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包