Java程序员的C++回归路 (5)

在c++的for循环中,经常使用!=来替代java中的<=作为判断是否跳出循环,这个是因为在c++的标准库中,很多的容器类提供了!=的运算符而没有<运算符,而很多时候又使用iterator来遍历容器。

迭代器类型

如size_type一样,我们一般不关心迭代器的具体类型。可以是iterator或者const_iterator。

使用新标准中提供的cbegin()和cend(),返回const类型的iterator

Dereference和member

以(*iter).empty为例,*iter的括号是必须的。如果没有括号的话将会被解析为iter.empty member,而iter是一个迭代器没有empty member。

于此同时,c++中提供了->运算符,这个就等于(*it).

使用iterator的不能使用iterator.add()来添加元素到容器中。

vector和string提供了额外的操作,如下表所示:

Java程序员的C++回归路

使用iterator的减法返回有符号数类型的difference_type

值得注意的是,迭代器只定义了减法运算而没有加法运算。

Array

字符数组

由于字符串由'\0'结束,所以在初始化char型数组时需要比字面量空间更大。

数组的初始化必须是一个初始化列表,不能用一个数组给另一个数组赋值,如下:

int[] a = {1, 2, 3};
int[] a2 = a;  // Error,不能使用数组赋值

复杂的数组声明

int (*Parray)[10] = &arr; // Parray是一个指针,指向大小为10的数组,数组类型为int

int (&arrRef)[10] = arr; //arrayRef是一个引用,引用的对象是一个大小为10的int类型的数组

在理解复杂的数组声明时,使用由内而外的理解方法去理解。

Eg: int *(&array)[10] = ptrs; // array是一个引用,引用的对象是10个int类型的指针(Reference to an array of ten pointers)

通过下标访问数组

通常使用sizt_t类型来定义数组的长度。

数组和指针

一般情况下,我们使用数组,编译器会自动将指针指向数组的第一个元素。

string nums[] = {"1", "2", "3"};
string *p = &nums[0];
string *p2 = nums;  //equivalent to p2 = &nums[0]

使用auto和decltype的类型:

int ia = [1, 2, 3];
auto ia2(ia2);
auto ia2(&ia[0]);  // ia2的类型是int*

C++11中引入了新的获取起始指针和尾指针的函数:begin()和end(),包含在iterator header

两个指针相减的结果是ptrdiff_t,类似于size_t,定义在cstddef header中。

可以使用指针来操作数组,参照如下例子:


int *p = &ia[2]; // p points to the element indexed by 2
int j = p[1];  // p[1] is equivalent to *(p+1)
int k = p[-2]; // equivalent to ia[0],可以使用减法指向之前的元素

内建的数组下标可以是负数,而vector等类型的下标必须是无符号数

c语言中的string

在c标准库中定义了一种字符串的convention,以'\0'结尾,定义在<string.h>中(对应c++中的cstring)

并且c标准库中提供的函数并不会校验传入的字符数组是否合法,这可能会引发一些问题。

对于指针来说,如果指针指向的不是同一个对象,那么指针之间的比较就没有意义。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzpps.html