上一讲指针链接:
指针第五部分(const修饰的指针、多级指针)---- 2021.2.22
指针数组
我们在接触指针的时候往往会接触到指针数组和数组指针这两个概念。我们今天先讲指针数组的概念和用法,至于数组指针我们会在之后的文章中提及到。
首先在说指针数组之前我觉得很有必要引入下普通数组的概念,也就是整型数组。
整型数组:是一个数组,数组的每一个元素都是整型。
那么我们可以由整型数组的概念中引入指针数组。
指针数组:是一个数组,数组的每一个元素都是一个指针。
那我们又是在什么条件下才提出的指针数组呢?
因为正如下代码所示,我们定义了三个整型变量a
,b
和c
。并且分别赋值为10
,20
和30
。那么我们想要保存其三个变量的地址需要定义三个指针,分别是*p1
,*p2
和*p3
。
int main()
{
int a = 10;
int b = 20;
int c = 30;
int* p1 = &a;
int* p2 = &b;
int* p2 = &c;
}
我们正常是可以这么操作的,但是我们想象万一需要保存地址的参数很多很多呢?是不是用这种方式会很琐碎,那么就有人提出指针数组这个概念了,很好的解决了这个问题。我们看看怎样来使用吧。
int main()
{
int a = 10;
int b = 20;
int c = 30;
//需求: 数组中的每一个元素都是指针(地址)
int* num[3] = {
&a,&b,&c };
printf("%d\n",sizeof(num));
for (int i = 0;i < sizeof(num) / sizeof(num[0]);i++)
{
printf("%d ", *num[i]);
}
}
分析如下:
- 我们定义了三个整型变量
a
,b
和c
。并且分别赋值10
,20
和30
。此时我们想要定义一个指针数组来保存这三个整型变量的地址,那么我们需要知道指针数组num
的数据类型是啥。比如,因为变量a
的数据类型是int
类型,由前面几篇文章可知,对变量取&
操作则会在最后的数据类型上加上“ * ”
,则最后我们需要定义的指针数组的数据类型为int *
类型。 printf("%d\n",sizeof(num));
这句话其实就是对指针数组num
的数组类型的字节大小进行打印。正常结果为12
。因为我们在前几篇文章中提到过,不管是什么数据类型的指针,最终的字节大小都是4
。该指针数组中有三个同样数据类型的变量,所以正常为3 x 4 =12
,结果如下:
- 那么我们如果想要打印指针数组的元素,即我们首先需要得知指针数组中有几个元素,则
sizeof(num)
为指针数组中总元素的字节大小,并且指针数组中的元素的数据类型都是一样的,则我们就只需要将数组中的某一个元素提取出来即可,这里拿第一个元素为例,即sizeof(num[0])
,则最终两式相除就可得数组元素大小,在本例中,为3
。
那么最终打印指针内容,我们需要进行“ * ”
操作即可。 - 为了让大家更好的理解,特意画了一张图供大家观看。
那么此时我们想要定义一个指针用来保存数组num首元素的地址,我们该怎样定义呢?
这就会用到我们之前在前面几篇文章中提到过的多级指针了。
比如,num[0]
的数据类型是int*
类型,那么我们需要再定义一个指针变量用来存放其地址。那么此时我们新定义的指针变量k
的数据类型应该比原来多一级“ * ”
。
首先先上代码!!!
int main()
{
int a = 10;
int b = 20;
int c = 30;
//需求: 数组中的每一个元素都是指针(地址)
int* num[3] = {
&a,&b,&c };
printf("%d\n", sizeof(num));
int** k = num;
for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
{
printf("%d ", **(k + i));
}
}
对上述代码分析如下:
- 由前面分析可知,我们新定义的指针变量k的数据类型正常情况下应该为
int**
类型,并且我们的目的是保存数组num
首元素的地址,即num
等价于&num[0]
。所以最终定义为int** k = num;
- 那同样我们想要通过指针变量
k
来获取变量a
,b
和c
的内容,即10
,20
和30
。那么以取变量a
的内容为例。我们此时需要一级一级往上推导。因为k
是一个指针变量,即指针变量k
保存的是num
数组首元素的地址,即k = &num[0];
那么我们想要通过指针变量k
来获取num
数组首元素的内容,即对指针变量k进行“ * ”
操作。所以即*k = &a;
那么再进行一次“ * ”
操作就可以提取到指针变量num[0]
指向的对应变量a
的那块内存空间的内容,即**k = 10;
,最终可以通过二级指针k
来获取变量a
的内容。达到了我们的目的。其他同理。 - 最终运行结果如下所示。
- 同时为了让大家更好的理解,特意画了一张图供大家观看。
指针作为函数的形参
先上代码!!!
void swap(int x, int y)
{
int k = x;
x = y;
y = k;
printf("x=%d y=%d\n", x, y);
}
int main()
{
int a = 10;
int b = 20;
swap(a,b);
printf("a=%d b=%d\n", a, b);
system("pause");
return 0;
}
对上述代码分析:
-
我们定义了两个整型变量
a
和b
,并且分别赋值为10
和20
。那我们最终想要通过swap
函数将a
和b
的值进行调换。即最终效果为a
的值为20
,b
的值为10
。运行结果如下:
-
我们从上述结果可知,最终
a
和b
的值并没有成功进行调换,这是为什么呢?为了让大家更好的理解,特意画了一张图供大家观看。
刚开始a
的值为10
,b
的值为20
,那么进入swap
函数的形参x
值为10
,y
的值为20
。所以此时定义了一个整型中间变量k
,用来暂存x
的值,并且最终通过k
来将x
的值赋值给y
,即最终达到了x
和y
值相互替换的效果,但是当退出该swap
函数之后,其实x
和y
相当于是临时变量,不会保存在虚拟内存中,即最终a
和b
的值还是没有真正意义上的改变,即和上图最终结果一样,a
的值为10
,b
的值为20
。那么我们怎样来通过swap
函数来实现a
和b
的值的互换呢?这时候指针就派上用场了! -
修改后
swap
代码如下所示:
void swap(int *x, int *y)
{
int k = *x;
*x = *y;
*y = k;
printf("x=%d y=%d\n", *x, *y);
}
int main()
{
int a = 10;
int b = 20;
swap(&a,&b);
printf("a=%d b=%d\n", a, b);
system("pause");
return 0;
}
同样为了让大家更好的理解,特意画了一张图供大家观看。
对上图分析如下:
首先我们可以明显的看到传入swap
函数的接口参数是&a
和&b
,也就是a
和b
的地址。那么指针变量x
和指针变量y
分别指向变量a
和变量b
。那么就在swap
函数中对x
和y
的调换其实就变相直接操纵了变量a
和b
的内容,即最终a
变成20
,b
变成10
,成功通过指针进行了调换,最终运行结果如下:
结束语
如果觉得这篇文章还不错的话,记得点赞 ,支持下!!!