第四章——复合类型

news2024/9/23 15:31:46

数组

数组(array)是一种数据格式,能够存储多个同类型的值。例如30个int类型的值,12个float类型的值。每个值都存储在一个独立的数组元素中,计算机在内存中依次存储数组的各个元素。

创建数组时应指出以下三点:

  • 存储在每个元素中的值的类型
  • 数组名
  • 数组中的元素数

在C++中,可以通过修改简单变量的声明,添加中括号(其中包含元素数目)来完成数组声明。如

int months[12];

上面一条语句的意思是,创建一个名为months的数组,该数组有12个元素,每个元素都可以存储一个int类型的值

声明数组的通用格式是:

typeName arrayName[arraySize];

 arraySize指定元素数目,它必须是整型常数(10、23)或const值,也可以是常量表达式,即其值在编译时都是已知的,不能是变量

数组可以单独访问数组元素

 方法是使用下标或索引来对元素进行编号。C++数组从0开始编号,用带索引的方括号来表示指定元素,例如months[0]表示months数组的第一个元素,months[11]表示数组的最后一个元素

数组的初始化

只有在定义数组的时候才能使用初始化,此后就不能使用了,也不能将一个数组赋给另一个数组

int hards[4] = {3,4,5,6};    //ok
int hands[4];                //ok
hands[4] = {5,6,7,8};        //error
hands = hards;               //error

 初始化数组时,提供的值可以少于数组的元素数目,如果只对数组的一部分进行初始化,则编译器把其他元素设置为0。

这里需要注意的是,C++11允许使用大括号的初始化方法(列表初始化)来进行数组的初始化。但是列表初始化禁止缩窄转换

 long lifts[]={24,56,3.0};

上面这条语句不能通过编译,因为将浮点数转换为整型是缩窄操作。

字符串

字符串是存储在内存的连续字节中的一系列字符。C++处理字符串的方式有两种。第一种来自C语言,被称为C-风格字符串,另外一种是基于string类库的方法

存储在连续字节中的一系列字符意味着可以将字符串存储在char数组中,其中每个字符都位于自己的数组元素中。

C-风格字符串具有一种特殊的性质:以空字符结尾,空字符被写作\0,其ASCII码为0,用来标记字符串的结尾

	char dog[8] = { 'b','e','a','u','x',' ','I','I' };//not a string
	char cat[8] = { 'f','a','t','e','s','s','a','\0' };// a string

 这两个数组都是char数组,但只有第二个数组是字符串

上述初始化方法需要使用大量单引号,还需要加上空字符,很繁杂。有一种将字符数组初始化为字符串的方法——只使用一个引号括起来的字符串即可,这种字符串被称为字符串常量或字符串字面值

char brid[11]="Mr. Cheeps";

用引号括起来的字符串隐式地包括结尾的空字符。

 应确保数组足够大,能够存储字符串中所有字符——包括空字符

拼接字符串常量

C++允许拼接字符串字面值,即将两个用引号括起来的字符串合并为一个。(任何两个由空白、制表符、换行符)分隔的字符串常量都将自动拼接成一个

strlen()只计算可见的字符。sizeof运算符指出整个数组的长度;

在数组中使用字符串

要将字符串存储在数组中,最常用的方法有两种——将数组转化为字符串常量、将键盘或文件输入读入到数组中。

字符串输入

cin使用空白(空格、制表符和换行符)来确定字符串的结束位置,这意味着cin在获取字符数组输入时只读入一个单词。

        每次读取一行字符串输入

        每次读取一个单词通常不是最好的选择,例如要求程序完整保存输入的New York,而不是只保存了New,需要采取另一种字符串读取方式

  • 面向行的输入:getline() 

getline()函数读取整行,它通过使用回车键输入的换行符来确定结尾。要调用这种方法,可以使用

cin.getline(name,number);

 该函数有两个参数,第一个参数是用来存储输入行的数组的名称,第二个参数是要读取的字符数

