HR's Blog

Swimming 🏊 in the sea🌊of code!

0%

指针

.

指针(pointer)是“指向(point to)”另外一种符合类型。与引用类似,指针也实现了对其他对象的间接访问。

指针与引用的区别:
其一:指针本身就是一个对象,允许指针复制和拷贝,而在指针的生命周期内可以先后指向几个不同的对象。
其二:指针无须在定义时初始值。

和其他内置的类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

指针的定义

1
2
3
4
5
6
7
8
9
10
11
12
//定义
int *ip1, *ip2;
double dp, *dp2;

//获对象地址(取地址符&)
int ival =42;
int *p = &ival;

// 利用指针访问对象
int ival = 42;
int *p = &ival;
count << *p;

指针的四种状态

  1. 指向一个对象
  2. 指向紧邻对象所占空间的下一个位置
  3. 空指针,意味着指针没有指向任何对象。
  4. 无效指针,也就是上述的情况之外的其他值。(一般都是没有初始化的指针,指向一个垃圾值)

试图拷贝或以其他方式访问无效指针的值都将引发错误。
访问空指针和无效指针的后果是无法预计的。

指针 vs 对象

指针可以降低传输大数据时候的花销。
指针可以修改自己所指的对象(相同的类型)。
但是指针在使用前要更加小心,因为有可能会指向nullptr,而直接使用对象就不会有这样的问题。

A pointer allows us to pass potentially large amounts of data around at low cost: instead of copying the data we simply pass its address as a pointer value. The type of the pointer determines what can be done to the data through the pointer. Using a pointer differs from using the name of an object in a few ways:

  1. We use a different syntax, for example, ∗p instead of obj and p−>m rather than obj.m.
  2. We can make a pointer point to different objects at different times.
  3. We must be more careful when using pointers than when using an object directly: a pointer may be a nullptr or point to an object that wasn’t the one we expected.

空指针

void*

void* as pointer to an object of unknown type. void *可以用来返回位置的类型,有点类似Objective-C的id类型。任何类型的指针都可以赋值给void *类型。void *也可以隐形的转为其他的类型。

nullptr

nullptr代表空指针, 使用nullptr使代码比替代方法更具有可读性,并避免函数重载以接受指针或整数时潜在混淆。
在nullptr引入之前,都是直接使用0来代表空指针。

nullptr的优点是它没有整数类型。 说实话,它也没有指针类型,但您可以将其视为所有类型的指针。 nullptr的实际类型是std :: nullptr_t,并且在一个奇妙的循环定义中,std :: nullptr_t被定义为nullptr的类型。 类型std :: nullptr_t隐式转换为所有原始指针类型,这就是使得nullptr就像它是所有类型的指针一样的原因。

NULL

NULL是一个宏,在不同的系统里面可能代表着不同的值。
NULL可能是0或者是0L,在C语言里面是(void*)0

1
2
3
int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL; //#include cstdlib

空指针最直接的办法就是用字面值nullptr来初始化。
NULL是一种定义在cstdlib的预处理变量来给指针赋值。

Pointer into Arrays

指针只能指向数组的第一个元素,所以程序员得自己维护数组的大小。

1
2
3
4
int v[] = { 1, 2, 3, 4 }; 
int∗ p1 = v; // pointer to initial element (implicit conversion)
int∗ p2 = &v[0]; // pointer to initial element
int∗ p3 = v+4; // pointer to one-beyond-last element

有些算法在搜索元素位置的时候,如果没有找到,通常会把指针指向最后一个元素末尾一个不存在的位置。

For every built-in array a and integer j within the range of a, we have:

1
a[j] == ∗(&a[0]+j) == ∗(a+j) == ∗(j+a) == j[a]