C++ Primer Plus(嵌入式公开课)---第4章 复合类型

本文深入探讨C++的复合类型,涵盖数组的定义、初始化规则,特别是C++11的新特性;详细讲解C语言中的字符串,包括字符数组与字符串的区别、字符常量和字符串常量的差异,以及strlen()和sizeof()的用法;介绍C++的string类,讨论其与C语言字符串的不同以及如何进行I/O操作。此外,还涉及结构体的创建与初始化、共用体的概念和字节对齐问题,以及枚举的使用。文章通过实例展示了指针与数组的交互,以及动态存储管理,包括new和delete的使用。最后,提到了数组的替代品——vector和array,并比较了它们与传统数组的异同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1017

C++ Primer Plus

第1-3章

点这里

第4章 复合类型

请添加图片描述

4.1 数组

4.1.1 概念、三要素、书写格式、下标

①数组里的元素必须是同类型的,且在计算机中占用连续的内存空间
②数组三要素:元素的类型、数组名、数组大小
③声明数组的通用格式:
请添加图片描述
数组通过下标或者索引来访问元素,下标从0开始。

4.1.2 数组的初始化规则:

只有在定义数组时才能使用初始化,此后就不能再初始化了,也不能将一个数组赋给另一个数组
请添加图片描述

4.1.3 C++11中数组初始化方式

用大括号,并且等号可以省略。
请添加图片描述
此外,C++标准模板库(STL)提供了一种数组替代品—模板类vector,而C++11新增了模板类array

4.2 字符串(C语言)

4.2.1 在数组中使用字符串

要把字符串存储到数组中,最常用的方法有两种:
1.将数组初始化为字符串常量;
2.从文件或键盘输入把字符串读入到数组中。

案例

请添加图片描述

4.2.2 区分 ①字符数组 和 字符串;②字符常量 和 字符串常量;③sizeof() 和 strlen() 。

①字符串 和 字符数组 的区别

C++笔记5:字符串 字符数组 string
字符数组不一定是字符串,但字符串一定是字符数组。

字符串以 空字符(null character) 结尾,空字符写作’\0’
请添加图片描述

②字符常量 和 字符串常量的区别(字符串常量本质上是个地址)

举例:
字符常量’S’是数字83的另一种写法;
字符串常量"S"由 字符’S’和’\0’ 组成,而且实际上"S"表示的是字符串的内存地址
请添加图片描述

③sizeof() 和 strlen() 的区别

注意区分sizeof()和strlen():
sizeof()统计整个字符数组所占内存的大小,单位是字节;
使用strlen()的前提是必须是字符串,只统计字符数组中可见的字符(‘\0’之后的字符就是不可见的字符),而且不会把 空字符\0 计算在内。

综合案例

主要用代码测试:
①字符数组 和 字符串 的区别;
②字符常量 和 字符串常量 的区别;
③sizeof() 和 strlen() 的区别。

//1.字符数组&字符串
	char arr1[10] = {
   
    'd','o','g','s' };//字符数组,不是字符串
	char arr2[10] = {
   
    'd','o','g','\0','s'};//字符数组,字符串(有结束符\0)
	cout << sizeof(arr1) << endl;//10个字节,而不是4个字节,因为sizeof()统计的是整个数组的长度
	cout << sizeof(arr2) << endl;//10个字节
	cout << strlen(arr1) << endl;//4个字符 不会报错,会警告	C6054可能没有为字符串“arr1”添加字符串零终止符。
	cout << strlen(arr2) << endl;//3个字符 只统计到结束符前的位置上,而且不把结束符算在内
							//因为结束符后面还有内容,所以也会警告	C6054可能没有为字符串“arr2”添加字符串零终止符。

//2.字符常量&字符串常量
	//用双引号括起来的字符串常量会隐式的包括结尾的空字符\0
	cout << sizeof('s') << endl;//1个字节
	cout << sizeof("s") << endl;//2个字节 除了字符s,还有结束符\0
	//cout << strlen('s') << endl;//报错,strlen()是用于字符串的
	cout << strlen("s") << endl;//1个字符