(如果这个参数为20,则它最多能读取19个字符,剩下的一个空间用于自动存储结尾的空字符)

getline()成员函数在读取指定数目的字符或遇到换行符时停止读取

getline()函数每次读取一行,通过换行符来确定行尾,但不保存换行符,相反它在存储字符串时,用空字符串来替换换行符 

  •  面向行的输入:get()

 istream类有另一个名为get()的成员函数,它的一种使用方式与getline()类似,接受的参数相同,解释参数的方式也相同,并且都读取到行尾。但get不再丢弃换行符,而是将其留在输入队列中。

cin.get(name,number);

另外还有一种使用方法是,使用不带任何参数的cin.get()调用可读取下一个字符(即使是换行符),因此可以用它来处理换行符,为读取下一行输入做好准备。

cin.get()

 string类

 可以使用string类型的变量而不是字符数组来存储字符串

#include<iostream>
#include<string>
using namespace std;
int main()
{
	char ch[10] = "jaguar";
	string str = "pather";
	cout << "ch: " << ch << endl;
	cout << "str: " << str << endl;

}

 string对象和字符数组之间的主要区别是,可以将string对象声明为简单变量,而不是数组,而且类设计让程序能够自动处理string的大小,这使得与使用数组相比,使用string更方便

string对象的一些操作

  • 前面讲过不能将一个数组赋值给另一个数组,但可以将一个string对象赋给另一个string对象
  • string还可以使用+运算符将两个string对象合并起来,还可以使用+=运算符将字符串附加到string对象的末尾
  • 对C风格字符串,头文件cstring提供函数strcpy()将字符串复制到字符数组中,使用strcat()将字符串附加到字符数组末尾;
strcpy(charr1,charr2);    //copy charr2 to charr1
strcat(charr1,charr2);    //append contents of charr2 to charr1
  •  string类I/O。可以使用cin和运算符>>来将输入存储到string对象中,使用cout和运算符<<来显示string对象,其句法与处理C风格字符串相同;但是在每次读取一行时两者使用的句法不同;

对于C风格字符串使用方法是

cin.getline(name,number);

这种句点表示法表明,函数getline()是istream类的一个类方法(第一个参数是目标数组,第二个参数是数组长度) 

而对于string对象。使用方法是

getline(cin,name);

 这里没有使用句点表示法,表明这个getline()不是类方法,它将cin作为参数,指出到哪里去查找输入。

结构简介 

数组虽然可以存储多个元素,但是要求所有元素的类型必须相同。C++中的结构是一种比数组更灵活的数据格式,同一个结构中可以存储多种类型的数据。结构是用户定义的类型,而结构声明定义了这种类型的数据属性。

 

 关键字struct表明,这些代码定义的是一个结构的布局,标识符inflatable是这种数据格式的名称。这样便可以像创建char或int类型的变量那样创建inflatable类型的变量了。接下来的大括号中包含的是结构存储的数据类型的列表,其中每一个列表项都是一条声明语句。总之结构定义指出了新类型的特征。定义结构后,便可以使用这种类型的变量了。

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

struct inflatable
{
	char name[20];
	float volume;
	double price;
};
int main()
{
	inflatable guest = { "Glorious",1.88,15.8 };
	inflatable pal = { "Audacious",3.12,23.9 };
	cout << "guest name: " << guest.name << " guest volume " << guest.volume;
}

 结构声名的位置很重要,一种可以放在main()函数中,紧跟在开始括号的后面,另一种选择是将声明放在main()的前面 ,位于函数外面的称为外部声明。外部声明可以被其后面的任何函数使用,而内部声明只能被该声明所属的函数使用。

共用体

共用体是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。也就是说,结构体可以同时存储int、long、和double,共用体只能存储int、long/或double。共用体的句法与结构体相似,但含义不同,例如

