C语言参数传递

来源:互联网 发布:淘宝乐町代购是真的吗 编辑:程序博客网 时间:2024/05/01 20:03

C语言参数传递方式有传值和传地址两种方式。

       1、传值方式

        原理:形参和实参占不同内存单元,传递的实际上是实参变量或表达式的一个拷贝副本,将这个副本值传给形参,形参内存单元内容保存的正是这个副本值,相当于给形参进行初始化,形参的值发生变化也不会传回给实参,因此是单向传递。

       例如:

                void increase(int x)

                      {

                           x++;

                      }

    当在主函数中调用上面这个函数时,会在ncrease函数内存栈中为形参x分配一个内存单元,然后把实参的值传到这个内存单元中,相当于给形参初初化了,然后形参x自增1,它改变的仅仅是形参内存单元中的内容,而实参内存单元中的内容并没有改变。当被调用函数执行完毕后,形参所分配的内存单元也被收回。

     

 

         2、传地址方式

        原理:和传值方式一样,当调用函数时也要为形参分配内存,被调函数执行完毕后也要收回内存。不同的是传递的是实参变量地址的拷贝值,而不是实参变量的值,在被调函数中对地址所指对象的操作会改变实参的值。但是形参的内容即存放的实参变量地址并不会改变。

          例如:

                  void increase(int * x)

                      {

                          *x++;

                      }

                  int main()

                  {

                       int i,*x;

                       i=10;

                       *x=20;

                      increase(&i);//如果定义的不是指针变量,那变要加上个取址号&,当然如果形参实参是数组的话,直接用数组名即可,因为数组名本身代表的就是数组的首地址

                      increase(x);

                  }

                主函数调用被调函数后,主函数中的i*x的值都会改变。

 

 

 

我曾经在做关于链表的实验时,想先写一个初始化结点的函数,用malloc给结点分配内存,然后给主函数调用。

struct node
{
 int data;
 struct node *next;
}

当初始化函数按下面这样写就会有问题:

int  init(struct node *n)
{
 n=(struct node *)malloc(sizeof(struct node));
 if(!n)
 {
  printf("Failed to create node\n");
  return -1;

 }
 return 0;

}

在主函数中定义struct node *n;然后执行init(n);编译能通过,但运行会报错。
因为虽然用了指针传递方式,但是被调函数只能改变n所指对象即结构体中成员的值,但其本身的值即地址并不会改变。

有两种解决办法,一是形参用双指针变量,一是被调用函数返回值类型设为结构体指针类型。

如:

int  init(struct node **n)
{
 (*n)=(struct node *)malloc(sizeof(struct node));
 if(!(*n))
 {
  printf("Failed to create node\n");
  return -1;

 }
 return 0;
}

n是一个双指针变量,它存放结构体指针变量的地址。

如:

或是被调用函数返回值类型设为结构体指针类型

struct node *  init()
{
 struct node *n=NULL;
 n=(struct node *)malloc(sizeof(struct node));
 return n;
}

 

原创粉丝点击