打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
第一部分 基础语言之三数组和指针
3.1 数组

如果没有显式提供元素初值,则数组元素会像普通变量一样初始化(第 2.3.4节):
· 在函数体外定义的内置数组,其元素均初始化为 0。
· 在函数体内定义的内置数组,其元素无初始化。
· 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初    始化;如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。

特殊的字符数组
char ca1[] = {'C', '+', '+'}; // no null
char ca2[] = {'C', '+', '+', '\0'}; // explicit null
char ca3[] = "C++";  // null terminator added automatically

3.1.1 数组操作
与 vector 元素一样,数组元素可用下标操作符(第 3.3.2 节)来访问,数组元素也是从 0 开始计数。对于一个包含 10 个元素的数组,正确的下标值是从 0 到 9,而不是从 1 到 10。
在用下标访问元素时,vector 使用 vector::size_type 作为下标的类型,而数组下标的正确类型则是 size_t(第 3.5.2 节)。

3.2 指针

3.2.1 指针的定义和初始化
指针可能的取值
一个有效的指针必然是以下三种状态之一:保存一个特定对象的地址;指向某个对象后面的另一对象;或者是0 值。若指针保存0 值,表明它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可使用它。下列定义和赋值都是合法的:

指针初始化和赋值操作的约束
对指针进行初始化或赋值只能使用以下四种类型的值:
1. 0 值常量表达式,在编译时可获得 0 值的整型 const对象或字面值常量 0。
2. 类型匹配的对象的地址。
3. 另一对象末的下一地址。
4. 同类型的另一个有效指针。


3.2.2 指向const的指针和const指针
如果指向 const 的指针所指的对象并非 const,则可直接给该对象赋值或间接地利用普通的非 const 指针修改其值:毕竟这个值不是 const。重要的是要记住:不能保证指向 const 的指针所对象的值一定不可修改。
如果把指向 const 的指针理解为“自以为指向 const 的指针”,这可能会对理解有所帮助。
在实际的程序中,指向 const 的指针常用作函数的形参。将形参定义为指向 const 的指针,以此确保传递给函数的实际对象在函数中不因为形参而被修改。(有时使用const 引用)
const 指针与任何 const 量一样,const 指针也必须在定义时初始化。
还可以定义指向const 对象的 const 指针

指针和 typedef
在 typedef(第 2.6 节)中使用指针往往会带来意外的结果。下面是一个几乎所有人刚开始时都会答错的问题。假设给出以下语句:
typedef string *pstring;
const pstring cstr;
注意上例中,const修饰的是pstring本身,所以这是一个指向string的const指针,而不是一个指向const string的指针。

3.3 C风格字符串
实际上,C 风格字符串既不能确切地归结为 C 语言的类型,也不能归结为 C++ 语言的类型,而是以空字符 null 结束的字符数组:
char ca1[] = {'C', '+', '+'}; // no null, not C-style string
char ca2[] = {'C', '+', '+', '\0'}; // explicit null
char ca3[] = "C++"; // null terminator added automatically
const char *cp = "C++"; // null terminator added automatically
char *cp1 = ca1; // points to first element of a array, but not C-style string
char *cp2 = ca2; // points to first element of a null-terminated char array
ca1 和 cp1 都不是 C 风格字符串:ca1 是一个不带结束符 null 的字符数组,而指针 cp1 指向 ca1,因此,它指向的并不是以 null 结束的数组。其他的声明则都是 C 风格字符串,数组的名字即是指向该数组第一个元素的指针。于是,ca2 和 ca3 分别是指向各自数组第一个元素的指针。
 C 风格字符串的标准库函数 
永远不要忘记字符串结束符 null
int len = strlen(s); //求出的len并不包含最后的 '\0' ,所以复制是注意len+1才能存储该C-Style字符串

使用数组初始化vector 对象
使用数组初始化 vector 对象,必须指出用于初始化式的第一个元素以及数组最后一个元素
的下一位置的地址:
const size_t arr_size = 6;
int int_arr[arr_size] = {0, 1, 2, 3, 4, 5};
// ivec has 6 elements: each a copy of the corresponding element
in int_arr
vector<int> ivec(int_arr, int_arr + arr_size);

传递给 ivec 的两个指针标出了 vector 初值的范围。第二个指针指向被复制的最后一个元素之后的地址空间。被标出的元素范围可以是数组的子集:
// copies 3 elements: int_arr[1], int_arr[2], int_arr[3]
vector<int> ivec(int_arr + 1, int_arr + 4);
这个初始化创建了含有三个元素的 ivec,三个元素的值分别是 int_arr[1] 到int_arr[3] 的副本。

3.4 多数组

多维数组的初始化
和处理一维数组一样,程序员可以使用由花括号括起来的初始化式列表来初始化多维数组的元素。对于多维数组的每一行,可以再用花括号指定其元素的初始化式:
int ia[3][4] = { /* 3 elements, each element is an array of size4 */
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
    };
其中用来标志每一行的内嵌的花括号是可选的。下面的初始化尽管有点不清
楚,但与前面的声明完全等价:
// equivalent initialization without the optional nested braces for each row
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
与一维数组一样,有些元素将不使用初始化列表提供的初始化式进行初始
化。下面的声明只初始化了每行的第一个元素:
// explicitly initialize only element 0 in each row
int ia[3][4] = {{ 0 } , { 4 } , { 8 } };
如果省略内嵌的花括号,结果会完全不同:
// explicitly initialize row 0
int ia[3][4] = {0, 3, 6, 9};
该声明初始化了第一行的元素,其余元素都被初始化为 0。

3.4.1. 指针和多维数组

因为多维数组其实就是数组的数组,所以由多维数组转换而成的指针类型应是指向第一个内层数组的指针。尽管这个概念非常明了,但声明这种指针的语法还是不容易理解:
int ia[3][4]; // array of size 3, each element is an array of ints of size 4
int (*ip)[4] = ia; // ip points to an array of 4 ints
ip = &ia[2]; // ia[2] is an array of 4 ints
在下面的声明中,圆括号是必不可少的:
int *ip[4]; // array of pointers to int
int (*ip)[4];      // pointer to an array of 4 ints
用 typedef 简化指向多维数组的指针typedef 类型定义(第 2.6 节)可使指向多维数组元素的指针更容易读、写和理解。
typedef int int_array[4];
int_array *ip = ia;




本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C#交错数组
二维数组
简单总结C语言中各种类型的指针的概念
C语言之指针与数组
直方图
指针
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服