重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
C语言中,函数参数只能传值。与传值对应的是传引用,C语言不支持函数参数传引用,C++语言才支持。
成都创新互联服务项目包括塔河网站建设、塔河网站制作、塔河网页制作以及塔河网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,塔河网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到塔河省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
C++传引用函数:
void foo(int a) { a = 3; }
假如a = 2,执行foo(a)后,a = 3。
---
C语言可以模拟传引用,方法是通过指针来实现:
void foo2(int* ap) { *ap = 3; }
假如a = 2,执行foo2(a)后,a = 3
foo2(a)调用本质上仍然是传值,只不过传递的是指针,指针即是地址,地址本质上是一个无符号整数。
如果:
void foo3(int b) { b = 3; }
假如a = 2,执行foo3(a)后,a = 2。这是因为foo3(a)调用过程中,a值传给形参b,修改b的值与实参a无关。
注意到,foo3(a)与上述foo(a)传引用的调用是形式一样的。
既然C语言通过指针可以实现传引用调用,为什么C++还要引入引用这个特性呢?这是因为C++引入的很多新特性需借助引用来实现,比如,拷贝构造函数等等。
你要用*去解引用,这样才能改变指针指向内存的值。
你的swap函数写的有问题,正确的写法有人给了。
至于为什么*x,*y的值没有改变,因为你交换的是2个形参的值,虽然你传入的是指针,但是你没有把它们当成指针来用,最后的结果跟传非指针值是一样的。
如果想真正改变实参的值,就必须交换指针指向的内存,而不是单纯交换指针变量本身。形参是通过堆栈传递的,只有用类似 *x = 1;这样的语句操作指针指向的内存,才能影响到实参,否则实参的值是不会改变的。
其实最好的方式就是去VS里调试运行,仔细观察运行过程,就能比较清晰地了解指针。单纯的理论是站不住脚的,拉出来溜溜就一清二楚了。
想对你能有帮助。
*s表示变量m本身,对*s的赋值就是对m赋值,所以*s=a[p]是正确的。
请注意,函数fun中的s变量是一个地址,只对该地址进行重新赋值,并不对其所指向的变量m造成影响。所以s=a[p]不改变main函数中m变量的值。
如果把*s=a[p]改为s=a[p],输出会是乱码。这具有很大的迷惑性,使人以为地址的赋值过程出现了问题。实际上,若把m改为全局变量(全局变量中字符串默认为空,int变量默认为0):
#includestdio.h
#includestring.h
#define N 10
typedef struct ss
{
char num[10];
int s;
}STU;
void fun(STU a[],STU *s)
{
int t,p=0;
t=a[0].s;
for(int i=1;iN;i++)
{
if(ta[i].s)
{
t=a[i].s;
p=i;
}
}
s=a[p]; //这里是错误的语句
}
STU m;
void main()
{
STU a[N]={
{"A01",81},{"A02",81},{"A03",81},{"A04",81},{"A05",81},
{"A06",81},{"A07",81},{"A08",61},{"A09",81},{"A010",81}
};
printf("the original data is :\n");
for(int i=0;iN;i++)
{
printf("NO=%s MARK=%d\n",a[i].num,a[i].s);
}
fun(a,m);
printf("the lowest is %s who's score is %d\n",m.num,m.s);
}
输出的将会是the lowest is who's score is 0
这说明变量m的值并未改变过。
事实上,若非要使用符号,正确的方法是使用“引用”:
#includestdio.h
#includestring.h
#define N 10
typedef struct ss
{
char num[10];
int s;
}STU;
void fun(STU a[],STU s)
{
int t,p=0;
t=a[0].s;
for(int i=1;iN;i++)
{
if(ta[i].s)
{
t=a[i].s;
p=i;
}
}
s=a[p];
}
void main()
{
STU a[N]={
{"A01",81},{"A02",81},{"A03",81},{"A04",81},{"A05",81},
{"A06",81},{"A07",81},{"A08",61},{"A09",81},{"A010",81}
},m;
printf("the original data is :\n");
for(int i=0;iN;i++)
{
printf("NO=%s MARK=%d\n",a[i].num,a[i].s);
}
fun(a,m);
printf("the lowest is %s who's score is %d\n",m.num,m.s);
}
这里的意思是“引用”,你可以百度上搜索C++中符号的两个意义。
如果想把在子函数中的数据操作变化反应到主函数中的相应变量上,则在主函数中一定要传递这个变量的地址,不要管这个变量是什么类型!!
struct BiTree*a; //这里定义一个变量a , 它的类型是个结构体指针
creatBiTree(a); //这里是将a的地址传递到子函数中,这样,子函数中,通过对a变量的地址的操作,实现了a本身的值的变化!!
void creatBiTree(struct BiTree**root) //这里形参是**,是因为a是指针,a的地址还是个指针,因此要是二维指针类型,这是与a的类型相关的!
如果改成(struct BiTree *root) , 主函数中 creatBiTree(a); //写成这样编译会报参数类型错误, creatBiTree(a); //则root在子函数中的变化,不能反应到a上!!root和a仅是在数值上相等的两个不同的数据!
首先需要声明函数指针的类型(下例子中的typedef int (*fpFunt)(int a,int b),再定义某个函数(下例中的Add),在其参数列表中使用该函数指针类型,同时需要定义另一函数(下例中的fpAdd,注意该函数形式要和fpFunt一致,本例子中是返回一个整数,两个整型参数)作为实参用。这里在手机上使用易历知食软件内的微C程序设计来编程,举个两个数相加的例子,代码如下图:
调用后运行结果如下图:
改成下面代码看看:
#include stdio.h
void abc(int *i,int *j)
{
int m;
m=*i; //指针变量的值也就是地址不能赋值给一般变量
*i=*j;//*i,*j才是指针变量指向的变量的值
*j=m;
}
void main()
{
int a,b;
int *pa=a,*pb=b;
printf("请输入a,b的值:");
scanf("%d,%d",a,b);
abc(pa,pb); //
printf("a=%d\tb=%d\n",a,b);
}