C++基础(5) - 复合类型(上)

news2024/12/22 23:02:05

文章目录

  • 数组
    • 1、什么是数组
    • 2、数组的声明
    • 3、数组的初始化
    • 4、数组的访问
    • 5、二维数组
    • 6、`memset` —— 给数组中每一个元素赋同样的值
  • 字符串(字符数组)
    • 1、`string.h` 头文件
      • 1.1 `strlen()`
      • 1.2 `strcmp()`
      • 1.3 `strcpy()`
      • 1.4 `strcat()`
  • string 类简介
    • 1、C++11 字符串初始化
    • 2、赋值、拼接和附加
    • 3、`string` 头文件
      • 3.1 `string` 中内容的访问
      • 3.2 `string` 的比较
      • 3.3 `length()/size()`
      • 3.4 `insert()`
      • 3.5 `erase()`
      • 3.6 `clear()`
      • 3.7 `substr()`
      • 3.8 `string::npos`
      • 3.9 `find()`
      • 3.10 `replace()`
  • 结构体
    • 1、结构体的定义和使用
    • 2、结构体变量的初始化
    • 3、结构体数组
  • 共用体
    • 1、什么是共用体
    • 2、共用体的用途
  • 枚举
    • 1、枚举的定义
    • 2、枚举的使用
    • 3、设置枚举量的值
    • 4、枚举的取值范围

数组

1、什么是数组

数组是一种数据格式,能够存储多个同类型的值。

数组的特点:

  1. 数组中的元素按线性方式排列,可以通过编号来访问数组中的每个元素;
  2. 每个值都存储在一个独立的数组元素中,计算机在内存中依次存储数组的各个元素;

 

2、数组的声明

要创建数组,可使用声明语句。数组声明应指出以下三点:

  1. 存储在每个元素中的值的类型;
  2. 数组名;
  3. 数组中的元素个数;

格式为:数据类型 数组名[数组大小];

注意:数组大小必须是整数常量,不可以是变量。

 

3、数组的初始化

  • C++ 允许在声明语句中初始化数组元素,只需提供一个用逗号分隔的值列表(初始化列表),并将它们用花括号括起来,可省略等号(=);

    int arr[4] = {3, 6, 8, 10};
    int arr[4] {3, 6, 8, 10};	// C++11 新增
    
  • 只有在定义数组时才能使用初始化,此后就不能使用了,也不能将一个数组赋给另一个数组;

    int arr[4] = {3, 6, 8, 10};	// 正确
    
    int hand[4];
    hand[4] = {3, 6, 8, 10};	// 错误
    hand = arr;	// 错误
    
  • 初始化数组时,提供的值可以少于数组的元素数目。如果对数组的一部分进行初始化,则编译器将把其他元素设置成0。若想初始化数组为0,则只需要显式将第一个元素初始化为0即可;

    int arr[4] = {3, 6};	// 第1个元素3,第2个元素6,其他元素为0
    int arr[4] = {0};	// 所有元素初始化为0
    int arr[4] = {};	// C++11新增,所有元素初始化为0
    
  • 如果初始化数组时方括号内([])为空,C++ 编译器将计算元素个数;

    int arr[] = {3, 6, 8, 10};	// 编译器会自动识别元素个数为4
    
  • 列表初始化禁止缩窄转换;

    long plifs[] = {25, 92, 3.0};	// 错误,浮点数转换为整型是缩窄操作
    char slifs[4] = {'h', 'i', 1122011, '\0'};	// 错误,1122011超过了char变量的取值范围
    char tlifs[4] = {'h', 'i', 112, '\0'};	// 正确,虽然112是一个int值,但在char类型的取值范围
    

 

4、数组的访问

int arr[indx];

其中 indx 为数组的索引(下标),范围为 0 ~ length-1;数组长度 length = sizeof(arr) / sizeof(int)。这里的 sizeof 之前的文章介绍过,它返回变量或数据类型的字节个数。因为 arrint 型数组,里面每一个元素都是 int 类型,所以 sizeof(arr) 表示所有元素的字节数,sizeof(int) 表示一个元素的字节数,两者之商就是元素的个数。