4.2.3 字符串输入–>每次读取一行字符串输入(案例见编程练习第1题

①用cin输入字符串的问题:只能读一个单词

问题:
cin使用空白(空格、制表符、换行符)作为字符串输入结束的标志,这意味着用cin获取字符数组的输入内容时一次只能读取到一个单词(因为有的单词之间是空格,比如New York,Marco Reus,而cin把空格做为字符串输入结束的标志之一)。

解决方法:
可以用istream类中成员函数getline()和get(),这两个函数都可以读取一整行直到遇到换行符。其中,getline()会丢弃最后的换行符,而get()将把换行符也作为输入的内容传输给电脑。

②面向行的输入:cin.getline() — 推荐☆☆

4.3.3 string类I/O中会讲到getline();
这节介绍的是cin.getline()
语法:

cin.getline(name1, 20);//默认是以'\n'作为输入结束符
cin.getline(name5, 20,'_');//以'_'作为输入结束符

括号里的参数分别是用来存储输入行的数组的名称,第二个参数是要读取的字符数(第二个参数是用来避免超越数组的边界),第三个参数是输入结束符,默认是换行符’\n’。
注意:cin.getline()不会保留结束符

案例:

请添加图片描述

问题+结论:

问题:
从上面的例子能看出如果一次输入的内容有多余的,就会被当作下一次输入的内容,归根结底是因为用下划线作为结束符。
结论:
所以一般不推荐使用下划线作为结束符

③面向行的输入:cin.get() —推荐☆

语法:

cin.get(name1, 20); //默认是以'\n'作为输入结束符
cin.get(name5, 20, '_' );  //以'_'作为输入结束符

括号里的参数分别是用来存储输入行的数组的名称,第二个参数是要读取的字符数(第二个参数是用来避免超越数组的边界),第三个参数是输入结束符,默认是换行符’\n’。
注意:cin.get()会保留结束符,将其放到输入队列中

案例1:

请添加图片描述

问题1+改进:

问题1:
从上面的例子可以看出,结束符和多余的内容会被当做是下一次的输入内容,这样会造成下一次的输入出错。
结论:
针对这个问题的解决办法是cin.get()把结束符吃掉

案例2:

请添加图片描述

问题2+改进:

问题2:
由于一般输入结束后都会回车,如果用下划线做结束符,并且下划线后面还有多余的内容,这样就算用cin.get()把结束符吃掉,后面多余的内容依然会影响到下一次输入。
结论:
所以不推荐用下划线或者别的符号做结束符

总结:

①首先,不论输入结束符是什么,都用.get()(可以读取一个字符)把这个结束符给读取掉,即跨过这个换行符;
②另外,不要把下划线或者其他符合作为结束符,直接用默认的回车符作为结束符最简单,没有那么多问题。
这样就为下一次输入做好充分的准备了:
请添加图片描述

④cin、cin.getline()、cin.get()总结☆☆☆(案例见编程练习第1题

读取字符串char name[20];的三种方法,推荐用第一种:(也可以看看第5章 - 5.9 编程练习 的 第7、7’、8、9题的汇总☆☆☆

char name[20]; cin.getline(name,20)☆☆ cin.get(name,20)☆ cin >> name;
多余的内容 当以下划线作为结束符时,输入时下划线后面多余的内容会影响下次输入。 当以下划线作为结束符时,输入时下划线后面多余的内容会影响下次输入。 不受多余的内容的影响
结束符 不受结束符的影响 因为会保留结束符,所以结束符和多余的内容会影响下次输入。 虽然cin只能读取一个单词,但也是以\n作为结束符,并且 \n会被存入到输入队列中 ,所以会影响到下次输入。
解决办法 对于多余的内容:
不要用下划线或者其他符号作为结束符
对于结束符的影响:
用.get()来消除
对于多余的内容:
不要用下划线或者其他符号作为结束符
对于结束符的影响:
用.get()来消除
示例: cin.getline(name1,20); cin.get(name2,20).get(); cin >> name3; cin.get();
                           
结论:
cincin.get()都需要.get()来消除结束符,而cin.getline()不需要,所以推荐用cin.getline(name,20);//把读取的整行内容给到数组name,一次最多读20个字节,这个20一般是字符数组name[20]的大小,是用来避免超越数组的边界
⑤空行和其他问题

有一个问题:如果输入的内容全是空格会怎么办,就没办法退出输入操作,其实如果想要空行,可以直接’\n’。

4.2.5 混合输入字符串和数字(案例见编程练习第1题

案例(这个案例不好,看编程练习第1题):
请添加图片描述
问题又是结束符被当做下一次输入的内容,所以先用cin.get()吃掉第一次输入遗留的结束符(‘\n’):
请添加图片描述
案例用的是cin.get(),应该用cin.getline(),不会保留结束符。

4.3 string类(C++)

4.3.1 C语言的字符串 和 C++的string类 的相同点

都可以通过下标的方式访问元素:
请添加图片描述

4.3.2 string类的 赋值、拼接、附加

不同于4.1.2 数组的初始化规则中不能将一个数组赋给另一个数组,但可以将一个string对象赋给另一个string对象;

C语言库中的函数:(包含头文件#include)
strcpy(str1, str2);//复制
strcat(str1, str2);//附加

C++中的str3 = str1 + str2; 需要
C语言中的strcpy(str3, str1); strcat(str3, str2); 来实现。

string的赋值、拼接、附加:
请添加图片描述

strlen() 和 str.size()、str.length()的区别

C++笔记5:字符串 字符数组 string
strlen()函数,这是C语言里的库函数。
.size()函数和.length()函数:都是用来统计字符个数,也不包含结束符’\0’。

4.3.3 string类I/O(案例见编程练习第1题

两种方法:
string name3;
getline(cin,name3);//可以读取整行 或者
cin >> name3;//只能读取一个单词 都可以,其中cin是istream类的一个对象。

C语言的字符串输入 C++的字符串输入
章节 4.2.3 字符串输入–>每次读取一行字符串输入 4.3.3 string类I/O
读取整行 由于cin一次只能读取一个单词,想要读取一行要用cin.getline()或者cin.get() 由于cin>>str也是一次只能读取一个单词,想要读取一行要用getline()
(注意:没有cin.)
示例 ①char name1[20]; char name2[20];
②cin>>name1;//读一个单词
cin.getline(name1,20); 和
cin.get(name2,20).get();//读整行
①string name3;
②getline(cin,name3);//读整行
cin >> name3;//读一个单词
示例备注 name1和name2是C语言的char name[],20是要读取的字符数 cin是istream类的对象,name3是string类的对象
            

补充:
C++笔记12:C++中.txt和.csv文件的写入和读取
这里的getline() 中不是istream类的对象cin,而是ifstream类的对象ifs和stringstream类的对象ss:

ifstream ifs;//创建输入流对象
string line;//记录每行的内容
getline(ifs, line)//整行读取,默认以'\n'作为分隔符
stringstream ss;
string subStr;
getline(ss, subStr, ',')) {
   
   //3.以','作为分隔符,将当前行的内容分开

4.4 结构体struct

关键字:struct

创建结构包括两步:
①声明结构体—它描述并标记了能够存储在结构中的各种数据类型;
②创建结构变量。

①声明结构体:
请添加图片描述
②创建结构体变量(C++中可以省略关键字struct):
请添加图片描述
补充:
①结构体可以通过使用成员运算符(.) 来访问各个成员变量;
②访问类成员函数(如cin.getline())的方式是从访问结构成员变量(vincent.price)的方式衍生而来的。

4.4.1 结构体初始化

方式1:(定义结构体 和 创建结构体变量 分开进行)
#include<iostream>
#include<string>
using namespace std;

//结构体声明:
struct Students{
   
   
	string name;
	int age;
};
int main(){
   
   

//C语言的常规初始化方式:
	struct 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值