一. 数组
(1). 内存中对象的存储
C++环境下 向内存中存储对象 就像是 向弹夹里装子弹,压进去一个然后在压进去另一个,抓到哪个子弹装哪个,是无序的,而有时,我们需要有序的存储一组相同类型的对象,可以通过封装成某种结构体,也可以使用更简单(看上去是)的数组。
数组能实现有序的存储,是用了一个投机取巧的方法,就是将所有成员所需要的内存大小一起申请,然后一次“压”进内存
(2). 声明数组
因为数组是一次申请所有元素占用内存大小的总和
,所以在声明数组时,必须要确定其大小,要么说明数组有几个什么类型的元素,要么直接告诉数组要存储的元素是什么
int
array01[] = {1,2,3};
int
array02[3] = {};
(3). 访问数组元素
C++可以使用一种叫做下标(有些书上叫索引)的东西访问数组的元素,下标 以 0 表示数组的第一个元素,1表示第二个元素,n表示数组的第n个元素(如果它存在的话)
int array01[] = {10,20,30};
cout << array01[0]; //10
cout << array01[1]; //20
cout << array01[2]; //30
"猥琐"点的现在就会想,如果再向后读一个int长度(
array01[2+1] )会怎样?
好吧,它会非常老实的向后再读取一个int长度的内存并显示其值,有99.9的可能该内存区间保存的并不会是一个int,即便是int这个值对我们来说也毫无意义。 奇妙的是 即便这样超出索引调用其他对象的内容编译器也不会报错。
(4). 指针运算
数组名默认引用数组的第一个元素, 当使用下标引用元素时, 实际上它会按照如下的公式进行计算
- 变量名(保存的首元素地址)+ 下标 * 元素类型长度
即便我们使用下标获取 第一个元素 array[0] , 也会按照上边的公式计算(假设为 int 类型数组 / 32位处理器)
- array首元素地址 + 0 * 4
这种直接操作内存地址 恰恰是指针所具备的功能, 实际上 在C++语言级,当使用下标引用元素时,可以将其看成是指针。
既然是指针,那假设有两个变量 a,b 可不可以在已知变量 a 的地址,和两个变量地址差值 ,通过运算让指针正确的指向 b ?,当然是可以的, 但这样做危险且实际意义不大
int
a = 10,b = 10086;
int
x = ((
int
)&a) - ((
int
)&b);
int
*p = &a;
int
k = (x/4);
cout <<
"变量 | b="
<< b <<
" , 变量地址:"
<< &b << endl;
cout <<
"指针 | b="
<< *(p-k) <<
" , 指针指向:"
<< (p-k) << endl;
虽然在语言级,下标具有指针的特性,但本质上两个是不同的东西, 这点 一定要明确。
(5). 数组的边界检查
const
int
array_size = 3;
int
array01[array_size] = {11,22,33};
for
(
int
i =0; i < array_size; i++)
{
cout << array01[i] << endl;
}
或许你已经想到了另一种获取数组元素个数的方法,对咧~ 就是 "先称了一个,又称了一堆,做了个除法~"
const
int
array_size =
sizeof(array01)/
sizeof
(
int );
[sizeof()用于过去类型大小]
二. 字符串
(1). 字符 和 字符数组
当我们输入并显示字符, 计算机做了如下工作:
- 查看我们输入的数字(没错是数字),再根据输入的数字在"字典中"找到并显示对应的某个字符的矢量图
[ 要进一步了解计算机如何显示文字,可以读这篇文章,顺便告诉我美人鱼你选A还是B ]
充当"字典"的最早叫 ASCII码表, ASCII的映射条目数只有127个。由于映射条目数太少, 很多语言肯定表示不了(如中文),于是就出现了 Unicode。
根据 Unicode 陆续出了很多版本的编码 如 UTF-8(变长), UTF-16 , UTF-32,可以映射的条目越来越多,对应的 每个字符占用的空间越大,
UTF-8是变长编码,既字符可以占一个字节,也可以是两个或三个字节。利于网络传输,因为它不会像定长编码( 如 UTF-16 每个字符固定占两个字节 ),一旦传输中丢了一个字节数据,后边的文字都会悲剧(乱码)。
C++ 中用 char(一个字节)表示 ,用 wchar_t(两个字节) 来表示 Unicode(一般为UTF-16)。
[Java中 char 是两个字节,Linux下wchar_t是四个字节,对应utf-32
]
(2). 字符串
由于字符串都是变长的(天知道你要写多少个字),所以 C/C++ 用一个特殊的字符“\0”来标识字符串结束位。
(3). 字符数组
字符数组就是其元素为表示字符类型的数组,这个没什么好说的,只是注意一点。当使用 字面值字符串常量 来初始化字符串时,末尾会有 字符串结束标记“\0”
char
array01[] =
"hello"
;
const
int
array_size =
sizeof
(array01)/
sizeof
(
char);
cout << array_size << endl;
// 6
(4). 指向 字面值字符串常量 的指针
当如下声明一个指针时,
char
*p =
"hello"
;
直接编译会报错,编译器非要你将指针设置为常量指针才罢休。其实 当
指针指向
字面值字符串常量时,而该字符串会存储在 运行环境中一个叫 只读存储区 的内存空间里,该区域的内容均不能修改。所以 *p也就变成了前边说过的 指向常量的非常量指针
char
const
*p =
"hello";
(5). string
C++中,将 传统的字符串封装成了一个新的类型 string,该类型提供了很多函数可以很方便的操作字符串,具体可以
看这里 。
[ Java,C# 中直接 string设置为内置类型,其在语言级就是字符串,并且是不可变的 ]
-
<原创文章 转载请注明出处 http://blog.youkuaiyun.com/meiwm 谢谢>
出处:
http://blog.youkuaiyun.com/meiwm
本文为原创,本文版权归作者所有。欢迎转载,但请务必保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。
-