注意:如果数组大小较大(大概 1 0 6 10^6 106 级别),则需要将其定义在主函数外面,否则会使程序异常退出。因为函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大。

 

5、二维数组

  1. 声明二维数组

数据类型 数组名[m][n];

m 表示二维数组有多少个一维数组,n 表示每个一维数组的元素个数。

二维数组

  1. 二维数组初始化

    创建二维数组时,可以初始化其所有元素,二维数组初始化是建立在一维数组初始化技术的基础之上:提供由逗号分隔的用花括号括起的值列表。

    int scores[3][4] = {
        {},
        {},
        {}
    };
    

    注意:二维数组的行数个数必须全部用大括号指定,不能省略,否则编译出错!【例如上面的 scores 数组,我省略三个大括号中的一个是不行的】

     

6、memset —— 给数组中每一个元素赋同样的值

给数组中每一个元素赋相同的值有两种方法:memsetfill

memset 函数的格式为:memset(数组名, 值, sizeof(数组名));。需要引入 string.h 头文件。

只建议初学者为数组赋 0-1。因为 memset 使用的是按字节赋值,并不是按元素赋值,很容易出错。如果想按元素赋值,可以使用 fill 函数,此时需要引入 algorithm 头文件。

 
 

字符串(字符数组)

  • 字符串是存储在内存连续字节中的一系列字符,又可以称为字符数组;

  • C++ 处理字符串有两种方式,一种是 C 语言风格,另一种是基于 string 类;

  • 可以将字符串存储在 char 数组中,每个字符都位于自己的数组元素中;

  • C 语言风格的字符串是以空字符结尾(空字符被写作 \0,ASCII 码为 0),用来标记字符串的结尾。处理字符串的函数都是根据空字符的位置,而不是数组长度来进行处理;

    存储字符串 “Kitty” 的情况为:char name[6] = {'K', 'i', 't', 't', 'y', '\0'};

  • 字符数组初始化为字符串,可以使用双引号("")将字符串内容括起来【仅限于初始化,程序其他位置不允许这样直接赋值整个字符串】;

    char name[16] = "Hello Kitty";
    char name[] = "Kitty";
    
  • 注意字符常量和字符串常量的区别;

    'S' 是字符常量,"S" 是字符串常量,存储的是 ['S', '\0']

 

1、string.h 头文件

1.1 strlen()

strlen(字符数组):获得字符数组中第一个 \0 之前的字符个数。

1.2 strcmp()

strcmp(字符数组1, 字符数组2):返回两个字符串大小的比较结果,比较规则是字典序。

  1. 字符数组1 < 字符数组2:返回一个负整数;
  2. 字符数组1 < 字符数组2:返回一个正整数;
  3. 字符数组1 < 字符数组2:返回0;

1.3 strcpy()

strcpy(字符数组1, 字符数组2):把字符数组2复制到字符数组1,覆盖复制,这里的复制还包括结束符 \0

1.4 strcat()

strcat(字符数组1, 字符数组2):把字符数组2拼接到字符数组1后面,两者之间的结束符会被覆盖。

 
 

string 类简介

除了使用字符数组之外,还可以使用 string 来存储字符串,而且 string 使用起来会比字符数组要简单。

要使用 string,必须包含头文件 string

 

1、C++11 字符串初始化

C++11 允许将列表初始化用于 C 风格字符串和 string 对象:

char first_data[] = {"Hello World"};
char second_data[] = {"The Elegant Plate"};
string third_data = {"Hello World"};
string third_data {"Hello World"};

string str = {'h', 'e', 'l', 'l', 'o'};
string str = "hello world";

 

