精华内容
下载资源
问答
  • 转载自:指针变量作为函数参数 指针变量作为函数参数 在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在...

    转载自:指针变量作为函数参数

    指针变量作为函数参数

    在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。

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

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

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

    #include <stdio.h>
    void swap(int a, int b)
    {  
        int temp;  //临时变量 
        temp = a;  
        a = b;
        b = temp;
    }
    int main()
    {   
        int a = 66, 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 的值,不会影响它外部(main() 内部) a、b 的值。

    改用指针变量作参数后就很容易解决上面的问题:

    #include <stdio.h>
    void swap(int *p1, int *p2)
    {   
        int temp;  //临时变量   
        temp = *p1; 
        *p1 = *p2;   
        *p2 = temp;
    }
    int main()
    {    
        int a = 66, b = 99;   
        swap(&a, &b);  
        printf("a = %d, b = %d\n", a, b);   
        return 0;
    }
    

    运行结果:

    a = 99, b = 66
    

    调用 swap() 函数时,将变量 a、b 的地址分别赋值给 p1、p2,这样 p1、p2 代表的就是变量 a、b 本身,交换 p1、p2 的值也就是交换 a、b 的值。函数运行结束后虽然会将 p1、p2 销毁,但它对外部 a、b 造成的影响是“持久化”的,不会随着函数的结束而“恢复原样”。

    数组名作函数参数

    数组是一系列数据的集合,无法通过参数将它们一次性传递到函数内部,如果希望在函数内部操作数组,必须传递数组指针。下面的例子定义了一个函数 max(),用来查找数组中值最大的元素:

    #include <stdio.h>
    int max(int *intArr, int len)
    {  
        int i, maxValue = intArr[0];  //假设第0个元素是最大值 
        for(i=1; i<len; i++)
        {       
            if(maxValue < intArr[i])
            {       
                maxValue = intArr[i];  
            }    
        }       
        return maxValue;
    }
    int main()
    {  
        int nums[6], i; 
        int len = sizeof(nums)/sizeof(int);    //读取用户输入的数据并赋值给数组元素  
        for(i=0; i<len; i++)
        {        
            scanf("%d", nums+i);   
        }    
        printf("Max value is %d!\n", max(nums, len)); 
        return 0;
    }
    

    运行结果:

    12 55 30 8 93 27↙
    Max value is 93!
    

    参数 intArr 仅仅是一个数组指针,在函数内部无法通过这个指针获得数组长度,必须将数组长度作为函数参数传递到函数内部。数组 nums 的每个元素都是整数,scanf() 在读取用户输入的整数时,要求给出存储它的内存的地址,nums+i就是第 i 个数组元素的地址。

    用数组做函数参数时,参数也能够以“真正”的数组形式给出。例如对于上面的 max() 函数,它的参数可以写成下面的形式:

    int max(int intArr[6], int len)
    { 
        int i, maxValue = intArr[0];  //假设第0个元素是最大值
        for(i=1; i<len; i++)
        {        
            if(maxValue < intArr[i])
            {   
                maxValue = intArr[i];
            }  
        }    
        return maxValue;
    }
    

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

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

    int max(int intArr[], int len)
    {    
        int i, maxValue = intArr[0];  //假设第0个元素是最大值  
        for(i=1; i<len; i++)
        {       
            if(maxValue < intArr[i])
            {           
                maxValue = intArr[i];   
            }    
        }    
        return maxValue;
    }
    

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

    实际上这两种形式的数组定义都是假象,不管是int intArr[6]还是int intArr[]都不会创建一个数组出来,编译器也不会为它们分配内存,实际的数组是不存在的,它们最终还是会转换为int *intArr这样的指针。这就意味着,两种形式都不能将数组的所有元素“一股脑”传递进来,大家还得规规矩矩使用数组指针。

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

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

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

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

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

    除了C语言,C++JavaPython 等其它语言也禁止对大块内存进行拷贝,在底层都使用类似指针的方式来实现。

    展开全文
  • 本文主要讲了c语言指针变量作为函数参数传递,下面一起来学习一下
  • 本文主要介绍C语言 指针变量作为函数参数,这里整理了相关资料和示例代码,以便大家学习参考理解知识点,有需要的小伙伴可以参考下
  • C语言指针变量作为函数参数

    参考:http://c.biancheng.net/cpp/html/74.html

    在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。

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

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

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

    #include <stdio.h>
    
    void swap(int a, int b){
        int temp;  //临时变量
        temp = a;
        a = b;
        b = temp;
    }
    
    int main(){
        int a = 66, 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 的值,不会影响它外部(main() 内部) a、b 的值。

    改用指针变量作参数后就很容易解决上面的问题:
    运行结果:
    a = 99, b = 66

    调用 swap() 函数时,将变量 a、b 的地址分别赋值给 p1、p2,这样 *p1、*p2 代表的就是变量 a、b 本身,交换 *p1、*p2 的值也就是交换 a、b 的值。函数运行结束后虽然会将 p1、p2 销毁,但它对外部 a、b 造成的影响是“持久化”的,不会随着函数的结束而“恢复原样”。

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

    用数组和变量作函数参数例子

    u8 canreceive[8];
    uint32_t ID;
    //函数
    u8 Can_Receive_Msg(u8 *buf,uint32_t *id) {        u32 i; CanRxMsg RxMessage;     if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;     CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); if(RxMessage.StdId==0x390) { for(i=0;i<8;i++)     buf[i]=RxMessage.Data[i];      *id=RxMessage.StdId; } if(RxMessage.StdId==0x190) { for(i=0;i<8;i++)     buf[i]=RxMessage.Data[i];  *id=RxMessage.StdId; } return RxMessage.DLC; }
    key=Can_Receive_Msg(canreceive,&ID);//调用

    展开全文
  • 指针变量作为函数参数示例及简析

    千次阅读 2019-08-21 17:15:30
    本文介绍指针变量作为函数参数时的相关内容。 示例代码如下: #include <stdio.h> #include <stdlib.h> int main() { /* 函数声明 */ int swap(int *p1, int *p2); int a = 0; int b = 0; ...

    本文介绍指针变量作为函数参数时的相关内容。

    示例代码如下:

     

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        /* 函数声明 */ 
        int swap(int *p1, int *p2);
        
        int a = 0;
        int b = 0;
        int i = 0;
        int *pointer_1 = NULL;
        int *pointer_2 = NULL;
        
        printf("please input a and b: ");
        scanf("%d %d", &a, &b);
        /* 交换前a和b的值 */
        printf("before swap: a=%d, b=%d\n", a, b);
        
        pointer_1 = &a;
        pointer_2 = &b;
        
        i = swap(pointer_1, pointer_2);
        /* 交换后a和b的值 */ 
        printf("after swap: a=%d, b=%d\n", a, b);
        
        system("pause");
        
        return 0;
    }
    
    /* 
    *  在此函数中实现指针变量的值的交换 
    */
    int swap(int *p1, int *p2)
    {
        int tmp = 0;
        
        tmp = *p1;
        *p1 = *p2;
        *p2 = tmp;
        
        return 0; 
    }

    上述代码运行结果如下:

     

     

    please input a and b: 11 33
    before swap: a=11, b=33
    after swap: a=33, b=11

    通过以上代码及运行结果,能够得出:

     

    1)指针作为函数参数时,是将一个变量的地址传送到另一个函数中。

    2)需要注意:函数swap的形参是以“int *p1”的形式进行的定义;而调用该函数时,实参直接传入指针(变量地址)“pointer_1”。

    3)函数swap的作用是交换两个变量(a和b)的值,其实现方法是通过交换指针变量所指向的值(*p1和*p2),而并非交换指针变量的值(p1和p2)。这是因为:函数参数传递的方式是“单向传送”的“值传递”方式(指针变量作为函数参数也是遵循这一规则),形参值(p1和p2)的改变不能使实参的值(pointer_1和pointer_2)随之改变,即,受“单向值传递”约束的只是指针变量(pointer_1和pointer_2),而指针变量(pointer_1和pointer_2)所指向的值(a和b)并不受约束,故可以通过函数传参进行改变。

    4)函数的调用可以(而且只可以)得到一个返回值(即函数值),而运用指针变量作为函数参数,可以得到多个变化了的值。

    5)对于swap函数的实现,下面有一个错误的示例:

     

    /*
    * swap函数的错误示例 *
    */
    int swap_error(int *p1, int *p2)
    {
        int *tmp;
        
        *tmp = *p1;
        *p1 = *p2;
        *p2 = *tmp;
        
        return 0; 
    }

    上述代码在编译时不会报错,但运行时会直接导致程序崩溃。原因在于,*p1(即a)是整型变量,而*tmp是指针变量tmp所指向的变量,但tmp中并无确定的值(它的值是不可预见的),因此tmp所指向的单元也是不可预见的。所以,对*tmp赋值有可能给一个存储着重要数据的存储单元赋值,这样就会破坏系统的正常工作。所以,应该将*p1的值赋给一个整型变量,如前面的正确示例中的tmp一样,用整型变量tmp作为临时辅助变量来实现*p1和*p2的交换。

     

    备注:这里尚未知道是否有方法能够通过修改此错误代码,来实现*p1和*p2的交换目的,待后续补全。

    展开全文
  • 一、指针变量作为函数参数 在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的...

    一、指针变量作为函数参数

    在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。

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

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

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

    #include <stdio.h>
    
    void swap(int a, int b)
    {
        int temp;  //临时变量
    
        temp = a;
        a = b;
        b = temp;
    }
    
    int main()
    {
        int a = 66, 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 的值,不会影响它外部(main() 内部) a、b 的值。

    改用指针变量作参数后就很容易解决上面的问题:

    #include <stdio.h>
    
    void swap(int *p1, int *p2)
    {
        int temp;  //临时变量
    
        temp = *p1;
        *p1 = *p2;
        *p2 = temp;
    }
    
    int main()
    {
        int a = 66, b = 99;
    
        swap(&a, &b);
        printf("a = %d, b = %d\n", a, b);
    
        return 0;
    }

    运行结果:

    a = 99, b = 66
    


    调用 swap() 函数时,将变量 a、b 的地址分别赋值给 p1、p2,这样 *p1、*p2 代表的就是变量 a、b 本身,交换 *p1、*p2 的值也就是交换 a、b 的值。函数运行结束后虽然会将 p1、p2 销毁,但它对外部 a、b 造成的影响是“持久化”的,不会随着函数的结束而“恢复原样”。

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

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

    交换两个变量的值


    二、用数组作函数参数

    数组是一系列数据的集合,无法通过参数将它们一次性传递到函数内部,如果希望在函数内部操作数组,必须传递数组指针。下面的例子定义了一个函数 max(),用来查找数组中值最大的元素:

    #include <stdio.h>
    
    int max(int *intArr, int len)
    {
        int i, maxValue = intArr[0];  //假设第0个元素是最大值
    
        for(i=1; i<len; i++){
            if(maxValue < intArr[i]){
                maxValue = intArr[i];
            }
        }
       
        return maxValue;
    }
    
    int main()
    {
        int nums[6], i;
        int len = sizeof(nums)/sizeof(int);
    
        //读取用户输入的数据并赋值给数组元素
        for(i=0; i<len; i++){
            scanf("%d", nums+i);
        }
        printf("Max value is %d!\n", max(nums, len));
    
        return 0;
    }

    运行结果:

    12 55 30 8 93 27↙
    Max value is 93!

    参数 intArr 仅仅是一个数组指针,在函数内部无法通过这个指针获得数组长度,必须将数组长度作为函数参数传递到函数内部。数组 nums 的每个元素都是整数,scanf() 在读取用户输入的整数时,要求给出存储它的内存的地址,nums+i就是第 i 个数组元素的地址。

    用数组做函数参数时,参数也能够以“真正”的数组形式给出。例如对于上面的 max() 函数,它的参数可以写成下面的形式:

    int max(int intArr[6], int len)
    {
        int i, maxValue = intArr[0];  //假设第0个元素是最大值
    
        for(i=1; i<len; i++){
            if(maxValue < intArr[i]){
                maxValue = intArr[i];
            }
        }
    
        return maxValue;
    }

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

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

    int max(int intArr[], int len)
    {
        int i, maxValue = intArr[0];  //假设第0个元素是最大值
    
        for(i=1; i<len; i++){
            if(maxValue < intArr[i]){
                maxValue = intArr[i];
            }
        }
    
        return maxValue;
    }

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

    实际上这两种形式的数组定义都是假象,不管是int intArr[6]还是int intArr[]都不会创建一个数组出来,编译器也不会为它们分配内存,实际的数组是不存在的,它们最终还是会转换为int *intArr这样的指针。这就意味着,两种形式都不能将数组的所有元素“一股脑”传递进来,大家还得规规矩矩使用数组指针。

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

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

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

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

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

    除了C语言,C++、Java、Python 等其它语言也禁止对大块内存进行拷贝,在底层都使用类似指针的方式来实现。

    展开全文
  • 使用指针变量作为函数参数|地址传递与指针传递实例总结地址传递值传递错误写法1错误写法2 地址传递 指针类型可以作为函数参数的类型,这时视为把变量的地址传入函数。如果在函数中对这个地址的元素进行改变,原先的...
  • 指针变量作为函数参数    函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。 栗子: 对输入的两个整数按大小顺序输出。现用函数处理,而且...
  • 人之所以痛苦,那是因为你在成长。--------magic_guo C语言中实参变量和形参变量之间的数据传递是单向的“值传递”方式。用指针变量作函数参数同样要遵循这一规则。...//指针变量作为函数参数, 改变...
  • 指针变量作为函数参数和一般变量作为函数参数是有区别的,对于这种区别初学者一般都很迷惑。下面我将就一个简单的例子来说明一下它们的区别。看透以后也许也就不那么疑惑了。# include void main(){ void swap1(int...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,018
精华内容 1,207
关键字:

指针变量作为函数参数