文章目录
1 值传递
(1) 普通变量作为函数参数传递
值传递(单向传递):实参传递给形参 而形参的值无法传递给实参
int max(int a,int b)
{
return a>b?a:b;
}
int swap(int a,int b)
{
int tmp=a;
a=b;
b=tmp;
return 0;
}
int main()
{
int a=1,b=2;
int m=max(a,b);
swap(a,b);
printf("%d %d",a,b);
return 0;
}
该程序求最大值结果没问题,但交换两数有问题。
形参(函数定义处)为普通形式
实参(函数调用处)为普通形式
函数调用时,发生 形参=实参 的赋值
值传递本质是因为形参和实参存储在不同的内存地址中
(2). 变量地址作为函数参数传递
实参为变量地址,形参为指针变量
函数调用时,发生 形参=实参 的赋值,即让指针指向变量
//int* p=&a;
int main()
{
int a=1,b=2;
swap(&a,&b);
printf("%d %d",a,b);
int *p,*q;
p=&a;
q=&b;
swap(p,q);//此时p,q 指代的也是地址,无需加&
printf("%d %d",*p,*q);
return 0;
}
int swap(int*a,int*b)
{
int tmp=*a;
*a=*b;
*b=tmp;
return 0;
}
本例中的两种形式
形参 | 实参 |
---|---|
指针 | 地址 |
指针 | 指针 |
以下为本例中的两种形式的函数片段
实参
swap(&a,&b);
实参
int *p,*q;
p=&a;
q=&b;
swap(p,q);
形参
int swap(int*a,int*b)
注意:此时仍为值传递,只是传递的值是实参的地址。
除了形参和实参的形式,在使用变量地址作为函数参数传递时,
- 如果被调用函数中改变的指针内容要回传给主调函数,
那么,要在函数定义时,对指针指向的内容进行修改,如本例中swap()函数体内
int tmp=*a;
*a=*b;
*b=tmp;
操作的是p,q所指向的地址内存储的变量,而不是操作的p,q
- 当在函数体内对指针地址进行修改,而函数没有返回值,如
p++
p=(int *)malloc(sizeof(iint));
等,
则不会返回给主调函数。
(3) 一维数组名作为函数参数传递
(1)用数组名作为实参,实际上是传递的数组的起始地址
- 实参
int a[10];
select(a,10);
对于实参: 因为数组的名字本身就是起始地址,所以不用再在数组名字前加 取地址符号&
- 形参
当用数组名作为实参时
对于形参:一维数组退化为指针变量
int select(int a[],n); //int a[] 表示数组的名字,[]只表示是数组类型,无其他含义。
int select(int *a,n);
(2)数组作为参数传递的组合
实参 | 形参 |
---|---|
数组名 | 数组名 |
数组名 | 指针 |
指针 | 指针 |
指针 | 数组 |
2. 引用作为函数参数传递
(1)特点
- 引用是变量的别名,
- 引用不是一种数据类型。
- 引用与原始变量使用同一个内存地址
这也就与 值传递 区别开来。 - c++拥有此特性,而c中没有,是c++有别于c的性质之一,
也就是说,c只能通过值传递的方式进行参数的运算处理,
(2)使用方式
int a;
int &b=a;//①
printf("%p %p",&b,&a);0028FF18 0028FF18
此段代码,声明b是a的引用。
- 此时,操作b也就相当于操作a。操作a也意味着操作b(传递性)
- 一旦声明了引用b,就不能让b再作为另外变量的引用。(唯一性)
- 取引用的地址 &b 等同于取所引用的变量的地址&a
int *p=&a;//②
注意:②的&是地址符,有别于①&表示的引用符号
(3)引用作为函数的参数进行传递
int main()
{
int a=1,b=2;
swap(a,b);
printf("%d %d",a,b);
return 0;
}
int swap(&a1,&b1)
{
int tmp=a1;
a1=b1;
b1=tmp;
return 0;
}
形参为变量的引用 ——&狗
若 狗 为指向整型的指针变量,则形参为 int* &a
#include <stdio.h>
#include <malloc.h>
typedef char Element;
typedef struct
{
Element data;
struct LNode* next;
}LNode;
//初始化头节点
int initList(LNode *&A)
{
//1 分配空间
A=(LNode*)malloc(sizeof(LNode));//申请A的头结点空间
//2 指针指向NULL
A->next=NULL;//初始时头结点后面指向NULL
return 0;
}
int main()
{
LNode *L=NULL;
initList(L);
return 0;
}
3 总结
在c语言中,三种内容传递方式
将修改后的内容传给调用者时,有三种方式,
1 一种是设定返回值 return——但只能返回一个变量。当然可以通过数组或者结构体存储多个变量的组合
2一种是使用 值传递的指针方式 (上述方式2 )—— 形参为指针类型,实参为变量地址的方式
3 定义全局变量,在某处修改该变量值,则全局有效
在c++中,4种内容传递方式
当子函数中涉及对输入的形参进行修改的语句,并需要将修改后的内容返回给调用者,则使用
1 值传递的指针方式
2 引用 方式传递,
3 定义全局变量,在某处修改该变量值,则全局有效
4 return+值传递
而后者更节省内存,因为引用和所引用的变量为同一内存地址。*
4 参考文献
《c语言程序设计》谭浩强
《c++程序设计》 谭浩强