2、赋值、拼接和附加

  • 不能将一个数组直接赋给另一个数组,但是可以将一个 string 对象直接赋给另一个 string 对象;

    char ch[20] = "hello";
    string str = "world";
    
    char ch1[20];
    ch1 = ch;	// 错误!!
    string str1;
    str1 = str;	// 正确!!
    
  • string 简化了合并操作,可以使用运算符 + 来将两个 string 对象合并起来,还可以使用 += 运算符。

    string str2 = str + str2;
    string str += str2;
    

 

3、string 头文件

虽然 string 类也可以使用 C 中的头文件 string.h,但是 C++ 为了更好地使用 string,也提供了自己的 string 操作函数。

3.1 string 中内容的访问

  1. 直接像数组那样通过下标访问 string;

    string str = "abc";
    cout << str[0] << endl;	// 要读入或输出整个字符串,只能使用 cin 和 cout
    
    // 还可以用 c_str() 将 string 类型转换为字符数组,然后用 printf 输出
    printf("%s\n", str.c_str());
    
  2. 通过迭代器访问;

    string str = "abc";
    string::iterator it = str.begin();
    // 上一句为了简便,还可以写成:
    auto it = str.begin();
    

3.2 string 的比较

两个 string 类型可以直接使用 关系运算符 进行比较,比较规则是字典序!

3.3 length()/size()

str.length()/str.size():返回字符串 str 的长度,即存放的字符数;

3.4 insert()

  1. str.insert(pos, string):在字符串 strpos 号位置插入字符串 string
  2. str.insert(it, it1, it2)it 为原字符串欲插入的位置,it1it2 为待插字符串的首尾迭代器,用来表示子串 [it1, it2) 将被插入到 it 的位置上;

3.5 erase()

  1. str.erase(it):删除迭代器 it 所在位置的元素;
  2. str.erase(begin, end):删除一个区间 [begin, end) 内的所有元素;
  3. str.erase(pos, length)pos 为开始删除的其实位置,length 为删除的字符个数;

3.6 clear()

str.clear():清空 string 中的数据;

3.7 substr()

str.substr(pos, length):返回从 pos 号位开始、长度为 length 的子串;

3.8 string::npos

一个常数,其本身的值为 -1,但由于是 unsigned_int 类型,因此实际上也可以被认为是 unsigned_int 类型的最大值。string::npos 用来作为 find 函数失配时的返回值。

3.9 find()

  1. str.find(str1):当 str1str 的子串时,返回其在 str 中第一次出现的位置;如果不是,则返回 string::npos
  2. str.find(str1, pos):从 strpos 号位开始匹配 str1,返回值与上相同;

3.10 replace()

  1. str.replace(pos, length, str1):把 strpos 号位开始、长度为 length 的子串转换为 str1
  2. str.replace(it1, it2, str1):把 str 的迭代器 [it1, it2) 范围的子串替换为 str1

 
 

结构体

结构体是由一批不同类型数据组合而成的一种新的数据类型,组成结构体数据的每个数据称为结构体的“成员”(域、元素),通常用来表示类型不同但是又相关的若干数据。

 

1、结构体的定义和使用

struct 结构体名字 {
    char name[20];	// 一些基本的数据结构或者自定的数据类型
    int age;
    ...
}[结构体变量1, 结构体变量2, ...];	// [] 中的是可选项

结构体里面可以定义除了自己之外的任何数据类型,因为定义自己本身会引起循环定义的问题,但是可以定义自身类型的指针变量。

  • 假设结构体名字为 student,依次创建结构体类型的变量:

    struct student stu, *stup;	// stu 为结构体变量,stup 为结构体指针变量,两者访问变量方式不同
    student stu;
    
  • 访问结构体类型变量成员:

    cout << stu.name;	// 普通变量的访问方式
    cout << stup->name;	// 指针变量的访问方式
    

 

2、结构体变量的初始化

使用逗号分隔值列表,并将这些值用花括号括起来,值之间用逗号分开:

student stu = {"cat", 19};
student stu {"dog", 18};
student stu {};

 

