C++ Primer 读书笔记 数组和指针

本文详细介绍了数组的基本概念,包括数组的定义、初始化及多维数组的使用,并深入探讨了指针的概念及其与数组的关系。此外,还讲解了C风格字符串的处理方式以及如何创建动态数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

数组

 

数组是由类型名、标识符和维数组成的复合数据类型。类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数。数组的维数必须用值大于等于1的常量表达式定义,在定义数组时,可为其元素提供一组用逗号分隔的初值,这些初值用花括号{}括起来,称为初始化列表。如果是字符数组,既可以用初始化列表初始化,也可以用一个字符串字面值进行初始化。

vector元素一样,数组元素可用下标操作符来访问,数组元素也是从0开始计数,数组下标的类型是size_t

 

指针

 

指针是指向某种类型对象的复合数据类型,是用于数组的迭代器:批向数组中的一个元素。与迭代器不同的,指针用于指向单个对象,而迭代器只能用于访问容器内的元素。每个指针都有一个与之关联的数据类型,该数据类型决定了指针所指向的对象的类型。C++语言中,使用*符号把一个标识符声明为指针:

int *ip, *ip2;              // 指针ipip2都是指向int类型对象的指针

string  *pstring;     // pstring是指向string类型对象的指针

 

一个有效的指针,必然是以下三种状态之一:

1、  保存一个特定对象的地址。

2、  指向某个对象后面的另一对象。

3、  0值。

对指针进行初始化或赋值,只能使用以下四种类型的值:

(1)     0值常量表达式

(2)     类型匹配的对象的地址

(3)     另一个对象之后的下一个地址。

(4)     同类型的另一个有效指针

 

C++提供了一种特殊的指针类型void*,它可以保存任何类型对象的地址。

Void指针只支持几种有限的操作:与另一个指针进行比较;向函数传递void*指针或从函数返回void*指针;给另一个void*指针赋值。不允许使用void*指针操纵它所指向的对象。

C++语言中,数组的名字自动指向数组第一个元素的指针。指针也可以进行算术操作,指针的算术操作和迭代器的算术操作以相同的方式实现。使用指针的算术操作在指向数组某个元素的指针上加上(或减去一个整形数值),就可以计算出指向数组另一元素的指针值。

比较难理解的就是指针和const限定符。如果指针指向const对象,则不允许用指针改变其所指向的const值。为了保证这个特性,C++语言强制要求指向const对象的指针也必须具有const特性。把一个const对象的地址赋给一个普通的、非const对象的指针会导致编译时的错误。但是可以把非const对象的地址赋给指向const对象的指针。我们可以把指向const对象的指针看成const_iterator。而const指针,其本身的值不能修改,可以理解为const iterator,可以修改其指向的对象。

 

C风格字符串

 

C风格字符串是以空字符null结束的字符数组。C++语言通过char *类型的指针来操纵C风格字符串。

下面是一些操纵C风格字符串的标准库函数:包含在头文件cstring

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

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

strcat(s1, s2) 将字符串s2连接到s1后,并返回s1

strcpy(s1, s2)   s2复制给s1,并返回s1.

strncat(s1, s2, n)     s2的前n个字符连接到s1后面,并返回s1

strncpy(s1,s2, n)      s2的前n个字符复制给s1,并返回s1

这些函数将假定它们所修改的字符串具有足够大的空间接收本函数新生成的字符。

 

创建动态数组

 

动态分配数组时,只需要指定类型和数组长度,不必为数组对象命名,new表达式返回指向数组的第一个元素的指针

Int *pia = new int[10];

动态分配的内存最后必须进行释放。如果不再需要使用动态创建的数组,程序员必须显式地将占用的存储空间返还给程序的自由存储区:

Delete [] pia;

 

混合使用标准库类stringC风格字符串

由于C风格字符串与字符字面值具有相同的数据类型,而且都是以空字符null结束,因此可以把C风格字符串用在任何可以使用字符串字面值的地方:

string对象进行初始化或赋值。

String类提供了一个名c_str的成员函数,返回C风格字符串。

 

使用数组初始化vector对象

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

const size_t arr_size = 6;

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

vector<int> ivec(int_arr, int_arr + arr_size);

被标出的范围可以是数组的子集。

 

多维数组

 

多维数组其实就是数组的数组。

初始化:

显式初始化所有的元素

int ia[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};

只初始化每行的第一个元素:

int ia[3][4] = {{0},{4},{8}};  //在这里,其它元素默认初始化为0

只初始化第一行

int ia[3][4] = {0,1,2,3};

当需要访问数组中特定元素时,必须提供其行下标和列下标。行下标指出需要哪个内部数组,列下标则选取该内部数组的指定元素。

 

指针和多维数组

因为多维数组其实就是数组的数组,所以由多维数组转换而成的指针类型应是指向第一个内层数组的指针。

int ia[3][4];

int (*ip)[4] = ia;

ip = &ia[2];

使用typedef简化指向多维数组的指针

typedef int int_array[4];

int_array *ip = ia;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值