C++学习笔记(四)——数组和指针

第四章、数组和指针

4.1 、数组

1、 数组定义中的类型名可以是内置类型或类类型; 除引用之外 ,数组元素的类型还可以是任意的复合类型。

2、 如果没有显式的提供元素初始值,则数组元素会像普通变量一样初始化:

(1) 在函数体外定义的内置数组( 元素为内置类型 ) ,其元素均初始化为 0

(2) 在函数体内定义的内置数组,其元素无初始化

(3) 、不管数组在哪里定义,如果元素是类类型,则自动 调用该类的默认构造函数 进行初始化; 如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化

3、 不允许数组直接复制或赋值。

4、 数组的下标类型是size_t 类型。

4.2、指针

1、 指针是指向某种类型对象的符合数据类型,是 用于数组的迭代器 :指向数组中的第一个元素。 指针保存的是另一个对象的地址

2、 "&"是取地址操作符, string s("Hello World!");&s 可以获得 s 的存储地址。 取地址操作符只能用于左值( 左值可以出现在赋值语句的左边或右边,右值只能出现在右边 )

3、 String* p1, p2;    //p1为指针, p2 为普通字符串变量

4、 有效的指针有以下三种状态之一:保存一个对象的地址;指向某个对象后面的另一个对象;或者是0 值 ( 表明它不指向任何对象 ) 。 未初始化的指针是无效的

5、  除非所指向的对象已经存在,否则不要先定义指针;如果必须分开定义指针和其所指向的对象,则将指针初始化为0

6、 把int 型变量赋给指针是非法的,尽管此 int 型变量的值可能为 0 。但 允许把数值0 或在编译时可获得 0 值的 const 量赋给指针 。此外,还可以用预处理器变量NULL 对指针进行初始化,其效果和 0 值一样

7、 void*指针: void* 表明该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。 不允许使用void* 指针操纵它所指向的对象

8、 *操作符可以获取指针所指向的对象,可以用来修改指针所指向对象的值。 如果对左操作数进行解引用,则修改的是指针所指对象的值;如果没有使用解引用操作,则修改的是指针本身的值

9、 指向指针的指针:使用** 操作符指派一个指针指向另一个指针。

10、 在表达式中使用数组名时,该名字会自动转化为指向数组第一个元素的指针

11、 指针的算术操作:

(1)、 指针的算术操作只有在原指针和计算出来的新指针都指向同一个数组的元素,或指向该数组存储空间的下一单元时才是合法的 。如果指针指向一对象,还可以在指针上加1 从而获取指向相邻的下一对象的指针;

(2)、 只要两个指针指向同一数组或有一个指向该数组末端的下一单元 ,还可以对两个指针进行减法操作。 其结果是标准库类型ptrdiff_t 的数据,表示两指针之间的差距

(3)、 size_t类型用于指明数组长度,必须是一个正数; ptrdiff_t 类型则应保证足以存放同一数组中两个指针的差距,它有可能是负数

(4)、允许在指针上加减 0 , 使指针保持不变 空指针( 具有 0 值 ) 加 0 是合法的,结果得到另一个值为 0 的指针

12、 int array[] = {0,2,4,6,8};

int *p = &array[2];    //指向 array[2]

int j = p[1];           //p[1]即为 array[3]

int k = p[-2];          //p[-2]即为 array[0]

使用下标访问数组时,实际上是对指向数组元素的指针做下标操作 ;只要指针指向数组元素,就可以对它进行以上操作。

13、 数组的超出末端指针: C++允许计算数组或对象的超出末端的地址,但 不允许对此地址进行解引用操作 计算数组超出末端位置之后或数组首地址之前的地址都是不合法的

14、 指针是数组的迭代器。

15、 指向const 对象的指针:

(1) 、如果指针指向const 对象,则不允许用指针来改变其所指向的 const 值, C++ 语言强制要求指向 const 对象的指针也必须具有 const 特性。

(2) 、const double *point; 其中 point 本身并不是 const ,在定义时不需要初始化,并且可以改变它指向的对象。但是 指针指向的对象的值不能改变

(3) 不允许把一个const 对象的地址赋给一个非 const 对象的指针,但可以把一个非 const 对象的地址赋给指向 const 对象的指针 ( 尽管此时const 指针指向的是非 const 对象,但还是不能通过指针修改对象的值 )

(4) 不能使用void* 指针保存 const 对象的地址,必须用 const void* 类型的指针保存 const 对象的地址

(5) 、可以把指向const 的指针理解为“自以为指向 const 的指针”,因为它既可以指向 const 对象,也可以指向非 const 对象。