union one4all
{
    int int_val;
    double double_val;
    long long_val;
};

 可以使用one4all变量来存储int、long/或double,条件是在不同的时间进行:

one4all pail;
pail.int_val=15;
cout<<pail.int_val;
pail.double_val=1.78;
cout<<pail.double_val;

pail有时可以是int变量,有时可以是double变量。

成员名称标识了变量的容量,由于共用体每次只能存储一个值,因此它必须有足够的空间来存储最大的成员,所以共用体的长度为其最大成员的长度。共用体的用途之一是当数据项使用两种或更多中格式(不会同时使用)时,可节省空间

枚举

enum的句法与使用结构相似,例如

enum spectrum{red,orange,yellow,green,blue,violet};

这条语句完成两项工作

  • 让spectrum成为新类型的名称;spectrum被称为枚举
  • 将red、orange等作为符号常量,它们对应整数值0~5。这些常量叫做枚举量

默认情况下,将整数值赋给枚举量,第一个枚举量的值为0,第二个枚举量的值为1,依次类推。

对于枚举,只定义了赋值运算符,没有为其定义算术运算

也可以使用赋值运算符来显式地设置枚举量的值

enum bits{one=1,two=2,four=4,eight=8};

 指定的值必须是整数,当然也可只显式地定义其中一些枚举量的值

指针和自由存储空间

前面谈到过计算机程序在存储数据时必须跟踪的3种基本属性(信息存储在何处、存储的值为多少、存储的信息是什么类型)

前面通过定义一个简单变量。声明语句指出了值的类型和符号名,还让程序为值分配内存,并在内部跟踪该内存单元。

下面用另外一种方法——指针。指针是一个变量,其存储的是值的地址,而不是值本身。对变量应用地址运算符(&)就可以获得它的位置。

声明和初始化指针 

指针声明必须指定指向的数据的类型

int* ptr;

这表明,*ptr的类型为int。由于*运算符被用于指针,因此ptr变量本身必须是指针。可以这样说ptr指向int类型、ptr的类型是指向int的指针。ptr是指针(地址),*ptr是int而不是指针。

 

 计算机需要跟踪指针指向的值的类型,例如char的地址与double的地址看上去没什么两样,但char和double使用的字节数是不同的,它们存储值时使用的内部格式也不同。

指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值,在这种情况下只能通过指针来访问内存。

#include<iostream>
using namespace std;
int main()
{
	int nights = 1001;
	int* pt = new int;    //allocate space for an int
	*pt = 1001;           //store a value there

	cout << "nights value = " << nights << " ,location " << &nights << endl;
	cout << "int ";
	cout << "value = " << *pt << " ,location " << pt << endl;
	return 0;
}

 

 程序使用new为int类型的数据对象分配内存。这是在程序运行时进行的,指针pt指向这个数据对象,如果没有pt,将无法访问这个数据单元。有了这个指针,就可以像使用变量那样使用*pt了,将值赋给*pt,从而将这些值赋给新的数据对象。

当需要内存时,可以使用new来请求,另外在使用完内存后,使用delete运算符能够将内存还给内存池,归还的内存可供程序的其他部分使用。

int *ps = new int;    //ok
delete ps;            //ok
delete ps;            //not ok

不要尝试释放已经释放的内存块,这样做的结果是不确定的。 

【只能用delete来释放使用new分配的内存,对空指针使用delete是安全的】

在使用new和delete时,应遵守以下规则

  • 不要使用delete释放不是new分配的内存
  • 不要使用delete释放同一个内存块两次
  • 如果使用new[ ]为数组分配内存,则应使用delete[ ]来释放
  • 如果使用new为一个实体分配内存,则应使用delete(没有方括号)来释放
  • 对空指针应用delete是安全的

指针和数组基本等价的原因在于指针算术和C++内部处理数组的方式。将整型变量加一后其值将增加一,但将指针变量加一后,增加的量等于它指向的类型的字节数。(将指向double的指针加1后,如果系统对double使用8个字节存储,则数值将增加8);另外C++将数组名解释为地址

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

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

