文章目录
- 定义指针及初始化
- 二级指针
一、地址与指针
日常生活中我们会问一个人住在哪,比如小明家住在XX省XX市XX县XX镇XX村,这就是其详细住址,也就是地址。
那么在程序中定义的任何变量实际上都是存在内存中的,那么他们的具体位置是多少呢,这里就涉及到了地址。就是这个变量真正存在的位置。
下面我们用代码举个例子,例如定义一个字符:
char ch = ‘a’;
我们用vs的监视窗口来看下字符 ch 的地址是多少呢?
那么在使用 cout << ch; 进行输出的时候,cout 也会去从 ch 的地址开始读取一个字符,之后打印输出出来。
变量的地址一般都是比较难记的,例如:0x007f2eab 之类的,那么能不能用专门的一个东西,或者说一种特殊类型的变量来保存这个地址呢?这个特殊类型的变量就是指针。
定义指针及初始化
int* p; //声明了一个指向int类型的指针,就在类型的后面加上一个*,代表是指针类型变量的意思。
但是他没有指向任何变量的地址。
- 将一个int类型的指针p指向了int类型变量a的地址。&符号是取地址符号,&a 就是取变量a的地址。
指针p也是一个变量,只不过是一个指针类型的变量,所以指针变量p的值就是 &a,指针变量p的地址是 &p。也就是说指针变量也是变量,他也有内容和地址。 - 在指针变量的前面加上一个
*
就能得到指针指向的变量自身。
所以对一个变量的修改,既可以通过该变量自身(直接修改),也可以通过指针/地址来实现修改(间接修改)。
说明:
①、指针变量的定义格式如下:基类型 *
指针变量名;
②、符号*
既可以靠近基类型,也可以靠近指针变量名,例如:int* p
; 和 int *p
; 都是正确的。
③、指针变量可以在定义的时候就初始化,也可以先定义后初始化,也可以在以后的任意一个时间去指向某个变量的地址:
④、基类型就是该指针变量指向的变量的类型。例如: int* ptr; 就是定义了一个指向int类型的指针变量ptr;你就不能把一个float类型的变量地址赋给他。
⑤、指针变量可以指向同一类型的变量,例如:
int a = 5, b = 6;
int *p = &a;
p = &b;
即:指针变量p既可以指向变量a的地址,也可以指向变量b的地址。
定义一个函数,实现交换两个参数的值:
二级指针
如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。
假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示:
int a =100;
int *p1 = &a;
int **p2 = &p1;
指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址。C语言不限制指针的级数,每增加一级指针,在定义指针变量时就得增加一个星号*。p1 是一级指针,指向普通类型的数据,定义时有一个*;p2 是二级指针,指向一级指针 p1,定义时有两个*。
二、指针与数组
之前我们知道如何 定义数组,在这里我们定义一个指针的数组,用来保存之前那个数组的所有元素的地址。如下:
①、C/C++中规定数组名字就是数组的首地址。也就是数组的第0个元素的地址。
②、C/C++中规定如果指针变量pnum已经指向数组中的一个元素,则pnum+1指向同一数组中的下一个元素的地址(而不是将pnum的值简单+1)。
③、访问数组的两种方法:
下标法:num[0];
指针法:*(pnum+idx)
小案例:指针遍历数组:
④指针运算(算术)
从上例你也可以得出:比如 int 类型指针pnum,pnum++ 他会指向下一个int的地址。
字符指针与字符数组
定义两个字符数组输入如下:
用指针的方式,实现将 str2 拷贝到 str1 中。
小案例:字符指针数组
三、指针与动态数组
new 分配内存
在C语言中,使用库函数malloc()来分配内存,在C++中仍然可以使用,但还要更好的方法new运算符。
new其实就是告诉计算机开辟一段新的空间,但是和一般的声明不同的是,new开辟的空间在堆上,而一般声明的变量存放在栈上。通常来说,当在局部函数中new出一段新的空间,该段空间在局部函数调用结束后仍然能够使用,可以用来向主函数传递参数。另外需要注意的是,new出来的是一段空间的首地址。所以一般需要用指针来存放这段地址。
通用格式如下:
typeName * pointer_name = new typeName;
示例如下:
delete 释放内存
释放通过new申请的内存
申请指向动态存储的结构数组的指针。参考类的动态内存申请与释放。