指针第六部分(指针数组、指针作为函数的形参)---- 2021.3.6

上一讲指针链接:

指针第五部分(const修饰的指针、多级指针)---- 2021.2.22

指针数组

我们在接触指针的时候往往会接触到指针数组和数组指针这两个概念。我们今天先讲指针数组的概念和用法,至于数组指针我们会在之后的文章中提及到。

首先在说指针数组之前我觉得很有必要引入下普通数组的概念,也就是整型数组。

整型数组:是一个数组,数组的每一个元素都是整型。
那么我们可以由整型数组的概念中引入指针数组。
指针数组:是一个数组,数组的每一个元素都是一个指针。

那我们又是在什么条件下才提出的指针数组呢?

因为正如下代码所示,我们定义了三个整型变量abc。并且分别赋值为102030。那么我们想要保存其三个变量的地址需要定义三个指针,分别是*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]);
    }
}

分析如下:

  1. 我们定义了三个整型变量abc。并且分别赋值102030。此时我们想要定义一个指针数组来保存这三个整型变量的地址,那么我们需要知道指针数组num的数据类型是啥。比如,因为变量a的数据类型是int类型,由前面几篇文章可知,对变量取&操作则会在最后的数据类型上加上“ * ”,则最后我们需要定义的指针数组的数据类型为int *类型。
  2. printf("%d\n",sizeof(num));这句话其实就是对指针数组num的数组类型的字节大小进行打印。正常结果为12。因为我们在前几篇文章中提到过,不管是什么数据类型的指针,最终的字节大小都是4。该指针数组中有三个同样数据类型的变量,所以正常为3 x 4 =12,结果如下:
    在这里插入图片描述
  3. 那么我们如果想要打印指针数组的元素,即我们首先需要得知指针数组中有几个元素,则sizeof(num)为指针数组中总元素的字节大小,并且指针数组中的元素的数据类型都是一样的,则我们就只需要将数组中的某一个元素提取出来即可,这里拿第一个元素为例,即sizeof(num[0]),则最终两式相除就可得数组元素大小,在本例中,为3
    那么最终打印指针内容,我们需要进行“ * ”操作即可。
  4. 为了让大家更好的理解,特意画了一张图供大家观看。

在这里插入图片描述
那么此时我们想要定义一个指针用来保存数组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));
    }
}

对上述代码分析如下:

  1. 由前面分析可知,我们新定义的指针变量k的数据类型正常情况下应该为int**类型,并且我们的目的是保存数组num首元素的地址,即num等价于&num[0]。所以最终定义为int** k = num;
  2. 那同样我们想要通过指针变量k来获取变量abc的内容,即102030。那么以取变量a的内容为例。我们此时需要一级一级往上推导。因为k是一个指针变量,即指针变量k保存的是num数组首元素的地址,即k = &num[0];那么我们想要通过指针变量k来获取num数组首元素的内容,即对指针变量k进行“ * ”操作。所以即*k = &a; 那么再进行一次“ * ”操作就可以提取到指针变量num[0]指向的对应变量a的那块内存空间的内容,即**k = 10;,最终可以通过二级指针k来获取变量a的内容。达到了我们的目的。其他同理。
  3. 最终运行结果如下所示。
    在这里插入图片描述
  4. 同时为了让大家更好的理解,特意画了一张图供大家观看。
    在这里插入图片描述

指针作为函数的形参

先上代码!!!

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;
}

对上述代码分析:

  1. 我们定义了两个整型变量ab,并且分别赋值为1020。那我们最终想要通过swap函数将ab的值进行调换。即最终效果为a的值为20b的值为10。运行结果如下:
    在这里插入图片描述

  2. 我们从上述结果可知,最终ab的值并没有成功进行调换,这是为什么呢?为了让大家更好的理解,特意画了一张图供大家观看。
    在这里插入图片描述
    刚开始a的值为10b的值为20,那么进入swap函数的形参x值为10y的值为20。所以此时定义了一个整型中间变量k,用来暂存x的值,并且最终通过k来将x的值赋值给y,即最终达到了xy值相互替换的效果,但是当退出该swap函数之后,其实xy相当于是临时变量,不会保存在虚拟内存中,即最终ab的值还是没有真正意义上的改变,即和上图最终结果一样,a的值为10b的值为20。那么我们怎样来通过swap函数来实现ab的值的互换呢?这时候指针就派上用场了!

  3. 修改后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,也就是ab的地址。那么指针变量x和指针变量y分别指向变量a和变量b。那么就在swap函数中对xy的调换其实就变相直接操纵了变量ab的内容,即最终a变成20b变成10,成功通过指针进行了调换,最终运行结果如下:
在这里插入图片描述

结束语

如果觉得这篇文章还不错的话,记得点赞 ,支持下!!!

猜你喜欢

转载自blog.csdn.net/qq_40544107/article/details/114267152
今日推荐