C与Python函数参数传递总结

来源:互联网 发布:身材好的女友知乎 编辑:程序博客网 时间:2024/05/29 18:51

要理解值传递、指针传递和引用传递的区别,主要要理解函数的实参和形参,函数的作用域(自动变量、栈),内存的布局以及指针和引用的特点。

值传递:只给函数提供输入值,需要复制开销,大对象很少使用值传递。

指针传递:可以改变指针指向内容的值,但是不能改变指针本身,无需复制开销。如果需要改变指针本身,可以使用二重指针或者指针引用。

引用传递:除了提供输入值外,还返回操作结果,无需复制开销。

对于引用传递方式,所传递的地址是通过对实参进行取地址运算来获得的;而对于指针传递方式,所传递的地址就是实参的值。

 

函数参数传递方式之一:值传递

值传递(passl-by-value)过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

void swap(int x, int y)
{
  int tmp;
  tmp = x;
  x = y;
  y = tmp;
  printf("x = %d, y = %d\n", x, y);
}
main()
{
  int a = 4,b = 6;
   swap(a,b);
  printf("a = %d, b = %d\n", a, b);
  return(0);
} ////////////////C     是否能交换 ab的值?

 

a=1
def no_change(a):

   printid(a)        ###输出a的内存地址
    a=a+1

    print id(a)
    return a
print no_change(a)

print id id(a),a          #########python   a的值是否改变?

 

函数参数传递方式之二:指针传递

指针传递(pass-by-pointer)过程中,同样也需要在堆栈段中为被调用函数的形参列表分配内存。但是,由于形参定义为指针类型,从主函数传递过来的是实参列表各变量的地址。因此,指针传递方式的特点是被调函数对形参的任何操作也都影响到主函数中实参的值。

 

void swap(int *px, int *py)
{
   int tmp = *px;
   *px = *py;
   *py = tmp;
   printf("*px = %d, *py = %d.\n", *px, *py);
}

 


main()
{
   int a = 4;
   int b = 6;
   swap(&a, &b);   //
形参是指针,实参为地址
   printf("a = %d, b = %d.\n”, a, b);
   return(0);
}                            ////////////////C    
是否能交换 ab的值?

 

 

b = [1,2,3]

def change_list(b):

    print id(b)
    b[0] = b[0] + 1

     print id(b)
    return b

print change_list(b)
printb                  ######python b
的值是否改变(list传递的是指针)

函数参数传递方式之三:引用传递

引用传递(pass-by-reference)过程中,被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量

 

void swap(int &x, int &y) /* 注意定义处的形式参数的格式与值传递不同 */
{
  int tmp = x;x = y;
  y = tmp;
  printf("x = %d, y = %d.\n", x, y);
}
main()
{
  int a = 4;
  int b = 6;
   swap(a,b); /*注意:这里调用方式与值传递一样*/   形参为地址,实参为参数值
   printf("a= %d, b = %d.\n”, a, b);

 

 参考:    C/C++中的函数参数传递机制            

原创粉丝点击