C++ 学习笔记 数组指针

数组的指针用法:
例如:
string nums[] = {"one","two","three"};
string *p = nums 等价于 string *p = &nums[0];
都是将指针指向第一个元素。
数组有一个特性,就是在很多地方用到数组名字的地方时,编译器会自动的将其替换成指向数组第一个元素的指针。

int a[] = {1,2,3,4,5,6,7,8,9};
auto a1(a);
以上的表达式中,a1的类型是指针而不是数组,其中 auto a1(a) 含义是的声明一个指针并指向数组a的第一个元素。故a1 = 1 这种赋值类型在上述表达式中自然错误。
如果 int a[] 不变 auto a1(&a[1]); 此时 a1的类型就只是一个 int 类型的指针。

指针也是迭代器:
例:
int arr[] = {1,2,3,4,5,6,7,8,9};
int *p = arr;// 之前提到过此时p指向arr[0]
++p; // p指向arr[1];
使用指针也可以遍历整个数组,这样做需要先获得指向数组的第一个指针和指向下一个元素的指针。 int *end = &a[9];//此时end 就是数组arr的尾指针。

在C++ 11 的标志函数库中,两个函数begin 和 end
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int *head = begin(arr); // 此时head 指向 arr 第一个元素
int *end = end(arr);//此时end 指向 arr 尾元素的下个位置的指针
由于begin 和 end 两个函数的存在,遍历数组变的更为容易了。(笑)

指针运算
例:
constexpr size_t sz = 5;
int arr[sz] = {1,2,3,4,5};
int *p = arr;
int *p2 = p +4;
上述表达式中,*p 是指向 arr[0];p+4所得的结果仍是一个指针,只不过是只不过是想和p相比向前进了4个位置。所以int *p = p+4 等价于 int *p = &arr[0+4];
int *p = arr + sz;// 使用警告
int *p2 = arr +10;// 报错
前者 在编译时 使用arr 会自动指向arr的一个元素,然后向后平移5位,起到了和 end 函数一样的效果。也就是说p指向了arr尾元素的下一个元素,但是超出这个范围编译器就会报错,但是刚好指向尾元素的下一位。
例:
int arr[ ] = {1,2,3,4,5};
int *b = arr;
int *e = arr+arr.length;(注:这里为了方便,用arr.length表示arr的长度)
while(b<e){
//do
++b;
}
这里需要注意的是 指针 b 和 e 指向的是 同一对象,所以可以比较;不同对象的指针是不无法进行比较的。
例:
int arr[ ] = {1,2,3,4,5};
int a = *(arr+4);//正确,a = arr[4]的值 也就是5
int b = *arr + 4;//正确,需要注意的是这个时候b = arr[0] + 4;

数组的下标和指针:
例:
int arr [] = {1,2,3,4,5};
int *p = &arr[2];
int j = p[1] //等价于 int j = arr[2+1];
int i = p[-1] //等价于 int i = arr[2-1]
标准库类型string 和 vector 类型也能执行下标运算,但是数组和它们还是有一些区别的,在标准库中的函数的下标必须是无符号类型,而内置的下标却没有这个要求。

猜你喜欢

转载自blog.csdn.net/yushu1995/article/details/78688378