3、结构体数组

  • 可以创建元素为结构体的数组,方法和创建基本类型数组完全相同:

    student stus[20];
    cin >> stus[0].name;
    cout << stus[19].age << endl;
    
  • 结构体数组初始化:

    student stus[2] = {
        {"cat", 19},
        {"dog", 18}
    };
    

 
 

共用体

1、什么是共用体

共用体(联合体)是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。例如一个共用体中定义了 intdouble 类型的变量,存储了 int 型数据之后,再存储 double 型数据,此时 int 型数据会丢失。

union one4two
    {
        int id_int;
        long id_long;
    };

    one4two pail;
    pail.id_int = 3;
    cout << pail.id_int << endl;	// 3
    pail.id_long = 3000;
    cout << pail.id_long << endl;	// 3000
    cout << pail.id_int << endl;	// 3000

共用体的句法与结构体相似,但是含义不同,共用体的长度为其最大成员的长度:

union one4all
{
    char char_val;
    short short_val;
    int int_val;	// one4all 的长度就是 int 类型的长度
};

 

2、共用体的用途

共用体的用途之一是,当数据项使用两种或更多种格式(但不会同时使用)时,可节省空间。

假设管理一个小商品目录,其中有一些商品的ID为整数,而另外一些的ID为字符串:

struct widget
{
    char brand[20];
    int type;
    union id
    {
        long id_num;
        char id_char[20];
    } id_val;
};
...
widget prize;
...
if (prize.type == 1) {
    cin >> prize.id_val.id_num;
} else {
    cin << prize.id_val.id_char;
}

匿名共用体(anonymous union)没有名称,其成员将成为位于相同地址处的变量。显然,每次只有一个成员是当前的成员:

struct widget
{
    char brand[20];
    int type;
    union
    {
        long id_num;
        char id_char[20];
    };
};
...
widget prize;
...
if (prize.type == 1) {
    cin >> prize.id_num;
} else {
    cin >> prize.id_char;
}

由于共用体是匿名的,因此 id_numid_char 被视为 prize 的两个成员,它们的地址相同,所以不需要用中间标识符 id_val 。程序员负责确定当前哪个成员是活动的。

共用体常用于(但并非只能用于)节省内存。

 
 

枚举

前文提到过符号常量,使用 const#define 进行定义。C++ 的枚举类型 enum 提供了另一种创建符号常量的方式,可以代替 const,它还允许定义新类型。

 

1、枚举的定义

enum 枚举名 {枚举量1, 枚举量2, ...};

// 例子如下:red为0,依此类推,数值加1。即 orange 为1,yellow 为2,...
enum colors {red, orange, yellow, green, blue, purple};

 

2、枚举的使用

// 使用枚举名声明该类型的变量
colors band;

// 只能将定义枚举时使用的枚举量赋值给这种枚举的变量
band = red;
// band = 5;	// 错误!!

// 可以通过强制类型转换,将有效的 int 值转换成枚举量
band = colors(4);

// 枚举量是整型,可被提升为 int 类型,但 int 类型不能自动转换为枚举类型
int col = blue;
col = 3 + red;

 

3、设置枚举量的值

  • 可以使用赋值运算符来显式地设置枚举量地值,指定地值必须是整数:

    enum bits{one = 1, two = 2, four = 4, eight = 8};
    
  • 也可以只显式地定义其中一些枚举量的值:

    enum bigstep{first, second = 100, third};	// first 为0,third 为101
    

    first 默认情况下为0,后面没有初始化的枚举量的值比其前面的枚举量大1,third 的值为 101

  • 可以创建多个值相同的枚举量:

    enum{zero, null = 0, one, numero_uno = 1};	// 这里 zero 也为0,one 也为1
    

     

