#include <iostream.h> #include ,stdio.h> /*--------------------比较的程式1:正常的含有函数的程序----------à int a[3]={1,2,3}; int function(int index); int main() { int a; a=function(2); cout<<a<<endl; return 0; }
int function(int index) { return a[index];----->返回值 } */---------------------------------------------------------------------------- --->
/*------------------比较的程式2-------------------------------------------à
int a[3]={1,2,3}; int main() { int b=a[2];-------------->右算子,赋出值 cout<<b<<endl;
a[2]=4; --------------->左算子,被赋值 cout<<a[2]<<endl; return 0; } *///-------->a[i]作为左算子和右算子所表示的意思不同 //---------------------------------------------------------------------------- ---à
/*-----------------------比较的程式3----------------------------------------à
int i; int a[3]={1,2,3}; int &function(int index); int main() {
function(2)=9;//--------->可被赋值了 cout<</*a[2]*/i<<endl; return 0; }
int &function(int index) { // return a[index]; return i; }/*----------------------------------------------------------------------à
*///----------->利用引用实现通过函数的返回类型的变化. //--------- -->为什么说:return a[index]返回的应是整形值 //------------>用了引用后明显变了 //------------>不用引用怎样实现上述的效果呢. //-------- --->即怎样使返回的相当左算子 //------------>怎样理解引用的作用和意义. 你是否感觉:&在几个用法中没有一致的性质可循. 下面我们就来探讨和总结一下:
/*usecase*/ By RedStar81 #include <iostream> #include <stdio.h>
using namespace std;
void main(void) { //测试引用是否可以赋以常量. /* int &a =100; //wrong */ //考察引用和指针的使用区别 /* int a = 100; int *ptr; ptr = &a; cout<<*ptr<<endl; getchar(); */ //测试对引用取址返回的结果 /* int a =100; int &b = a; cout<<b<<endl; cout<<&b<<endl; int &c = b; cout<<c<<endl; getchar(); */ //测试是否可以重新赋值 /* int a = 100; int b = 200; int &c = a; cout<<a<<endl<<b<<endl<<c<<endl; c = b; cout<<c<<endl; getchar(); */ //说明引用的一种错误用法.......... /* int a = 100; int &b = &a; cout<<a<<endl<<b<<endl; getchar(); */ /* char* str = "I am programming."; char*& rpchar = str; cout<<str<<endl<<rpchar<<endl; getchar(); */ //测试引用和指针混合的情况... typedef char* PChar; typedef char& RChar; typedef PChar& RPChar; PChar str = "I am programming."; /* RPChar rpchar; //wrong:not initialized......... rpchar = str; */ RPChar rpchar = str; cout<<str<<endl<<rpchar<<endl; getchar(); } */
/*********** /*结论:对于int& a;引用实际是一种隐式指针,是方便编程而引入的,识别由编译器支持 . 在函数的使用中.可把它理解为跟后面的结合. int (&a); 在传递参数的过程中跟取地址值意思差不多. /* 而在函数内部使用过程中则相当与数值.你可把它看作便利的原因.其实引用& /* 是一个能自动被编译器逆向引用的常量型指针 总结: ... /* A.常规使用: /* 1. int a = 100; /* int &b = a; /* 2. int a = 100; /* int &b = a; /* int &c = b; /* 3. int a = 100; /* int &b; //必须定义时赋值,不同于指针(int a = 100; /* // int *p; p =&a;) /* b = a; /* 4. int &a = 100; //不可将常量赋予引用...
/* const int& a = 100;//可行,作全局看 /* 5. int a = 100; /* int &b = a; /* cout<<&b<<endl; //输出的是a(也是b)的地址..而不是指针 /* // 的地址... /* 6. int a = 100; /* int &b = a; /* int *ptr; /* ptr = &a; /* cout<<a<<b<<*ptr<<endl; //结果是一样的..注意*ptr. . /* 7. int a =100; /* int b = 200; /* int &c = a; /* c = b; //引用可重新赋值........... /* /*B.较难的使用规则: /* 1. 系列错误用法: /* char* str = "I am programming."; /* 定义引用数组:int& a[3]; (定义指针数组:int* a[3]; ) /* 定义引用的指针:int&* a; (定义指针的指针:int** pt r; /* 定义引用的引用:int&& a; /* 2. 可定义指针的引用: int*& a = str; //When it must
/* be initialized when definedv. /* /*C.引用在函数和对象域的使用 /* 1. 做函数返回类型的应用:(当然传递的参数类型为引用,那么
/* 是地址传递方式...) /* int arr[3] = {1,2,3}; /* fook(2) = 100; //函数返回的是引用,做左值时,编译
//器将其当作地址使用.... /* //而如返回的是常量,那当然不可 //赋值 /* int& fook(int index){ return (arr[index]+1);} /* /* 2.返回局部变量 /* int& fook(param){ /* int m = 100; /* return m; /* } /* //在函数结束生命周期后,返回的地址将不可用. /* /* 3.不好的对普通对象的引用 /* class MClass; /* MClass* mcptr; /* mcptr = new MClass(param); /* if(!mcptr) MError("Constructing object failed."); /* MClass& mcref = *mcptr; /* 也许上面的引用可以使你感觉更舒服的使用MClass: 如 /* mcref.function();而不必 /* (*mcptr).function();或mcptr->function(); /* 可是相比之下,一个严重的问题来了:内存泄露.. /* 因为引用不像指针那样明显:你很可能忘记:delete &mcref;
/* /* 4.对对象相关的参数的引用 /* void fook(param1) /* { /* param->function(noramlparam); /* } /* 上面的程式中,我想传递一个对象的地址,从而使用对象的成员函 /* 数..怎么办? /* /* void fook(MClass* mcpptrparam){}; /* 恩,可以. /* 用一用: /* MClass mcptr = new MClass(param); /* fook(mcptr); /* 还有呢: /* MClass mcobj; /* fook(&mcobj); /* /* 当然你也可: /* void fook(MClass& mcrefparam){}; /* 这样引用的对象可在全局数据区、堆栈、栈 /* 5.当然引用真的就是为了方便吗?....... /* 其实正如它在函数返回值里的应用,可由编译器识别为地址,在作 /* 为对象相关参数的 /* 引用里亦存在同样的好处,指针的引用可替换指针的指针,多变的 /* 工作.... /*

|