前言
指针是指向另外一种类型的复合类型,指针实现了对其他对象的间接访问。指针本身是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。指针无需再定义的时候赋值。和其他内置的类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。
一、指针的基本概念
1、指针的概念
指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。
定义指针的形式“:
类型 * 变量名
int* p; //p 是指向int型对象的指针
double* a,* b; //a 和b 都是指向double类型的指针
2、获取对象的地址
指针存放某个对象的地址,要想获取该地址,需要使用 取地址(操作符&)。
int ival = 42;
int *p = &uival; //p 存放变量ival的地址;p是指向变量ival的指针;p指针指向了ival变量
3、利用指针访问对象
如果指针指向了一个对象,则允许使用解引用符(操作符*)来访问对象。
int ival = 42;
int * p = &ival;
cout<<"*p ="<< *p << endl;//由符号* 得到指针p所指的对象,输出42.
解引用操作仅适用于那些确实指向了某个对象的有效指针。
4、空指针
空指针不指向任何对象,在试图使用一个指针之前代码可以首先检查是否为空。几种常见的空指针方法:
int * p1 = nullptr; //等价于int * p1 = 0;
int * p2 = 0; //直接将p2初始化为字面量为0
int *p3 = NULL; //等价于int *p3 = 0;
建议初始化所有的指针,并且在可能的情况下,尽量等定义了对象之后再定义指向它的指针。如果实在不清楚指针应该指向何处,就把它初始化为nullptr 或者0,这样程序就能检测并知道,它没有指向任何具体的对象了。
5、void × 指针
void* 是一种特殊的指针类型,可用于存放任意对象的地址。一个void* 指针存放着一个地址,这一点和其他类型的指针是类似的。不同的是,我们对该地址中到底是什么类型的对象并不了解:
double obj = 3.14, *pd = &obj;
void *pv = &obj ;// obj可以存放任意类型的地址
pv = pd;//pv可以存放任意类型的地址
二、字符指针
在指针的类型中我们知道有一种指针类型为字符指针 char*;通常有两种使用情况:
1、第一种情况
#include<stdio.h>
int mian(){
char ch = 'W';
char* p = &ch;
*p = 'W';
return 0;
}
2、第二种情况
int main(){
char* pstr = "hello bit.";//本质是把字符串hello bit. 首字符的地址放到了pstr中。
printf("%s\n", pstr);
return 0;
}
有这样的一个面试题目:
int main(){
char str1[] = "hello bit.";
char str2[] = "hello bit.";
char *str3 = "hello bit.";
char *str4 = "hello bit.";
if (str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if (str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。
三、指针数组
1、指针数组的基本概念
指针数组是一个存放指针的数组。它是一个数组。
int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组
四、数组指针
1、数组指针的定义
数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。
int (*p)[10];
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。
//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。
2、&数组名VS数组名
对于下面的数组:
int arr[10]; //arr 和 &arr分别代表什么?
我们分析一下以下的代码:
可见数组名和&数组名打印的地址是一样的。那么,如下的代码呢???