4、枚举的取值范围

  • 每个枚举都有取值范围,通过强制类型转换,可以将取值范围中的任何整数赋值给枚举变量,即使这个值不是枚举值:

    enum bits{one = 1, two = 2, four = 4, eight = 8};
    bits myflag = bits(6);
    
  • 枚举取值范围:

    • 上限:寻找第一个大于枚举量最大值的2的幂次方,上限就是这个值减1;

      例如最大枚举量为 101,第一个大于它的是 2 7 = 128 2^7 = 128 27=128,所以上限就是 128 − 1 = 127 128 - 1 = 127 1281=127

    • 下限:枚举量最小值为0,则下限为0;否则寻找第一个小于它的2的幂次方,加上1;

      例如最小枚举量为 -6,第一小于它的是 − 2 3 = − 8 -2^3 = -8 23=8,因此下限为 − 8 + 1 = − 7 -8 + 1 = -7 8+1=7

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/340192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第二十六天 | 39. 组合总和,40.组合总和II,131.分割回文串

一、参考资料组合总和题目链接/文章讲解&#xff1a;https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1KT4y1M7HJ 组合总和II题目链接/文章讲解&#xff1a;https://programmercarl.com/004…

STL——stack

一、stack介绍和使用 1.stack文档介绍 &#xff08;1&#xff09;stack是一种容器适配器&#xff0c;专门用于具有后进先出操作的上下文环境中&#xff0c;其只能从容器的一端进行元素的插入与删除&#xff0c;以及提取操作。 &#xff08;2&#xff09;stack是作为容器适配…

Python如何安装模块,python模块安装失败的原因以及解决办法

前言 今天来给刚开始学习python的朋友讲解一下 如何安装python模块, python模块安装失败的原因以及解决办法 很多朋友拿到代码之后&#xff0c;就开始复制粘贴 --> 然后右键进行运行 结果就是报错说 没有这个模块 得安装啥的 Python模块安装 一. 打开命令提示符 win …

分布式项目-品牌管理(5、6)

【今日成果】&#xff1a; //使用阿里云OSS服务&#xff1a; //使用v-if如果地址没有就不显示 &#xff0c; 如果地址错误图片就显示不出来&#xff1b; 【快速回顾】&#xff1a; 任何数据的删除都不要使用物理上的删除&#xff0c;应当使用逻辑上的删除&#xff01;&…

2023,AI 技能学起来

这段时间&#xff0c;ChatGPT 算是火出圈了。不仅朋友圈转发各种 ChatGPT 的文章&#xff0c;连我夫人这种从来不关注科技新闻的人也问我 ChatGPT 是怎么回事。其实我算是比较早知道并关注 ChatGPT 的&#xff0c;去年 12 月份还写了一篇文章 AI 也会写代码了&#xff0c;但我并…

一文讲清chatGPT的发展历程、能力来源和复现它的关键之处

1. ChatGPT是什么 chatGPT是什么&#xff1f;这可能是最近被问的最多的一个。 大家第一反应这应该是GPT系列的一个最新模型&#xff0c;普通大众可能更愿意把它看做是一个人工智能。实际上&#xff0c;它其实就是一个基于大规模语言模型的对话系统产品。官网对它定义十分的明…

前端——周总结系列四

1 JS变量与常量 概述 变量&#xff1a;在后续编码过程中会被重新赋值&#xff0c;是不断变化的。常量&#xff1a;固定不变的数据&#xff0c;日常生活比如性别男&#xff0c;代码层面是在编码过程中不会变化的固定数据。 命名规则 变量 可以包含数字&#xff0c;字母&…

四家文档管理系统中披露的未修补安全漏洞

四家供应商 LogicalDOC、Mayan、ONLYOFFICE 和 OpenKM 的开源和免费增值文档管理系统 (DMS) 产品中披露了多个未修补的安全漏洞。 佛山市东联科技有限公司网络安全研究人员表示&#xff0c;这八个漏洞提供了一种机制&#xff0c;“攻击者可以通过该机制说服人类操作员在平台上…

背包问题代码合集(C/C++)

目录 1 01背包问题 2 完全背包问题 3 多重背包问题 4 分组背包问题 1 01背包问题 有N件物品和一个容量是V的背包。每件物品只能使用一次。 第 物品的体积是&#xff0c;价值是。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;…

