指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。 本质上, 指针和普通的变量没有什么区别, 只是它的值稍微特殊一点, 是一个地址, 通过这个地址我们就可以访问到实际的值。
指针即地址,指针即地址, 指针即地址, 记住这句话, 就能非常容易理解指针。
指针的一般定义为:指针类型 *指针变量名;
其中指针的类型是指指针所指向的地址中存放的值的类型, 因为指针本身是个地址值,数据类型是固定的; *是指针的标识符, 指针变量名是指针变量的名字。
例如:
int *pt1; //定义了一个int型的指针pt1, 它指向的地址中存放的值是int型 double *pt2; //定义了一个double型的指针pt2, 它指向的地址中存放的值是double型
上面定义的指针没有初始化, 一个没有初始化的指针用起来是比较危险的, 因为不知道指向了哪里。所以用指针之前一定要初始化。 可以初始化为NULL值, 编译器会特殊处理。
2.2 二级指针所谓二级指针就是指向指针的指针, 也就是指针中存放的是另一个指针的地址。 一个形象的比喻就是套娃。
只要理解了指针即地址这句话, 多级指针理解起来也没有难度。
二级指针定义时需要2个*。
例如:
int **pt; //定义了一个指向int型指针的指针3 指针的操作 3.1 访问指针的值
访问指针的值是指针最常见的操作了。指针本身只是个地址, 我i们一般不关心这个地址本身, 我们关心的是这个地址位置上存放的实际值。
通过*可以访问指针的值。
例如:
#includeusing namespace std; int main() { int val=1; int *pt1=&val; cout<<"the point is:"< 输出
the point is:0x72fe04 the value of the point is:1可以看到, 如果直接输出指针本身, 它就是个地址, 这也印证了我一直强调的指针即地址这句话。 用*就可以访问指针所存放的实际值。
3.2 指针的数学运算指针既然也是个值, 就支持基本的数学运算, 像++, --, +, -这些操作。
需要注意的是, 指针加1并不是地址值加1, 取决于指针的类型, 如int型指针, 指针加1实际上指针的值是加了4。 因为一个int型占4个字节。 要理解这一点,核心还是指针即地址这句话。 我们关心的是地址中存放的实际值, 而不是关心地址本身。 那么指针加1, 我们实际要想的是指向下一个值, 所以得加4。 如果指针只是加1的话, 实际上指向了一个int型值的中间一些bit位, 显然不是我们想要的。例如:
#includeusing namespace std; int main() { int val=1; double val2 = 2; int *pt1=&val; double *pt2=&val2; cout<<"the int point is:"< 输出:
the int point is:0x72fdfc the int point +1 is:0x72fe00 the int point + 2 is:0x72fe04 the int point ++ is:0x72fe00 the double point is:0x72fdf0 the double point +1 is:0x72fdf8数组的名字就是地址, 所以可以把数组名赋值给一个指针。 那么指针就指向了数组的首元素地址。 但是字符串或者字符数组比较特殊,数组名不仅是地址, 而且也是字符串的值(实际上, 字符串或字符数组没有特殊之处, 名字也和普通数组名一样是个地址, 只是cout输出时做了特殊处理, 名字可以直接输出字符串的值)。
#includeusing namespace std; int main() { int arr[3] ={1, 2, 3}; char chs[4]={'a','b','c', ' '}; // "abc" int *pt = arr; char *pt_s = chs; cout<<"the arr is :"< 输出:
the arr is :0x72fdf0 the pointer is :0x72fdf0 the value of pointer is :1 the string is:abc the pointer of string is:abc the value of the string pointer is:a



