- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C++ Primer Plus 第四章之C++ Primer Plus复合类型学习笔记由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
数组(array)是一种数据格式,能够存储多个同类型的值。每个值都存储在一个独立的数组元素中,计算机在内存中依次存储数组的各个元素.
数组声明的三个特点:
C++中可以通过修改简单变量的声明,添加中括号(其中包含元素数目)来完成数组声明.
例如:
short days[24]; // 一天有24个小时 。
声明数组的的一般语法格式为:
1
2
|
// 数组类型 数组名字[数组的大小]
int
score[4];
// 四个人的分数,整型数组
|
数组的大小是指定元素的数目,必须是整型常数或const值,也可以是常量表达式(8*sizeof(int)) 。
可以使用其他的类型来创建(C语言使用术语:派生类型) 。
数组的用途,可以单独访问数组元素,方法是:使用下标或索引对元素进行编号。从0开始编号.
编译器不会检查下标是否有效,所以要注意下标合法性,避免程序异常问题。 C++使用索引的方括号表示法来指定数组元素.
1.只有在定义数组时才能初始化,此后不能使用,也 不能将一个数值赋给另一个数组.
2.初始化数组时,提供的值少于数组的元素数目.
3.如果只对数组的一部分进行初始化,则编译器把其他元素设置为0.
4.如果初始化为{1}而不是{0},则第一个元素被设置为1,其他元素都被设置为0. 。
5.如果初始化数组方括号内([])为空,C++编译器将计算元素个数。 例如:short things[] = {1,3,5,7},
C++11将使用大括号的初始化(列表初始化)作为一种通用的初始化方式,可用于所有类型.
在C++中列表初始化就增加了一些功能:
初始化数组时,可省略等号(=) 。
1
|
double
earnings[4] {1.2e4,1.6e4,1.1e4,1.7e4};
|
可不在大括号内包含任何东西,这会将所元素都设置为零.
1
2
3
|
unsigned
int
const
[10] = {};
float
balances[100] {};
|
列表初始化禁止缩窄转换.
1
|
long
num[] = {25,92,3.0};
// 浮点数转换为整型是缩窄操作
|
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include<iostream>
using
namespace
std;
int
main()
{
// 创建一个名字为yams的数组,包含了3个元素,编号是0~2.
int
yams[3];
yams[0] = 7;
yams[1] = 8;
yams[2] = 6;
// 使用逗号分隔的值列表(初始化列表),然后用花括号括起来即可。
// 列表中的空格是可选的,如果没有初始化函数中定义的数组,其元素值也是不确定。
int
yamcosts[3] = {1,2,3};
cout<<
"yams 数组是:"
<<yams[0]+yams[1]+yams[2]<<endl;
cout<<
"yams[1] = "
<<yams[1]<<endl;
int
total = yams[0] * yamcosts[0] + yams[1] * yamcosts[1];
total = total + yams[2] * yamcosts[2];
cout<<
"total yam = "
<<total<<endl;
// sizeof运算符返回类型或数据对象的长度(单位为字节)。
// 如果将sizeof运算符用于数组名,得到的是整个数组的字节数。
// 如果sizeof用于数组元素,得到的是元素的长度(单位为字节)。
cout<<
"\n yams数组的大小 = "
<<
sizeof
(yams)<<
" Bytes.\n"
;
cout<<
"一个元素的大小 = "
<<
sizeof
(yams[0])<<
" Bytes.\n"
;
return
0;
}
|
字符串是存储在内存的连续字节中的一系列字符.
C语言,常常被称为C-风格字符串(C-style String) 。
以空字符(\0,ASCII码对应为0)来标记字符串的结尾.
基于String类库的方法 。
存储在连续字节中的一系列字符意味着可以将字符串存储在char数组中。其中每个字符都位于自己的数组元素中.
使用引号括起来的字符串,这种字符串叫 字符串常量(String constant) 或 字符串字面值(string literal) .
字符串常量(使用双引号)不能与字符常量(使用单引号)互换.
例如:
1
|
char
name[] =
"Soler"
;
|
字符串结尾的空字符,不用直接显式包括,机器在键盘输入,将字符串读入到char类型中,会在结尾自动加上空字符.
⚠️注意:确定了存储字符串所需的最短数组时,不要忘记把结尾的空字符包括在内.
方法:直接两个引号括起来的字符串合并为一个。任何两个由空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个.
1
|
cout<<
"My name is "
"Soler HO.\n"
|
2.3 在数组中使用字符串 。
将字符串存储到数组的常用方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <iostream>
#include <cstring> /*提供strlen()函数*/
using
namespace
std;
const
int
Size = 15;
int
main()
{
char
name1[Size];
char
name2[Size] =
"C++owboy"
;
// 字符串的拼接
cout<<
"Howdy!I'm "
<< name2;
cout<<
"!,What's your name?\n"
;
cin>>name1;
cout<<
"Well, "
<<name1<<
",your name has : "
<<
strlen
(name1)<<
" letters and is stored!\n"
;
cout<<
"In an array of "
<<
sizeof
(name1)<<
" Bytes\n"
;
cout<<
"Your iniatial is "
<<name1[0]<<
".\n"
;
// name1数组中的第一个元素
name2[3] =
'\0'
;
cout<<
"Here are the first 3 characters of my name:"
<<name2<<endl;
return
0;
}
|
strlen() 函数 和 sizeof()运算符的区别 。
strlen()函数 。
返回的是存储在数组中的字符串的长度,而~~不是数组本身的长度~~。strlen()只计算可见的字符,而 不把空字符计算在内.
sizeof() 运算符 。
指出变量或数据类型的字节大小。可用于获取类、结构、共用体和其他用户自定义数据类型的大小.
解决没有逐行读取输入的缺陷.
istream中提供了面向行的类成员函数:getline() 和 get() 函数 。
2.4.1 面向行的输入:getline() 。
使用通过回车键输入的换行符来确定输入结尾。使用 cin.getline() .
函数有两个参数:
数组名称
。空字符(\0)
)。格式:
1
|
cin.getline(name,ArSize);
|
2.4.2 面向行的输入:get() 。
与getline() 函数类似,接受的参数相同,解释参数的方式也相同,并读到行尾.
区别:get() 读取并丢弃换行符,将其留在输入队列中.
格式:
1
|
cin.get(name,ArSize);
|
get() 将两个类成员函数拼接(合并):
1
|
cin.get(name,ArSize).get();
|
⚠️注意:get() 函数读取空行后设置会失效,输入会被阻断。可用如下恢复:
1
|
cin.clear();
|
混合输入数字和面向行的字符串会导致的问题:无法输入地址.
解决方法:直接使用get()进行读取之前丢弃换行符.
string类位于名称空间std中,所以需要提供using指令或者是直接使用std::string进行引用.
要使用string类,必须在程序中包含头文件string中.
string类定义隐藏了字符串的数组性质.
使用string对象的方式和使用字符数组相同.
C-风格字符串
来初始化string对象中。cin来将键盘输入
存储到string对象中。cout
来显示string对象。数组表示方法
来访问存储在string1对象中的字符。赋值 —— 不能将一个数组赋给另一个数组,但可以将一个string对象赋另一个string对象.
1
2
3
4
5
6
7
8
|
char
char01[20];
// 创建一个空列表
char
char02[20] =
"Jason"
;
// 创建一个初始化数组
string str01;
// 创建一个空的string对象
string str02 =
"Soler Ho"
;
// 创建一个初始化的string对象
char01 = char01;
// 不可执行,一个数组不能赋值给另一个数组
str01 = str02;
// 可执行,可将一个string对象赋给另一个string对象。
|
string类简化字符串合并操作.
利用运算符 + 将两个string对象合并起来.
1
2
3
4
|
string str01;
string str02 =
"Soler Ho"
;
string = str01 + str02;
|
可以使用运算符 += 将字符串附加到string对象的末尾.
1
2
3
4
|
string str01;
string str02 =
"Soler Ho"
;
str01 += str02;
|
结构是用户定义的类型,而结构声明定义了类型的数据属性.
定义类型之后,就直接创建类型的变量.
结构比数组灵活,同一个结构中可以存储多种类型的数据.
1
2
3
4
5
6
|
struct
(关键字) 类型名(标记成为新类型的名称)
{
结构成员1;
结构成员2;
结构成员3;
};
//(结束结构声明)
|
对于结构中的成员,使用成员运算符(.)来进行访问各个成员.
与数组一样,列表的初始化用于结构,且等号(=)可有可无.
1
|
infor Soler_infor {
"Soler HO"
,55,168};
// 在C++11中,= 号可以省略
|
如果大括号内未包含任何东西,各个成员都将设置为零.
1
|
infor Soler_infor {};
|
不允许缩窄转换 。
✅ 小Tips:C++允许在声明结构变量时省略关键字struct.
成员赋值(memberwise assignment):可以使用赋值运算符(=)将结构赋另一个同类型的结构。这样结构中的每个成员都将被设置为另一个结构中相应成员的值。即使成员是数组。这种方式就是成员赋值.
共用体(union),也叫做联合(union)。一种 构造数据类型 .
关键字:union 。
联合(union):将不同类型的数据在一起共同占用同一段内存 。
存储不同的数据类型,但只能同时存储其中的一种类型 。
示例:
1
2
3
4
5
6
|
union
sample
{
int
int_val;
long
long_val;
double
double_val;
};
|
同时存储int、long和double
。只能存储int、long和double
三种。结构体:struct 。
共用体:union 。
常用于操作系统数据结构或硬件数据结构.
匿名共用体(anonymous union)没有名称,其成员将成为位于相同地址处的变量.
C++的enum工具提供了另一种创建符号常量的方式,可以代替const,允许定义新类型,但必须有严格限制.
使用enum的语法格式与结构的使用类似.
1
|
enum
color{red,orange,yellow,green,blue,voilet};
|
6.1 设置枚举量的值 。
1
|
enum
week{Monday = 1,Tuesday = 2;Wednesday = 3;Thursday = 4};
|
指定的值必须是整数。也可以只显示定义其中一些枚举量的值.
如果第一个变量未初始化,默认为0。后面没有被初始化的枚举量的值将比其前面的枚举量大1。也可以创建多个值相同的枚举量.
1
|
enum
{zero,null = 0,numero_one,one = 1};
|
每个枚举都有取值范围的上限,通过强制类型转换,可以将取值范围中的任何整数值赋给枚举常量,即使这个值不是枚举值.
找到大于最大值的,最小的2的幂,减去1,得到就是取值范围的上限.
如果不小于0,则取值范围的下限为0,否则,采用寻找上限方式相同的方式,但是要加上负号.
对于选择使用多少空间来存储枚举由编译器决定.
对于地址显示结果是十六进制表示法,因为都是常常描述内存的表示法.
指针与C++基本原理 。
面向对象编程和传统的过程性编程的区别,OOP强调的是运行阶段(而不是编译阶段)进行决策.
运行阶段:程序正在运行是,取决于不同的情况。编译阶段:编译器将程序组合起来时。坚持原先设定的安排 。
指针用于存储值的地址。指针名表示的是地址.
*运算符称为间接值或解除引用运算符,将其应用于指针,得到该地址处存储的值.
指针的声明必须指定指向的数据的类型.
1
|
int
*p_updates;
|
*p_updates 的类型是int,所以*运算符被用于指针,所以p_updates变量必须是指针.
运算符*两边的空格是可选的.
1
2
3
|
int
*ptr;
/*该情况强调:*ptr是一个int类型的值。*/
int
* ptr;
/*该情况强调:int* 是一种类型,指向int的指针。*/
|
在C++中,int*是一种复合类型,是指向int的指针.
1
|
double
*tax_ptr;
|
在C++创建指针时,计算机将分配用来存储地址的内存,但是不会分配用来存储指针所指向的数据的内存.
⚠️注意:一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址.
整数可以加减乘除等运算,而指针描述的是位置.
C++语言 数字不能作为地址使用,如果要把数字当地址来使用,应通过强制类型转换将数字转换为适当的地址类型.
7.4 使用new分配和delete释放内存 。
指针在运行阶段 分配未命名的内存以存储值。然后使用内存来访问内存.
C语言中,使用 库函数malloc()来分配内存。C++中使用 ———— new运算符.
7.4.1 要注意使用delete进行内存的释放 。
需要内存时,直接使用new来请求,这是内存管理数据包的一个方面.
如果使用了delete运算符,使得在使用完内存后,能够将其归还给内存池,这是有效使用内存的关键.
使用delete时,后面要加上指向内存块的指针.
1
2
3
|
int
* ps =
new
int
;
// 使用new进行内存分配
...
delete
ps;
// 使用delete进行内存的释放
|
⚠️注意点:
1.使用delete释放ps的内存,但是 不会删除指针ps本身.
2.只能用delete来释放使用new分配的内存,但是如果是空的指针使用delete是安全的.
使用delete的关键:用于new分配的内存。 不是要使用于new的指针,而是用于new的地址.
❌警告:不能创建两个指向同一个内存块的指针。会增加错误地删除同一个内存块两次的可能性.
C++中,创建动态数组,只需要将数组的元素类型和元素数目告诉new即可。必须在类型名后面加上方括号,其中包含了元素数目.
通用格式:
1
2
3
|
Type_name *pointer_name =
new
Type_name[num_element];
//例子
int
* psome =
new
int
[10];
// 创建10个int元素的数组
|
new运算符会返回第一个元素的地址 。
如果使用完new分配的内存,使用delete进行内存的释放.
1
|
delete
[] psome;
// 进行内存的释放
|
delete和指针直接的方括号告诉程序,应释放整个数组,不仅仅是指针指向的元素.
delete中的方括号的有无取决于使用new时的方括号有无.
对于指针数组的使用,直接可以按照普通数组的使用即可.
指针和数组基本等价的原因:指针算术(pointer arithmetic) 和C++ 内部处理数组的方式.
对整数变量 + 1,其值增加1 。
对指针变量 + 1,增加的量等于它指向的类型的字节数.
获取数组地址的两种方式 。
1
2
3
|
double
* pw = wages;
// 数组名 = 地址 ;将pw声明为指向double类型的指针。然后将其初始化为wages - - - wages数组中第一个元素的地址。
short
* ps = &wages[0];
// 使用地址操作;使用地址运算符来将ps指针初始化为stacks数组的第一个元素。
|
8.1.1 声明指针 。
要声明指向特定类型的指针,语法格式:
1
2
3
4
|
TypeName *pointerName;
// 例子
double
* pn;
// pn 指向一个double类型
char
* ps;
// ps 指向一个char类型
|
8.1.2 给指针赋值 。
将内存地址赋给指针。可以对变量名应用 & 运算符,来获得被变量名的内存地址,new运算符返回未命名的内存的地址.
示例:
1
2
3
4
5
6
7
8
|
double
* pn;
// pn 指向一个double类型
double
* pa;
// pa 指向一个double类型
char
* pc;
// pc 指向一个char类型
double
bubble = 3.2;
pn = &bubble;
// 把bubble的地址赋值给 pn
pc =
new
char
;
// 新建char地址并分配给pc
|
8.1.3 对指针解除引用 。
对指针解除引用意味着获得指针指向的值.
方法1:对指针应用解除引用或间接值运算符(*)来解除引用.
1
2
|
cout<<*pn;
*pc =
's'
;
|
方法2:使用数组表示法。 不可以对未初始化为适当地址的指针解除引用.
8.1.4 数组名 。
多数情况下,C++将数组名视为数组的第一个元素的地址.
1
|
int
tacos[10];
// 此时的tacos同样也是&tacos[0]
|
8.1.5 指针算术 。
C++中允许指针和整数相加。加1 的结果等于原来的地址值加上指向的对象占用的总字节数.
也可以将一个指针减去另一个指针,获得两个指针的差。得到一个整数,仅当两个指针指向同一个数组(也可以指向超出结尾的一个位置)时,这种情况会得到两个元素的间隔.
8.1.6 数组的动态联编和静态联编 。
使用数组声明来创建数组时,将采用静态联编,即数组长度在编译时设置.
1
|
int
tacos[10]
// 静态联编
|
使用new[]运算符创建数组时,将采用动态联编(动态数组),即将在运行时为数组分配空间,其长度为运行时设置.
使用这类数组后,要使用delete[]释放所占用的内存.
8.1.7 数组表示法和指针表示法 。
使用方括号数组表示法等同于对指针解除引用.
数组名和指针变量也是一样。所以对于指针和数组名,既可以使用指针表示法,也可以使用数组表示法.
1
2
3
4
5
6
|
int
* pt =
new
int
[10];
*pt = 5;
pt[0] = 6;
pt[9] = 5;
int
coats[10];
*(coats + 4) = 12;
|
数组名是第一个元素地址.
如果给cout提供一个字符的地址,则它将从该字符开始打印,直到遇到空字符为止.
在cout和多数C++表达式中,char数组名、char指针以及用引号括起来的字符串常量都被解释为字符串第一个字符的地址.
不要使用字符串常量或未被初始化的指针来接收输入.
在字符串读入程序时,应使用已分配的内存地址。该地址不是数组名,也可以使用new初始化过的指针.
strcpy()接受两个参数,第一个:目标地址,第二个:要复制的字符串的地址.
要确定目标空间有足够的空间来存储副本.
对于在指定结构成员时,句点运算符和箭头运算符的选择时:
结构名
,则使用句点运算符(.)
。指向结构的指针
,则使用箭头运算符(->)
。把new用于结构的两个步骤 。
创建结构 。
要创建结构,需要同时使用结构类型和new.
创建访问其成员.
在函数内部定义的常规变量使用自动存储空间,称为自动变量.
只在特定函数被执行时存在.
自动变量时一个局部变量,作用域为包含它的代码块。通常存储在栈中,遵循后进先出(LIFO).
变量称为静态的方式在函数外面定义在声明变量时使用关键字static.
整个程序执行期间都存在的存储方式(存在于程序的整个生命周期).
内存池(自由存储空间或堆)用于静态变量和自动变量,且内存是分开的.
模板类vector和array是数组的替代品.
模板类vector类似于string类,也是一种动态数组.
vector对象
包含在vector头文件
中。using编译指令
、using声明
或std::vector
。语法
来指出它存储的数据类型
。元素数
。
位于名称空间std中,与数组一样,array对象的长度固定,也使用栈(静态内存分配),而不是自由存储区.
头文件 array.
9.3 数组、vector和array的区别 。
无论是数组、vector对象还是array对象,都可使用标准数组表示法来访问各个元素.
从地址可知,array对象和数组存储在相同的内存区域(即栈)中,vector对象存储在自由存储区域或堆中.
可以将一个array对象赋给另一个array对象,对于数组,必须逐个元素复制数据.
Github地址:https://github.com/SolerHo/cpp-Primer-Plus-6e-Notes/blob/master/Chapter04/README.md 。
到此这篇关于C++ Primer Plus 第四章之C++ Primer Plus复合类型学习笔记的文章就介绍到这了,更多相关C++ Primer Plus复合类型内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://www.cnblogs.com/launolife/p/15063471.html 。
最后此篇关于C++ Primer Plus 第四章之C++ Primer Plus复合类型学习笔记的文章就讲到这里了,如果你想了解更多关于C++ Primer Plus 第四章之C++ Primer Plus复合类型学习笔记的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在实现一个显示容器级别的图表。根据填充水平,线条的颜色应该改变(例如,接近最大值时应该显示红色)。我不想计算线条的不同部分并手动设置它们的颜色,而是想定义一个颜色自动改变的带。我想用自定义 Com
#include int main(void) { int days, hours, mins; float a, b, c, total, temp, tempA, tempB; a
if()//first if { if()//second if statement; } else statement; 我知道 else 与第一个 if 匹配,但我的问题是为什么?我是
以下代码中测试了 Ready 的哪个实例,为什么? interface type TObject1 = class ... public property Ready: boole
我刚刚花了相当多的时间来寻找像这个 plunk 中的差距.问题没那么简单。这是一个动态创建的页面,一些具有 margin-bottom 的组件恰好显示在 .main 的最后。 在我指责 CSS 之前,
我的程序应该在对话中创建圆形图标。我有三个按钮,每个按钮代表要制作的图标的颜色。因此,如果我点击不同的按钮 10 次,我的程序应该创建 10 个不同颜色的圆圈。这是我的代码,分为 2 个类: impo
我读过; A compound literal is a C99 feature that can be used to create an array with no name. Consider
当您创建一个复合 View 并为其扩充 xml 布局文件时,如下所示: public class CompundLayout extends LinearLayout{...} 这会像这样用根扩展一个
我正在创建一个带有标签和文本框的复合 uibinder 小部件。 预期用途是: The text to be put in the box. 我找到了如何使用自定义 @UiConstruc
任何人都可以举一个结合使用设计模式组合和责任链的实际例子吗? 谢谢 最佳答案 一个非常实际的例子是 GUI 设计,例如 Qt 框架。 QObject 可以是单个对象或多个对象的组合。 QObjects
我在这个项目中的一些表单中使用了复合 View 模型的模式。它工作得很好。 在这种情况下,我有一个 VendorAddress View 模型。我在这个项目的几个地方使用了 Address(es),所
我正在尝试构建一个我认为需要多个 JOIN 的 SQL 查询,但我不知道语法。 这是每个表(带有列名)的粗略示例。 T1( key ,名称) T2(键,fkeyT1) T3(键,fkeyT2) 我想从
我有一个 Composite我希望能够以编程方式启用/禁用。 Control.setEnabled(boolean enabled)方法工作正常,但它没有提供任何小部件被禁用的视觉信息。 我想做的是让
如果子域不是“mobile”并且文件名不是“design”或“photo”,我想回显某些内容,因此 echo if (not“mobile”且不是“design”)或(not“mobile”而不是“照
我有一张有几列的 table 。第 1 列和第 2 列可以包含四个 alpha 值中的任何一个:set={A,B,C,D}。 我想检查每列是否包含集合中的两个值之一。所以我想简化这个陈述: SELEC
我创建了一个全局数据类型,并在页面中使用表单渲染器让用户填写数据并提交到网站。 默认的英语工作正常。现在,当我尝试支持第二种语言时,我遇到了问题。根据复合文档: 1.在 ~/Frontend/Comp
我需要将自定义对象作为值存储在字典中,例如具有两个复合整数键的 datastrukturer。 (复合 ID) 我尝试使用数组作为键,但两者都不起作用,因为我猜这只是指向该数组的指针,用作键 如果我能
版本:3.2.1 关系 表B中的两列与表A中的两列相关联。 表A-> hasMany->表B 表B->属于--表A B.a_id = A.a_id B.a_name = A.a_name 食谱 在食谱
我创建了一个全局数据类型,并在页面中使用表单渲染器让用户填写数据并提交到网站。 默认的英语工作正常。现在,当我尝试支持第二种语言时,我遇到了问题。根据复合文档: 1.在 ~/Frontend/Comp
当前版本的 Log4net 是否有办法创建具有复合滚动样式的 RollingFileAppender,其中滚动文件始终保留给定的扩展名(在我的情况下为 .log)? 我想要的格式示例: MyLog.l
我是一名优秀的程序员,十分优秀!