指针的本质
我个人觉得指针的本质像一把钥匙,通过这把钥匙可以拿到宝箱(变量)里的财宝(数值)。
指针的赋值
指针的赋值呢,一般有以下几种。
单一变量赋值
例如
int a = 10;
int *b = &a;
这时,b内存储的变量就是a的地址(内存中的地址,以十六进制数来表示)。
当然,指针变量也可以先申请后赋值。例如:
int a = 10;
int *b;
b = &a;
一维数组、字符串等的赋值
以数组为例
int a[10];
int *b = a;
int *c = &a[0];
这两种方式都是将数组a的首地址赋值给指针变量。
指向二维数组指针变量的赋值
int a[10][10];
int (*b)[10] = a;
指向二维数组的指针,一定要在定义指针变量时,预先声明二维数组的列数。
在这里呢要明确一下指向二维数组的指针和指针数组的区别。例如:
int *p[5];
int (*p)[5];
第一种,该数组中的每个元素,都是一个指针,而第二种就是一个简单地指向二维数组的指针变量而已。
利用指针对数组or字符串进行遍历
利用中间变量进行遍历
for (int i = 0; i < n; i++)
{
*(p + i) = ....;
}
利用指针自加操作进行遍历
while(...)
{
*p++ = ...;
}
二维数组的遍历
二维数组的遍历和也是需要两个变量表示行和列。
比如要表示第i行第j列的指针形式是 *((p + i) + j)。
这里需要强调的一点是,p 和 p + 1的差值并不一定是1,而是要根据你的指针变量的类型来确定。例如:
int p;
p 和 p + 1的差值应该是4,因为int类型变量在内存中占据四个字节,就比如,张三家有四个连着的车库,你要从张三家的车库走到李四家的车库,需要走过去四个,才能到李四家的车库。
指针的一些操作
自加自减
p++,p--,++p, --p等
解引用
根据指针的地址去访问改地址所存储的变量的过程叫做解引用。
例如 :int a = 5; int *b = &a;
这时,b中存储的是a的地址,如果要访问这个地址里面的值,则需要使用 *b这个操作。这称之为解引用。
指针的作用
在介绍指针的作用之前,你先考虑下面这两个问题。
我在一个函数中定义了一个局部变量,然后要在另一个函数中对这个变量进行一些改变。该怎么做?
我在一个函数中把输入的数据存储到了一个定义的局部变量数组中,那我该怎么将这个数组作为返回值交给调用函数进行使用?
答案是显而易见的,利用指针。那我们该怎么做呢?下面演示一下这两个问题的操作。
void fun_s(int *b)
{
*b = 5;
}
void fun()
{
int a = 10;
fun_s(&a);
cout << a;
}
通过上面的操作,本来值为10的a,在经过fun_s(&a)这一操作后,a的值变成了5 。
再来看第二个问题。
int *fun_s(int *b)
{
int c[10];
for (int i = 0; i < *b; i++)
c[i] = i;
return c;
}
void fun()
{
int a = 10;
int * b = fun_s(&a);
for (int i = 0; i < 10; i++)
cout << *(b + i) << ' ';
}
上面这个fun_s函数,以数组指针的形式,返回了一个数组,在fun函数中将会输出从0~9的十个数字。
利用指针动态申请数组
int *a = (int *)malloc(sizeof(int) * n);
上面这句话的意思是,使用malloc函数,申请一个每个字符占一个int类型变量,个数为n的一个数组,并将这个数组的首地址赋值给指针a。
指针的基本操作暂时就想到这么多了,等以后再想到别的继续补充。