计算机科学类专升本复习之“C语言指针变量作为“函数参数“”详解(初稿)

C语言指针变量作为"函数参数"

在c语言中,"函数的参数"可以是"整数、小数、字符"等具体数据,还可以是指向它们的"指针"

用指针变量做函数可以将"函数外部的地址"传递到"函数内部",使得函数在内部可以操作函数外部的数据。并且这些"数据"不会随着函数的结束被"销毁"。

像数组、字符串、动态分配的内存等都是一系列数据的集合,没有办法通过一个参数全部传入函数内部,只能传递它们的指针,在函数内部通过指针来影响这些数据集合。

有的时候,对于整数、小数、字符等基本类型数据的操作也必须要借助指针,一个典型的例子就是交换两个变量的值。

//有些初学者可能会使用下面的方法来交换两个变量的值:

#include<stdio.h>

void swap(int a,int b)

{

    int kang;//定义一个临时变量kang

    kang = a;

    a = b;

    b = kang;

}



int main()

{

    int a = 65,b=99;

    swap(a,b);

    printf("a=%d,b=%d\n",a,b);

    return 0;

}

结果:

a = 66, b = 99

分析:

从结果可以看出,a、b 的值并没有发生改变,交换失败。

这是因为swap()函数内部的a、b和main()函数内部的a、b是"不同的变量",占用不同的内存

它们除了名字一样,没有其他任何联系。

swap()教换的是它们内部a、b的值,不影响外部a、b的值(mian()内部)。


 

如果改用指针变量作为参数,那么很容易就解决上面的问题

#include<stdio.h>

void swap(int *p1,int *p2)

{

    int kang;

    kang = *p1;

    *p1 = *p2;

    *p2 = kang;

}

int main()

{

    int a = 66, b = 99;

    swap(&a,&b);

    printf("a=%d,b=%d\n",a,b);

    return 0;

}

结果:

a = 99, b = 66

分析:

1. 调用swap()函数时,将变量a、b的地址"分别赋值给p1、p2"这样*p1、*p2代表的就是变量a、b本身交换*p1、*p2的值也就是交换a、b的值。

2. 函数运行结束后 虽然会将p1、p2销毁,但它对外部的a、b造成的影响是"持久化"的,不会随着函数的结束而"恢复原样"

3. 需要注意的是临时变量 temp,它的作用特别重要,因为执行*p1 = *p2;语句后 a 的值会被 b 的值覆盖,如果不先将 a 的值保存起来以后就找不到了。


 

这就好比拿来一瓶可乐和一瓶雪碧,要想把可乐倒进雪碧瓶、把雪碧倒进可乐瓶里面,就必须先找一个杯子,将两者之一先倒进杯子里面,再从杯子倒进瓶子里面。这里的杯子,就是一个“临时变量”,虽然只是倒倒手,但是也不可或缺。



 

二、用数组作函数参数

数组是"一系列数据的集合",无法通过"参数"将它们一次性传递到"函数内部",如果希望在"函数内部"操作数组,必须传递"数组指针"。

说白一点就是通过指针,一个接一个的将参数传递到函数内部,所以就有了for()循环!!

//下面来个程序例子吧!

#include<stdio.h>

int max(int *kang,int len)

{

    int i,maxValue = kang[0];//假设第0个元素是最大值

    for(i=1;i<len;i++)

    {

        if(maxValue < kang[i])

        {

            maxValue = kang[i];

        }

    }

    return maxValue;

}



int main()

{

    int num[6],i;

    int len = sizeof(num)/sizeof(int);

    //读取用户输入的数据并赋值给数组元素

    for(i=0;i<len;i++)

    {

        scanf("%d",num+i);

    }

    printf("Max value is %d!\n",max(num,len));

    return 0;

}

结果:

11 555 999 6 5 888

Max value is 999!

分析:

参数kangkang仅仅只是一个"数组指针",在函数内部无法通过这个指针获取到数组长度,必须将"数组长度"作为"函数参数"传递到函数内部。

数组num的每个元素都是整数,scanf()在读取用户输入的整数时,要求给出存储它的内存地址,num+i就说第i个数组元素的地址。

用 数组做参数时,参数也能够以 "真正" 的数组形式给出。

//例如对于上面的max()函数,它的参数可以写成下面的形式

int max(int kangkang[6],int len)

{

    int i,maxValue = kangkang[0];

    for(i=1;i<len;i++)

    {

        if(maxValue < kangkang[i])

        {

            maxValue = kangkang[i];

        }

    }

    return 0;

}

int kangkang[6]好像定义了一个拥有 6 个元素的数组,调用 max() 时可以将数组的所有元素“一股脑”传递进来。

//大家也可以省略数组长度,把形参简写为下面的形式:

int max(int kangkang[],int len)

{

    int i,maxValue = kangkang[0];

    for(i=1;i<len;i++)

    {

        if(maxValue < kangkang[i])

        {

            maxValue = kangkang[i];

        }

    }

    return 0;

}

int kangkang[]虽然定义了一个数组,但没有指定数组长度,好像可以接受任意长度的数组。

实际上这两种形式的数组定义都是假象,不管是int kangkang[6]还是int kangkang[]都不会创建一个数组出来,编译器也不会为它们分配内存,实际的数组是不存在的,它们最终还是会转换为int *kangkang这样的指针。

这就意味着,两种形式都不能将数组的所有元素“一股脑”传递进来,大家还得规规矩矩使用数组指针。

int kangkang[6]这种形式只能说明函数期望用户传递的数组有 6 个元素,并不意味着数组只能有 6 个元素,真正传递的数组可以有少于或多于 6 个的元素。

需要强调的是,不管使用哪种方式传递数组,都不能在函数内部求得数组长度,因为 kangkang 仅仅是一个指针,而不是真正的数组,所以必须要"额外增加一个参数"来传递数组长度。//所以就有了 int len 这个参数!!


 

C语言为什么不允许直接传递数组的所有元素,而必须传递数组指针呢?

因为 参数的传递本质上是"赋值的过程",赋值是对"内存"进行拷贝。所谓拷贝,是指将一块内存上的数据复制到另外一块内存上。

对于像 int、float、char 等基本类型的数据,它们占用的内存往往只有几个字节,对它们进行内存拷贝非常快速。而数组是一系列数据的集合,数据的数量没有限制,可能很少,也可能成千上万,对它们进行内存拷贝有可能是一个漫长的过程,会严重拖慢程序的效率,为了防止技艺不佳的程序员写出低效的代码,C语言没有从语法上支持数据集合的直接赋值。


 

猜你喜欢

转载自blog.csdn.net/weixin_51563198/article/details/122784803