我们接着说C++指针相关的内容, 我们先看个代码, 看看数组遍历的几种方式
//定义一个长度是 7 的整数数组
int array[] = { 12, 56, 78, 96, 37, 86, 22 };
auto begin = std::begin(array);
auto end = std::end(array);
//auto end = array + 7;
std::cout << "begin 处的元素值为:" << * begin << std::endl;
std::cout << "begin + 1 处的元素值为:" << *(begin + 1) << std::endl;
std::cout << "array数组的长度为" << end - begin << std::endl;
std::cout << "采用for语句遍历数组" << std::endl;
for (auto data : array)
std::cout << data << std::endl;
std::cout << "begin 和 end 遍历数组" << std::endl;
for (auto it = begin; it != end; it++)
std::cout << *it << std::endl;
- 执行的结果如下
begin 处的元素值为:12
begin + 1 处的元素值为:56
array数组的长度为7
采用for语句遍历数组
12
56
78
96
37
86
22
begin 和 end 遍历数组
12
56
78
96
37
86
22
- 通过上面的代码我们看出C++中对数组的遍历可以有不同的方式, 第一种就是利用常见的for语句遍历, 这个就不多说了
- 第二种方式就比较有意思, 我们利用标准库当中的 begin 和 end 函数来取得array的首元素指针和 末尾元素指针的下一个位置指针, 注意这里不是末尾元素的指针, 而是末尾元素的下一个位置的指针。后面就跟昨天说的迭代器一样, 遍历整个数组
- 既然用 std::end() 函数是为了取得末尾元素的下一个元素的指针, 那么我们直接用首地址 + 7 不是也一样吗? 我们可以试一下, 结果是一样的, 但是这里不推荐这种写法, 因为非常容易出错。推荐使用 std::end() 取得末尾元素的下一个位置的指针。
我们在进行数组大小计算的时候直接拿两个指针相减, 得到的结果类型是一种 ptrdiff_t 的标准库类型, 和 size_t 一样, ptrdiff_t也是一种定义在cstddef头文件中的机器相关的类型,可以是负值。
- 我们应该也注意到指针是可以比较大小的, 例如下面的代码
auto n = std::end(array) - std::begin(array);
int *pt = array;
while(pt < std::end(array))
{
// do something
}
- 但是我们不应该比较不同类型的指针,否者编译器会报提示你不同类型指针不能比较大小, 如下代码所示
int a = 12;
float b = 30;
std::cout << (&a < &b) << std:::endl;
这个时候编译就会出现以下错误
错误(活动) E0042 操作数类型不兼容("int *" 和 "float *")
- 最后我们特别要注意的是我们利用 std::end() 获取到的指针是不能解引用的, 因为这个指针里面是没有有效数据的。