相关文章

10.1UEC++/UObject

1. 1.new出的对象&#xff0c;不用自己管理内存释放&#xff1b; 2.比如两个类对象指针a,b同时指向一个苹果&#xff0c;若苹果消亡&#xff0c;会将a,b同时指向空。 3.保存时&#xff0c;将工程中的actor&#xff0c;属性等能够保存在本地就是uob在发挥作用。 4.不管在ue&…

自然语言处理实战项目12-基于注意力机制的CNN-BiGRU模型的情感分析任务的实践

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下自然语言处理实战项目12-基于注意力机制的CNN-BiGRU模型的情感分析任务的实践&#xff0c;本文将介绍一种基于注意力机制的CNN-BiGRU模型&#xff0c;并将其应用于实际项目中。我们将使用多条CSV数据样例&#xff0…

虚拟机ubuntu系统IP地址变成127.0.0.1了

使用sudo dhclient -v指令动态获取IP地址 注意要把电脑网线拔掉&#xff0c;如果WIFI和有线同时连着设备就会出现如下情况 拔掉网线后正常

网络应用基础交换机(NETBASE第五课)

网络应用基础交换机&#xff08;NETBASE第五课&#xff09; 交换机的定义 交换是按照通信两端传输信息的需要&#xff0c;用人工或设备自动完成的方法&#xff0c;把要传输的信息送到符合要求的相应路由上的技术的统称。交换机根据工作位置的不同&#xff0c;可以分为广域网交…

Tubi 时间序列 KPI 的异常值检测

欢迎来到 Tubi—— 在这里&#xff0c;广告型视频点播永不停歇&#xff01; 作为全球最大的流媒体服务之一&#xff0c;Tubi 保持稳定增长&#xff0c;并始终关注对业务发展至关重要的前沿趋势。基于此&#xff0c;Tubi 数据科学团队创建了一套全新警报系统&#xff0c;对 Key…

【Kubernetes运维篇】RBAC认证授权详解(一)

文章目录 一、RBAC授权认证理论知识1、什么是RBAC授权&#xff1f;2、认证基本流程3、K8S客户端访问apiserver的认证几方式1、第一种&#xff1a;客户端认证2、第二种&#xff1a;Bearertoken方式3、第三种&#xff1a;Serviceaccount方式 4、RBAC授权常见角色绑定方式1、第一种…

安装OSAR_Co_X

在找开源的QSAR平台 在WOS里用“open source”、“QSAR”、“platform”为关键字找到一个描述QSAR-Co-X的文献&#xff0c;这是一个基于python开发的QSAR平台&#xff08;额&#xff0c;&#xff0c;&#xff0c;目前还不是很清楚&#xff09;。 根据链接找到Github里代码的所…

讲故事vs讲知识,区别太大

讲故事vs讲知识&#xff0c;区别很大 以故事化的方式讲知识&#xff0c;一般受众爱听 讲故事&#xff0c;通常受众爱听 趣讲大白话&#xff1a;但不是所有的故事都爱听 【趣讲信息科技219期】 #非著名IT人安志强的趣味笔记# **************************** 有一小部分故事&#…

CTFshow-pwn入门-栈溢出pwn49(静态链接pwn-mprotect函数的应用)

pwn49 首先我们先将pwn文件下载下来&#xff0c;然后赋上可执行权限&#xff0c;再来查看pwn文件的保护信息。 chomd x pwn checksec pwn file pwn我们可以看到这是一个32位的pwn文件&#xff0c;并且保护信息开启了NX和canary&#xff0c;也就是堆栈不可执行且有canary。最最…

算数运算符

运算符介绍&#xff1a;运算符是一种特殊的符号&#xff0c;用以表示数据的运算、赋值和比较等。 算术运算符赋值运算符关系运算符逻辑运算符位运算符三元运算符 算术运算符 算术运算符是对数值类型的变量进行运算的。 % 取模&#xff0c;取余 在 % 的本质&#xff0c;a % b…