找数字(字符串思维题)

刚开始自己的思路&#xff1a;用dfs暴搜&#xff0c;没考虑时间复杂度&#xff08;准确来说当时不知道该题的时间复杂度该怎么算&#xff09;&#xff0c;如果用暴搜写的话是&#xff08;10的100次方&#xff09; 正确的思路&#xff1a;最小值&#xff1a;定义一个长度为m的空…

(C语言)指针进阶

问&#xff1a;1. ( )&#xff0c;[ ]&#xff0c;->&#xff0c;&#xff0c;--&#xff0c;. &#xff0c;&#xff0a;的操作符优先级是怎么样的&#xff1f;2. Solve the problems&#xff1a;只有一个常量字符串与一个字符指针&#xff0c;该怎么打印常量字符串所有内容…

AI_Papers:第一期

2023.02.06—2023.02.12 文摘词云 Top Papers Subjects: cs.CL 1.Multimodal Chain-of-Thought Reasoning in Language Models 标题&#xff1a;语言模型中的多模式思维链推理 作者&#xff1a;Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, Alex Sm…

生产Nginx现大量TIME-WAIT,连接耗尽,该如何处理?

背景说明&#xff1a; 在尼恩读者50交流群中&#xff0c;是不是有小伙伴问&#xff1a; 尼恩&#xff0c;生产环境 Nginx 后端服务大量 TIME-WAIT &#xff0c; 该怎么办&#xff1f; 除了Nginx进程之外&#xff0c;还有其他的后端服务如&#xff1a; 尼恩&#xff0c;生产环境…

【设计模式-11】责任链模式

认识设计模式&#xff08;十一&#xff09;---责任链模式【一】责任链模式【二】介绍&#xff08;1&#xff09;意图&#xff08;2&#xff09;主要解决&#xff08;3&#xff09;何时使用&#xff08;4&#xff09;如何解决&#xff08;5&#xff09;关键代码&#xff08;6&am…

面对日益强大的AIGC,内容创作者们该何去何从?

面对日益强大的AIGC&#xff0c;内容创作者们该何去何从&#xff1f; 忽如一夜东风来&#xff0c;AIGC红全球。好似在一夜之间&#xff0c;AIGC就突然走红了&#xff0c;朋友圈、各大平台、各大社群&#xff0c;对于它的讨论话题也是越来越多。AIGC也成为了继NFT、元宇宙、Web…

pandas——groupby操作

Pandas——groupby操作 文章目录Pandas——groupby操作一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤一、实验目的 熟练掌握pandas中的groupby操作 二、实验原理 groupby(byNone, axis0, levelNone, as_indexTrue, sortTrue, group_keysTrue, squeezeFalse&…

STM32单片机GSM短信自动存取快递柜

实践制作DIY- GC0104-自动存取快递柜 一、功能说明&#xff1a; 基于STM32单片机设计-自动存取快递柜 二、功能介绍&#xff1a; STM32F103C系列最小系统板0.96寸OLED显示器DY-SV17F串口语音播报模块4*4矩阵键盘GSM短信模块4路舵机&#xff08;模拟4个柜子&#xff09; ***…

动规规划-完全背包问题

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 首先回顾一下0-1背包问题&#xff0c;它和…

【寒假day4】leetcode刷题

&#x1f308;一、选择题❤1.下列哪一个是析构函数的特征&#xff08; &#xff09;。A: 析构函数定义只能在类体内 B: 一个类中只能定义一个析构函数 C: 析构函数名与类名相同 D: 析构函数可以有一个或多个参数答案&#xff1a;B答案解析&#xff1a;析构函数是构造函…

练 习

1.判断三个中最重的//依次输入相应的人的体重double people1, people2, people3;cout << "请输入第一个人体重" << endl;cin >> people1;cout << "请输入第二个人体重" << endl;cin >> people2;cout << "请…