极限研究-"&"函数返回引用与返回普通类型的区别

本文探讨了函数返回值中引用与非引用的区别,并通过具体示例分析了这两种返回类型在内存层面的不同表现形式。强调了正确选择返回类型的重要性,特别是在涉及变量生命周期时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 函数返回值有很多类型,但是什么时候该返回引用,而什么时候又该返回非引用呢?它们之间有什么区别吗?

让我们来看两个例子:

  • //函数返回引用
  • int &test1(int test_array[])
  • {
  •     return test_array[1];
  • }
  • //函数返回普通类型
  • int test2(int test_array[])
  • {
  •     return test_array[1];
  • }

仔细观察这两个函数,你会发现函数主体一样的:return test_array[1];

那它们返回的结果是否一样呢?

  • void main(int argc,char *argv[])
  • {
  •     int test[5]={0,1,2,3,4};
  •     test1(test);
  •     test2(test);
  • }

调试该程序:

分别在test1、test2内部下断点:

  • int &test1(int test_array[])
  • {
  • 00411C40  push        ebp  
  • 00411C41  mov         ebp,esp 
  • 00411C43  sub         esp,0C0h 
  • 00411C49  push        ebx  
  • 00411C4A  push        esi  
  • 00411C4B  push        edi  
  • 00411C4C  lea         edi,[ebp-0C0h] 
  • 00411C52  mov         ecx,30h 
  • 00411C57  mov         eax,0CCCCCCCCh 
  • 00411C5C  rep stos    dword ptr es:[edi] 
  •     return test_array[1];
  • 00411C5E  mov         eax,dword ptr [test_array]
  • //这里的mov eax,dword ptr [test_array]是不是有些迷惑呢?
  • //实际上这里应该是mov eax,dword ptr [ebp+8],即[ebp+8]处存放第一个参数
  • //的地址,所以这里的eax是获得的数组test_array的基址 
  • 00411C61  add         eax,4 
  • //这里就应该十分明了:获得下标为1的数组的地址
  • }
  • int test2(int test_array[])
  • {
  • 00411D90  push        ebp  
  • 00411D91  mov         ebp,esp 
  • 00411D93  sub         esp,0C0h 
  • 00411D99  push        ebx  
  • 00411D9A  push        esi  
  • 00411D9B  push        edi  
  • 00411D9C  lea         edi,[ebp-0C0h] 
  • 00411DA2  mov         ecx,30h 
  • 00411DA7  mov         eax,0CCCCCCCCh 
  • 00411DAC  rep stos    dword ptr es:[edi] 
  •     return test_array[1];
  • 00411DAE  mov         eax,dword ptr [test_array] 
  • //这里就不需要再解释了吧
  • 00411DB1  mov         eax,dword ptr [eax+4] 
  • //直接获得下标为1的数组的值
  • }

结论:“&”对函数返回值的类型有着本质上的影响,如果加“&”返回该类型的指针类型,如果不加则返回该类型的基本类型(即使在函数实体内的操作是完全一样的情况下),同时要注意返回值的作用范围,即如果引用一个在作用域在该函数内的变量就会引发错误,因为在该函数结束时,被引用变量的生命周期也会结束,所以将返回一个不存在的值。当函数要返回一个作用域在该函数范围的变量时不能使用“&”!

#include<stdio.h> #include<stdlib.h> #include"hpoly.h" #define NULL 0 void PrintPoly(PolyList*head) {PolyList*p; int m=0; p=head->next; while(p!=NULL) {printf("\t%5d%5d,p->coef,p->exp); p=p->next;m++; if(m%4==0) printf("\n\t");} printf("\n\n\t多项式项数m=%d\n",m); system("pause"); } void main() {PolyList*PLA*PLB PLA=CreatePoly(); PLB=CreatePoly(); system("cls"); printf("多项式A:\n"); PrintPoly(PLA); printf("多项式B:\n"); PrintPoly(PLB); PolyAdd(PLA,PLB); printf("多项式:\n"); PrintPoly(PLA); } PolyList*CreatePoly() {PolyList*head,*p,*tail; int ic,ie; head=(PolyList * )malloc(sizeof(PolyList)); head->next=NULL; tail=head; printf("请输入系数指数(ic,ie),直到输入0为止:\n"); scanf("%d,%d",&amp;ic,&amp;ie); while(ic!=0) {p=(PolyList * )malloc(sizeof(PolyList)); p->coef=icic;p->exp=ie; tail->next=p; tail=p; tail->next=Null; scanf("%d,%d",&amp;ic,&amp;ie); } return(head); } void PolyAdd(PolyList *PLA, PolyList *PLB) { PolyList *pa,*pb,*tail,*s; int sum; pa = PLA->next; pb = PLB->next; tail = PLA; PLB->next = NULL; while (pa != NULL &amp;&amp; pb != NULL ) { if ( pa->exp < pb->exp ) { tail->next = pa; tail = pa; pa = pa->next; } else if ( pa->exp > pb->exp ) { tail->next = pb; tail = pb; pb = pb->next; } else { sum = pa->coef + pb->coef; if ( sum != 0 ) { pa->coef = sum; tail->next = pa;tail = pa; pa = pa->next; s = pb; pb = pb->next; free(s); } else { s = pa; pa = pa->next; free(s); s = pb; pb = pb->next; free(s); } } } if(!pa&amp;&amp;!pb) tail->next=NULL; else if ( pa != NULL ) tail->next = pa; else tail->next = pb; } 设计算法实现两个一元多项式的建立、相加操作,要求利用原有空间求其多项式,并且按指数从小到大排列输出这两个多项式及其多项式,其输出形式为多项式的系数、指数。修改代码
最新发布
03-29
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值