16、 const指针:

(1) 、const 指针必须在定义时初始化,而且它所指向的对象不能改变,但是它指向的对象的值可以改变 ( 前提是该对象是非 const 对象 ) 。

(2) 指向const 对象的 const 指针 :既不能修改指针指向的对象,也不能修改指针指向对象的值。

(3) 、typedef string *pstring;         const pstring cstring; 其中cstring  是指向 string 类型对象的 const 指针。 ( 相当于 string  * const cstring;) 。

4.3、 C 风格字符串

1、 C风格字符串 (cstring) 是 以空字符null 结束的字符数组

2、 C风格字符串的相关操作:

(1) 、strlen(s) :返回 s 的长度,不包括字符串结束符 null ;

(2) 、strcmp(s) :比较两个字符串 s1 和 s2 是否相同。若相等则返回 0 ,若 s1 大于 s2 则返回正数,若 s1 小于 s2 则返回负数;

(3) 、strcat(s1,s2) :将字符串 s2 连接到 s1 后,返回 s1 ;

(4) 、strcpy(s1,s2) :将 s2 复制给 s1 ,返回 s1 ;

(5) 、strncat(s1,s2,n) :将 s2 的前 n 个字符连接到 s1 后,返回 s1 ;

(6) 、strncpy(s1,s2,n) :将 s2 的前 n 个字符复制给 s1 ,返回 s1 ;

3、 传递给标准库函数strcat 和 strcpy 的第一个实参数组必须有足够大的空间存放新生成的字符串。

4、 动态数组:

(1) 、用于存放 动态分配的对象 的内存空间称为程序的 自由存储区(free store) 或堆 (heap) 。C 语言用标准库函数 malloc 和 free 在自由存储区分配存储空间,而 C++ 用 new 和 delete 实现;

(2) 、定义动态数组:int *array = new int[10];( 未初始化 ) , 在自由存储区中创建的数组对象是没有名字的,只能通过地址间接地访问

(3) 、动态数组的初始化: 如果数组元素是类类型,将使用该类的默认构造函数进行初始化;如果是内置类型,则无初始化

(4) 、可使用跟在数组长度后面的一对空圆括号对数组元素进行初始化:int *array = new int[10](); 对于动态分配的数组, 其元素只能初始化为元素类型的默认值,不能像数组变量一样用初始化列表为数组元素提供不同的初值

(5) 、const 对象的动态数组 ( 用处不大 ) :必须为这种数组进行初始化,允许定义类类型的 const 数组,但是该类必须有默认的构造函数;

(6) C++不允许定义长度为 0 的数组,但可调用 new 动态创建长度为 0 的数组

(7) 、释放动态数组时千万别忘了方括号对。

5、 混合使用标准库类string 和 C 风格字符串:

(1) C风格字符串和字符串字面值具有相同的数据类型,且都是以空字符 null 结束, 因此可以把C 风格字符串用在任何可以使用字符串字面值的地方;

(2) 、在要求用C 风格字符串的地方不可直接使用标准库 string 类型对象,但可以通过成员函数 c_str 来实现; c_str返回的指针指向 const char 类型的数组 :const char *string = string2.c_str();

(3) 、c_str 返回的数组并不一定是有效的,接下来 对string2 的操作有可能改变 string2 的值,使返回的数组失效 ;如果想持续访问该数组则应该复制c_str 函数返回的数组。

6、 使用数组初始化vector 对象,必须指出用于初始化式的第一个元素和数组最后一个元素的下一个位置的地址:

const size_t arr_size = 6;

int int_array[arr_size] = {0,1,2,3,4,5};

vector<int> vector(int_array, int_array + arr_size );

4.4、多维数组

1、 多维数组的初始化:int array[2][3] = {{1,2,3},{4,5,6}}; 该初始化式等同于 int array[2][3] = {1,2,3,4,5,6}; 只初始化每行的第一个元素:int array[2][3] = {{0},{4}}; 其余元素的初始化与一维数组一样;如果省略内嵌的大括号,结果会完全不同: int array[2][3] = {0,4,8}; 该声明初始化了第一行的元素,其余元素被初始化为 0

2、 指针和多维数组: 多维数组是数组的数组,所以由多维数组转换而成的指针类型应该是指向第一个内层数组的指针 ;下面是这种指针的声明方法:

int array[3][4];

//圆括号必不可少 ,int *point[4]; 表示整型指针的数组;

int (*point)[4] = array; //表示指向整数数组的指针

point = &array[2];

3、 用typedef 简化指向多维数组的指针:

typedef int int_array[4];

int_array *point = array;

(未完待续)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值