UE5.1.1 C++从0开始(17.GAS游戏能力系统)

教程的链接&#xff1a;https://www.bilibili.com/video/BV1nU4y1X7iQ 教程内的老师没用GAS的插件&#xff0c;而是自己写了一个。这一篇文章只是开头&#xff0c;还有很多的内容没有往里面写。 新增了一个object类&#xff0c;新增了一个使用这个类的组件。然后把这个组件用…

text-to-3d方面的论文列表分享

以下给出几篇我个人觉得比较有价值的text-to-3d的论文列表&#xff0c;论文的超链接会连接到arxiv上。 DreamfusionFantasia3DTangoLatent-NeRFMagic-3dClip-ForgeClip-MeshDreamfieldAvatarCLIPPoint-EShape-EText2Mesh

P3804 【模板】后缀自动机(SAM)

题目描述 给定一个只包含小写字母的字符串 S。 请你求出 S 的所有出现次数不为 11 的子串的出现次数乘上该子串长度的最大值。 输入格式 一行一个仅包含小写字母的字符串 S。 输出格式 一个整数&#xff0c;为所求答案。 题解&#xff1a;这里就不讲后缀自动机的模板相关…

zigbee学习之DHT11温湿度传感器+zigbee无线通信

开发环境&#xff1a;IAR烧录器串口调试助手CC2530DHT11 两个模块&#xff1a;一个作为协调器&#xff0c;负责接收数据&#xff0c;一个作为终端&#xff0c;负责发送数据 步骤&#xff1a; 1、SampleApp.c里配引脚P0_6(查看硬件上的标识) 2、DTH11.c里配引脚 3、修改PANID和信…

超纯水抛光混床树脂的选择及工艺流程

一、什么是超纯水&#xff1f; 既将水中的导电介质几乎完全去除&#xff0c;又将水中不离解的胶体物质、气体及有机物均去除至很低程度的水。电阻率大于18MΩ*cm&#xff0c;或接近18.3MΩ*cm极限值。 超纯水是科技界为了研制超纯材料&#xff08;半导体原件材料、纳米精细陶…

服务器搭建oracle,并远程连接教程

下载两个压缩包&#xff0c;然后上传到服务器&#xff0c; 软件安装09&#xff1a;CentOS安装Oracle - 虚拟机 - 5997CK - 欢迎您! (hezhilin.online) 这里有全部步骤&#xff0c;反正过了几天我也会忘记&#xff0c;不赘述了。 直接上拆的坑&#xff1a; 开启服务器端口后…

借书问题-2022年全国青少年信息素养大赛Python国赛第3题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第5讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计…

9.33UEC++、容器

1.定义&#xff1a; 2.TArray&#xff1a;快&#xff0c;小&#xff0c;高 &#xff1a;同质容器 &#xff1a;创建栈对象&#xff0c;不能创建堆对象 如何构建TArray&#xff1a; 获取方式&#xff1a; 实现方式&#xff1a;定义一个array容器数组&#xff0c;两种遍历方式…

跳跃游戏(力扣)贪心 JAVA

给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示例 1&#xff1a; 输入&#xff1a;nums [2,3,1,1,4] 输出&#xff1a;true 解释&#xff1a;可以先跳 1 步…

【实用工具】(BeyondCompare+CppCheck对某次更新的文件进行静态检查)按文件清单复制文件到指定文件夹的辅助工具【2023.07.07】

摘要 开发一个功能提交了多次代码&#xff0c;现在需要比较最终的提交和某次提交的差异并进行静态代码检查。用到了BeyondCompare和CppCheck软件。但是有个问题&#xff0c;BeyondCompare不能把差异项导出&#xff0c;于是乎花了两个小时写了个辅助工具。 使用说明 第一步&…