C++ Primer Plus Chapter 4 --复合类型(笔记)
1. char类型
char类型是专为存储字符而设计的,通过使用字母的数值编码解决储存问题。最常见的符号集是ASCII字符集,字符集中的字符用数值编码表示(ASCII码),例如:A的编码是65,M的编码是77.
#include <iostream>using namespace std;int main()
{char ch;cout << "Enter a character: " << endl;cin >> ch;cout << "Hola!";cout << "Thanks you for the " << ch << " character." << endl;system("pause");return 0;}
输出为:
Enter a character:
M
Hola!Thank you for the M character
字符M通过cin、cout完成转换工作
输入时,cin讲键盘输入的 M 转换为 77; 输出时,cout 将值 77 转换为显示的字符 M.
若将字符用单引号括起,如‘M’(字符常量,数字77的另一种表示形式),可直接表示字符字面值。如char ch =‘M’;则cout ch=77。
2. 字符串
C-风格字符串性质:以空字符结尾,空字符被写作\0,其ASCII码为0,用来标记字符串的结尾。(字母之间要加空字符)
char cat[8] = {'f', 'a', 't', 'e', 's', 's', 'a', '\0'};
字符串常量或字符串字面值:用引号括起的字符串隐式的包括结尾的空字符。
例如,"s"表示的是两个字符(s和\0)组成的字符串(实际上是字符串所在的内存地址)。
char bird[11] = "Mr.Cheeps";
char fish[] = "Bubbles";
另,
sizeof运算符计算整个数组的长度,
但strlen( )函数计算的是储存再数组中的字符串的长度,另外,它只计算可见的字符,不会把空字符计算在内。
1. 字符串输入:
cin通过空白(空格、制表符和换行符)来确定字符串的结束位置
2. 每次读取一行字符串输入:
cin遇到空格就直接确定字符结束的位置,这样会常常引发错误,例如:输入城市名称 New York,将无法正常输出。面向行的成员函数getline( )和get( )将解决这一问题。
1)面向行的输入:getline( )
回车键或达到读取字符上限,停止读取。cin.getline(name1 name2 name3,...,字符数 );
2)面向行的输入:get( )
读取完不会丢弃换行符,这样换行符会留在输入队列中,第二次调用时看到的第一个字符就是换行符,因此不会读取任何内容。解决方案:cin.get(name1 name2,字符数); cin.get( ); cin.get(name1 name2,字符数);
或 cin.get(name1 name2,字符数).get( );
3. 混合输入字符串和数字:
cin >> year;-----改为(cin >> year).get( ); 这样可以防止出现输入数字后,回车,无法再输入字符的选择
3. string类简介
1. string类:提供了一种将字符串作为一种数据类型的表示方法(从理论上说,可以将char数组视为一组用于存储一个字符串的char存储单元,而string类变量时一个表示字符串的实体);
2. 要使用string类,必须在程序中包含头文件string;
3. 不能将一个数组赋给另一个数组,但可以将一个string对象赋给另一个string对象。
4. string类简化了字符串的合并操作,可以直接使用+进行合并。
5. 计算char 和string 包含的字符个数:int len1 = str1.size( ); //obtain length of str1
int len2 = strlen(charr1); //obtain length of charr1
函数 strlen( ) 时一个常规的函数,它接受C-风格的字符串作为自己的对象,并返回字符串包含的字符数;str1是一个string的对象,而size( ) 是string类的一个方法。
6. cin getline(charr, 20); //char
getline (cin, str); //string
7. strcpy( ):将字符串复制到字符数组中
strcpy(charr1, charr2); //copy charr2 to charr1
strcat( ):将字符串附加到字符数组末尾;
strcat(charr1, charr2); //append contente of charr2 to charr1
4. 结构简介(struct)
1. 在数组中只能存储一种数据类型,而结构,是一种比数组更灵活的数据格式,同一个结构可以存储多种类型的数据;
2. 结构是用户定义的类型,而结构声明定义了这种类型的数据属性。定义了类型后,变可以创建这种类型的变量。因此,创建结构包括两部。首先,定义结构描述--它描述并标记了能够存储在结构中的各种数据类型。然后,按照描述创建结构变量(结构数据对象);
struct inflatable //structure declaration
{char name[20];float volume;double price;
}
1)新类型的名称:inflatable,inflatable中包含char,float,double这三种类型的变量;
2)列表中的每一项都被称为结构成员,该结构有3个成员;
3)定义结构后,便可以创建这种结类型的变量了
inflatable hat;
inflatable woopie_cushion;
inflatable mainframe;
4)通过成员名能够访问结构的成员,例如,hat的类型是inflatable,hat.volume 指的是结构volume成员,因此hat.volume 相当于是float类型的变量,可以像使用float变量那样使用。总之,hat是一个结构,而hat.volume是一个float的变量;
inflatable guest =
{"Glorious Gloria", //name value1.88, //volume value29.99 //price value
};
要注意各个值输入的顺序,并通过“,”隔开,每个值各占一行。也可以放在一行,但注意要用,隔开;
3. 位于main( ) 函数外面的声明被称为外部声明,反之为内部声明;外部声明可以被其后面的任何函数使用,而内部声明只能被声明所属的函数使用;
4. 变量也可以在函数外部和内部定义,C++提倡使用内部变量和外部声明;
5. 可以将成员name指定为string对象而不是字符数组
#incude <string>
struct inflatable
{std::string name;float volume;double price;
};
6. 结构数组
inflatable guests[2] // initializing an array of structs
{{"Bambi", 0.5, 21.99}' // first structure in array{"Godzilla, 2000, 565.99} // next structure in array
};
1)guests 本身是一个数组,而不是结构,因此像guests.price这样的表示是无效的;
2)数组中的每个元素都是结构;
7. 结构中的位字段(从未见过这种表示,没get到这种用法到底是干嘛的?)
制定占用特定位数的结构成员,这使得创建与某个硬件设备上的寄存器对应的数据结构非常方便;
字段的类型应为整型或枚举,接下来是冒号,冒号后面是一个数字,它指定了使用位数
struct torgle_register
{unsigned int SN : 4; // 4 bits for SN valueunsigned int : 4; // 4 bits unusedbool goodIn : 1; // valid input (1 bit)bool goodTorgle : 1; // successful torgling
};
5. 共用体(union)
1. 共用体是一种数据格式,它和结构不同,结构可以同时存储多种类型的数值,而共用体只能同时存储其中的一种,不同的数据类型要分别进行调用,不能同时使用。
union one4all
{int int_val;long long_val;double double_val;
};
one4all pail;
pail.int_val = 15;
cout << pail.int_val;
pail.double_val = 1.38;
cout << pail.double_val;
6. 枚举 (enum)
1. enum 是一种创建符号常量的方式,可以替代const;
2.
enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet}
3. 枚举量是整型,可被提升为 int 类型,但 int类型不能自动转换为枚举类型;
4. 枚举的取值范围:最大值(大于最大值的,最小的2的幂 - 1),最小值(0,或最大值的相反数);
7. 指针和自由存储空间
1. 如何找到常规变量的地址?
在变量前面加地址运算符(&),例如,home是一个变量,则&home是它的地址;
2. 指针---是一个变量,其存储的是值的地址,因此,指针表示的是地址;
p_updates = &updates;
3. ( * )运算符,被称为间接值或解除引用运算符
将其应用于指针,可以得到该地址处存储的值。例如,假设 a 是一个指针,则 a 表示的是一个地址,而 *a 表示存储在该地址处的值,*a 与常规的 int 变量相同。
4. 假设,update 为 int变量,p_update 为指针变量
update,p_update就好比一枚硬币的两面。变量 update 表示值,并使用&运算符来获取地址;而变量 p_update 表示地址,并使用*运算符来获得值。
5. 指针声明必须指定指针指向的数据的类型
int * p_update;
p_update 指向 int 类型,p_update 的类型是指向 int 的指针,p_update 是指针(地址),而 *p_update 是int, 而不是指针。
6. 指针只是分配了存储地址的内存,没有分配指针所指的数据的内存
long * fellow; //creat a pointer-to-long
*fellow = 22333; // place a value in never-never land
以上,fellow没有被初始化,程序会默认它为存储22333的地址,但很可能fellow指向的地方并不是22333的地址。
注意:一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。
int update = 6;
int * p_update;
p_update = &update;
7. 指针不是整型,它描述的地址(位置),地址是不能像int类型的整型数那样进行加减乘除运算的。
int * pt;
pt = 0XB8000000; //wrong,type mismatch
pt是一个int类型的指针,0XB8000000是一个整数,两者是两种概念,不能相互匹配;
int * pt;
pt = (int *) 0XB8000000; //type match
注意,pt是int值的地址并不意味着pt本身的类型是int;
8. 使用 new 来分配内存
1. (没懂)程序运行时内存分配,将指针初始化为变量的地址;变量是在编译时分配的有名称的内存,而指针只是为可以通过名称直接访问的内存提供一个别名。。指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。。在这种情况下只能通过指针来访问内存。
(new 是根据数据类型,先动态分配的内存,再返回地址,最后将地址赋给变量,这样变量就可以访问内存单元、可以像使用变量那样使用[*变量]、可以将值赋给[*变量])
2.
int * pn = new int;
new int 告诉程序,需要适合存储的 int 的内存。new运算符根据类型来确定需要多少字节的内存。然后,他找到这样的内存,并返回其地址。接下来,将地址赋给 pn,pn时被声明为指向 int 的指针。
9. 使用 delete 释放内存
1.delete运算符,它使得在使用完内存后,能够将其归还给内存池。
2. delete 只能释放有 new 分配的内存;
3.
int * ps = new int; // allocate memory with new
. . . // use the memory
delete ps; // free memory with delete when done
可释放ps指向的内存,但不会删除指针ps本身;
10. 使用 new 来创建动态数组
1. 使用 new 创建动态数组
int * pt = new int;
short * ps = new short [500];
delete pt;
delete [] ps;
1)new 运算符返回第一个元素的地址;
2)当程序使用完 new 分配的内存块时,要用 delete 来释放它们;
3)不要使用 delete来释放不是 new 分配的内存;
4)不要使用 delete 释放同一个内存块两次;
5)如果使用 new[ ] 为数组分配内存,则应使用 delete[ ] 来释放;
6)如果使用 new 为数组分配内存,则应使用 delete 来释放;
7)对空指针应用 delete 时安全的。
2. 使用动态数组
#include <iostream>using namespace std;int main()
{double * p3 = new double [3];p3[0] = 0.2;p3[1] = 0.5;p3[2] = 0.8;cout << "p3[1] is " << p3[1] << ".\n";p3 = p3 + 1; // increment the pointercout << "Now,p3[0] is " << p3[0] << " and";cout << "p3[1] is " << p3[1] <<".\n";p3 = p3 - 1; // point back to beginningdelete [] p3;system("pause");return 0;}
输出为:
p3[1] is 0.5.
Now,p3[0] is 0.5 andp3[1] is 0.8.
1)指针 p3,它指向包含3个 double 值的内存块中的第一个元素;
2)将指针当作数组名来使用,p3[0] 为数组中第一个元素,p3[1] 第二个元素,p3[2]第三个元素;
3)需要注意的是,p3 = p3 +1,指针是变量,即指针指向下一个地址;
4)最后,p3 = p3 - 1,让指针又回到了原来的位置,释放内存。
11. 指针、数组和指针算术
1.指针算术:指针变量的值加1后,增加的量等于它指向的类型的字节数。
例如,指向 double 的指针加1后,如果系统对 double 使用 8 个字节存储,则数值将增加 8;
2. 指针小结
1)声明指针
double * pn;
char * pc;
pn 和 pc 都是指针,而 double * 和char * 是指向 double 的指针和指向 char 的指针;
2)给指针赋值
即,将内存地址赋给指针。& 运算符来获取被命名的内存地址,new 运算符返回未命名的内存地址;
double * pn; double * pa; char * pc; double bubble = 3.2; pc = &bubble; pc = new char; pa = new double[30];
3)对指针解除引用
4)区分指针和指针所指向的值
5)数组名
数组名视为数组的第一个元素的地址;
但,将sizeof 运算符用于数组名时,此时将返回整个数组的长度(单位为字节);
6)指针算术
7)数组的动态联编和静态联编
new 是动态,数组声明创建的时静态;
8)数组表示法和指针表示法(没看懂说的是啥,p111)
3. 指针和字符串
#include <iostream>
#include <cstring> // declare strlen( ), strcpy( )using namespace std;int main()
{char animal[20] = "bear"; // part 1const char * bird = "wren";char * ps;cout << animal << " and " << bird <<endl;cout << "Enter a kind of animal: ";cin >> animal;ps = animal;cout << ps << "!" << endl;cout << "Before using strcpy( ):" << endl;cout << animal << " at " << (int *) animal << endl; // part 2cout << ps << " at " << (int *) ps << endl;ps = new char[strlen(animal) + 1]; // part 3strcpy(ps, animal);cout << "After using strcpy( ):" << endl;cout << animal << " at " << (int *) animal << endl;cout << ps << " at " << (int *) ps << endl;delete [] ps;system("pause");return 0;}
输出为:
bear and wren
Enter a kind of animal: fox
fox!
Before using strcpy( ):
fox at 00AFFA24
fox at 00AFFA24
After using strcpy( ):
fox at 00AFFA24
fox at 00D75D48
1)part 1
ps指针未被初始化,animal数组初始化为字符串“bear”,charz=指针指向一个字符串;
“wear”实际表示的是字符串的地址;
字符串字面值就是常量,因此在代码声明中可以使用关键字const;
如果cout << ps,即创建未初始化的指针,则可能显示一个空行、一堆乱码、或是程序崩溃;
C++不能抱枕字符串的字面值被唯一存储,故使用const;
在将字符串读入程序时,应使用已分配的内存地址。该地址可以是数组名也可以是使用new初始化后的指针;
2)part 2
a. 如果给cout提供一个指针,它将打印地址。但指针类型时*char,则cout将显示指向的字符串;
如果要显示的是字符串的地址,就要强制转换为int*,如,(int *) ps;
b. animal 和 ps 都是指针,因此,ps = animal, 复制的时地址而不是字符串。这样,两个指针就指向了相同的内存单元和字符 串;
3)part 3
a. 分配内存来存储字符串:ps = new char[strlen(animal) + 1];
b. 将animal赋给 ps 时不可行的,因为这样只能修改存储在 ps 中的地址,从而失去程序访问新分配内存的唯一途径。
需要strcpy( )函数;
c.通过strcpy( )、new可获得“fox”的两个独立的副本;
综上:复制地址---分配内存来存储---通过strcpy( )字符串复制到新分配的空间
这章的内容为什么那么多!!!我感觉自己马上要学晕了!!!!
4. strcpy( ) 和 strncpy( ):后者可指定字符长度;
C++ Primer Plus Chapter 4 --复合类型(笔记)相关推荐
- C++ Primer Plus 学习笔记(第 4 章 复合类型)
C++ Primer Plus 学习笔记 第 4 章 复合类型 数组 数组(array)是一种数据格式,能够存储多个同类型的值. 要创建数组,可使用声明语句.数组声明应指出以下三点: 存储在每个元素的 ...
- C++Primer Plus (第六版)阅读笔记 + 源码分析【第四章:复合类型】
第四章:复合类型 数组 第四章:复合类型 复合类型组成: 基本整型. 浮点类型. 数组:存储多个同类型的值.(一组特殊的数组可以存储字符串.) 结构体:存储多个不同类型的值. 指针:将数据所处位置告诉 ...
- c++primer plus 6 读书笔记 第四章 复合类型
目录 第4章复合类型 4.1 数组 4.1.1 4.1.2 数组的初始化规则 4.1.3C ++数组初始化方法使用{} 赋值,禁止缩窄转换. 4.2 字符串 4.2.1 拼接字符串常量 4.2.2 在 ...
- Go圣经-学习笔记之复合类型(二)
2019独角兽企业重金招聘Python工程师标准>>> 上一篇 Go圣经-学习笔记之复合类型 下一篇 Go圣经-学习笔记之复合数据结构(三) map介绍和简单使用 map是一种无序的 ...
- 【C++ Primer Plus】第4章 复合类型
目录 [数组] [C- 字符串] 字符串的输入 字符串拼接 字符串常用函数 [数组长度] [string类] 原始字符串 [struct 结构简介] [枚举] [指针和自由存储空间] 使用new分配内 ...
- c++ 复合类型 读书笔记(二)
目录 String类 string拼接 赋值 struct 结构数组 结构中的位字段 共用体(union) 枚举(enum) 设置枚举量的值 枚举量的取值范围 指针与c++基本原理 声明和初始化指针 ...
- bool类型头文件_C++ Primer Chapter2 变量和基本类型
第二章 变量和基本类型 声明: 本文为<C++ Primer 中文版(第五版)>学习笔记. 原书更为详细,本文仅作学习交流使用. P30-P71 数据类型是程序的基础.C++语言支持广泛的 ...
- 《C++Primer 中文第四版》 笔记
endl 是一个特殊值,称为操纵符,将它写入输出流时,具有输出换行的效果,并刷新与设备相关联的 缓冲区.通过刷新缓冲区,用户可立即看到写入到流中的输出 程序员经常在调试过程中插入输出语句,这些语句都应 ...
- 实现在GET请求下调用WCF服务时传递对象(复合类型)参数
WCF实现RESETFUL架构很容易,说白了,就是使WCF能够响应HTTP请求并返回所需的资源,如果有人不知道如何实现WCF支持HTTP请求的,可参见我之前的文章<实现jquery.ajax及原 ...
最新文章
- 6个超炫酷的HTML5电子书翻页动画【转】
- 【连载】第一章:亚洲-台湾(1)
- 编译器和链接器的任务是什么
- PHP 文件夹操作「复制、删除、查看大小」递归实现
- html阴影 渐变,CSS3:图层阴影及渐变
- iOS边练边学--UITableViewCell的常见属性设置
- Java 输入输出流 转载
- 转iOS逆向工程:Reveal查看任意app的高级技巧!
- DT大数据梦工厂视频资源
- matlab的四个取整函数!
- python用xlwings 隐藏Excel某行或某列
- java爬虫抓取nba_利用Python爬虫爬取NBA数据功能实例分享
- “火星一号”项目计划于2026年实现载人登陆火星
- 【C和指针】const指针
- 【一句日历】2019年5月
- 孪生素数 所谓孪生素数指的就是间隔为 2 的相邻素数,它们之间的距离已经近得不能再近了,就象孪生兄弟一样。
- java启动器_Minecraft Java版新启动器正式开放
- 在c程序语言中aph,C 语言试题
- 跟我学制作Pak文件
- 仿基因编程原理导论(里面的几个重要的概念正在做修正,所以这只能算是一个原理的初稿。)
热门文章
- 11月11日在线研讨会预热 | ODX诊断数据库转换工具 — VDC(ODX)
- 吃鸡是python写的吗_吃鸡游戏也是用Python写的?学了Python,120个月年终奖向你招手~...
- 如何将浏览器设置为海外当地浏览器?
- 微型计算机接口及控制技术,微型计算机及接口技术
- 如何选择高密度应用光纤配线箱?
- 项目经理如何做好会议管理 节约时间?
- 离线下载,腾讯插入迅雷的利刃
- Auto CAD:CAD软件之底边菜单栏(捕捉模式、极轴状态、对象捕捉、允许禁止动态UCS、动态输入、显示隐藏线宽、快速查看图形、选择循环命令、切换空间按钮)简介之详细攻略
- bert 是单标签还是多标签 的分类_搞定NLP领域的“变形金刚”!手把手教你用BERT进行多标签文本分类...
- LVS负载均衡群集之构建NAT模式