C++学习笔记6:数组

补充C++基础笔记。

数组

数组和vector
相同之处:也是存放类型相同的对象的容器,这些对象本身没有名字,需要通过其所在位置访问。
不同之处:数组的大小确定不变,不能随意向数组中增加元素。

定义和初始化内置数组:维度已知

  1. 定义
unsigned cnt = 42;   //不是常量表达式
constexpr unsigned sz = 42;   //常量表达式
int arr[10];   //含有10个整数的数组
int *parr[sz];   //含有42个整数指针的数组
string bad[cnt];   //错误:cnt不是常量表达式
  1. 初始化
const unsigned sz = 3;
int ial[sz] = {0, 1, 2};   //3个元素的数组
int a2[] = {0, 1, 2};   //维度是3的数组
int a3[5] = {0, 1, 2};   //等价于a3[] = {0, 1, 2, 0, 0}
string a4[3] = {"hi", "bye"};   //等价于a4[] = {"hi", "bye", ""}
  1. 字符数组:使用字符串初始化时,字符串字面值的结尾处有一个空字符,会被拷贝进去
char a1[] = {'C', '+', '+'};   //列表初始化,没有空字符
char a3[] = "C++";   //自动添加表示字符串结束的空字符
  1. 注意:不能将数组的内容拷贝到其他数组作为初始值,也不能用数组为其他数组赋值
  2. 更复杂的数组声明–指针和引用
int *ptrs[10];   //ptrs是含有10个整型指针的数组
int &refs[10] = /*?*/;   //错误:不存在引用的数组
int (*Parray)[10] = &arr;   //Parray指向一个含有10个整数的数组
int (&arrRef)[10] = arr;   //arrRef引用一个含有10个整数的数组

int *(&arry) [10] = ptrs;   //arry是数组的引用,该数组含有10个指针
  1. 一个小例子
string sa[10];   //sa中有10个""
int ia[10];   //ia中有10个0
int main() {
	string sa2[10];   //sa2中有10个""
	int ia2[10];   //ia2中10个未定义元素 -- 内置变量
//和内置类型的变量一样,如果在函数内部定义了某种内置类型的数组,那么默认初始化会令数组含有未定义的值
}

访问数组元素

  1. 与标准库类型vector和string一样,数组的元素也能使用范围for语句或下标运算符来访问 -> 数组除了大小固定这个特点外,其他用法与vector基本类似。
  2. 在使用数组下标的时候,要将其定义成size_t类型。

指针和数组

  1. 使用取地址符可以获取指向某个对象的指针 + 数组也是对象 -> 对数组的元素取地址符就能得到指向该元素的指针。
string nums[] = {"one", "two", "three"};   //数组的元素是string对象
string *p = &nums[0];   //p指向nums的第一个元素
string *p2 = nums;   //等价于p2 = &nums[0]

auto的情况

int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};   //ia是一个含有10个整数的数组
auto ia2(ia);   //ia2是一个整数指针,指向ia的第一个元素

–> 实际上,在大多数表达式中,使用数组类型的额对象其实是使用一个指向该数组首元素的指针。

decltype(ia) ia3 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ia3 = p;   //错误:不能用整型指针给数组赋值
ia2[4] = i;   //正确:把i的值赋给ia3的一个元素
  1. 指针也是迭代器:支持vector和string的迭代器支持的全部运算
    小例子:输出数组arr的全部元素
for (int *b = arr; b != e; ++b)
	cout << *b << endl;
  1. C++11新标准:begin和end两个函数
    数组不是类 -->> 这两个函数不是成员函数
    小例子:找出arr中的第一个负数
int *pbeg = begin(arr),  *pend = end(arr);  //pbeg指向arr的首元素,pend指向arr尾元素的下一位置
while (pend != pend && *pend >= 0)
	++pbeg;

注意:尾后指针不能执行解引用和递增操作

  1. 指针运算:解引用、递增、比较、与整数相加、两个指针相减
    相减的结果:一种名为ptrdiff_t的标准库类型[定义在cstddef头文件中的机器相关的类型] -> 是一种带符号类型
  2. 下标和指针
int ia[] = {0, 2, 4, 6, 8};
int i = ia[2];   //ia转换成指向数组首元素的指针,ia[2]得到(ia + 2)所知的元素

int *p = &ia[2]//p指向索引为2的元素
int j = p[1];   //p[1]等价于*(p + 1), 就是ia[3]所表示的那个元素
int k = p[-2];   //p[-2]是ia[0]表示的那个元素

–> 内置的下标运算符的索引值不是无符号类型,这一点与vector和string不同

多维数组:数组的数组

  1. 处理多维数组的小例子
    方式一:
constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt];
for (size_t i = 0; i != rowCnt; ++i) {
	for (size_t j = 0; j != colCnt; ++j) {
		ia[i][j] = i * colCnt + j;
	}
}

方式二 – C++11新增了范围for语句:

constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt];
for (auto &row : ia)
	for (auto &col : row) {
		col = cnt;
		++cnt;
}

–> 要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值