太仓网站建设网站推广,WordPress链接点击次数统计,传奇网站怎么做,wordpress用那个采集器引用 引用的基本使用引用的起源引用的语法引用的本质引用的注意事项引用和指针 引用作为函数参数引用作为函数的返回值常量引用其它用返回值方式调用函数#xff08;case 1#xff09;用函数的返回值初始化引用的方式调用函数#xff08;case 2#xff09;用返回引用的方式… 引用 引用的基本使用引用的起源引用的语法引用的本质引用的注意事项引用和指针 引用作为函数参数引用作为函数的返回值常量引用其它用返回值方式调用函数case 1用函数的返回值初始化引用的方式调用函数case 2用返回引用的方式调用函数case3用函数返回的引用作为新引用的初始化值的方式来调用函数case4 引用的基本使用
引用的起源
将变量名作为实参值传递改变形参实参并不改变。将指针作为实参实际上采用的也是值传递只不过这里的值指的是变量的地址。传送变量的别名传递的是变量的地址所以二者本身完全是同一个地址的变量。
引用的语法
数据类型 别名变量名 引用声明符别名和原变量代表的是同一变量单元在传参数时别名和原变量可以取同一个名字
引用的本质
给变量起别名。引用的本质是一个指针常量int * const p a;是个指针该指针是常量指针常量的指向不可更改但是该地址内的值可以更改这就是引用一旦初始化为某一变量的别名后再不能更改的原因。 在外部看可以简化如下 code:#include iostream#include stringusing namespace std;int main(){int a 666;int b a; // 编译器内部自动转化为 int* const b a;b 888; // 发现是引用自动转化为 *b888;cout a的值: a endl;system(pause);}
result:引用的注意事项
引用在声明时必须同时初始化。必须引用合法的内存空间int a10; 错的。在声明一个变量的引用后不能再作为其它变量的别名。
code:int a 10;cout address of a a , value of a a endl;int x 20;cout address of x x , value of x x endl;int b a; //引用声明cout address of b b , value of b b endl;b x; //是变量赋值而不是将该引用作为其它变量的引用 cout address of a a , value of a a endl;cout address of b b , value of b b endl; result:address of a000000D209FCFB34, value of a10address of x000000D209FCFB54, value of x20address of b000000D209FCFB34, value of b10address of a000000D209FCFB34, value of a20 // a的值变为20address of b000000D209FCFB34, value of b20引用和指针
不必设立指针变量指针变量要开坡另外的内存空间其内容是地址。二引用变量不是第一个独立的变量不单独占用内存空间。在函数调用时并不需要再变量名前加取址符。在a前面有类型时是引用如 int a, 否则为取址符。改变形参对于引用和指针实参同时改变。
引用作为函数参数
引用作为函数形参形参改变实参改变。不需要像指针那么复杂的操作。
值传递仅仅改变形参实参不发生变化
code:
#include iostream
#include string
using namespace std;void swap(int x, int y)
{cout 值传递swap之前x, y分别为: x , y endl;int temp;temp x;x y;y temp;cout 值传递swap之后x, y分别为: x , y endl;
}int main()
{int a1 666;int b1 888;cout 值传递swap之前a1, b1分别为: a1 , b1 endl;swap(a1, b1);cout 值传递swap之后a1, b1分别为: a1 , b1 endl;system(pause);return 0;
}result:值传递swap之前a1, b1分别为: 666,888值传递swap之前x, y分别为: 666,888值传递swap之后x, y分别为: 888,666值传递swap之后a1, b1分别为: 666,888指针作为参数传递的是实参的地址值那么对该地址的操作会影响到实参。
code:
#include iostream
#include string
using namespace std;void swap_pt(int *x, int *y)
{cout x, y地址分别为: x , y endl;cout 值传递swap之前*x, *y分别为: *x , *y endl;int temp;temp *x;*x *y;*y temp;cout 值传递swap之后*x, *y分别为: *x , * y endl;
}int main()
{int a1 666;int b1 888;cout a1, b1地址分别为: a1 , b1 endl;cout 值传递swap之前a1, b1分别为: a1 , b1 endl;swap_pt(a1, b1);cout 值传递swap之后a1, b1分别为: a1 , b1 endl;system(pause);return 0;
}resulta1, b1地址分别为: 00000006F5D4F904,00000006F5D4F924值传递swap之前a1, b1分别为: 666,888x, y地址分别为: 00000006F5D4F904,00000006F5D4F924值传递swap之前*x, *y分别为: 666,888值传递swap之后*x, *y分别为: 888,666值传递swap之后a1, b1分别为: 888,666引用传递实参和形参是同一变量
code:
#include iostream
#include string
using namespace std;void swap_reference(int x, int y)
{cout x, y地址分别为: x , y endl;cout 引用传递swap之前x, y分别为: x , y endl;int temp;temp x;x y;y temp;cout 引用传递swap之后x, y分别为: x , y endl;
}int main()
{int a1 666;int b1 888;cout a1, b1地址分别为: a1 , b1 endl;cout 引用传递swap之前a1, b1分别为: a1 , b1 endl;swap_reference(a1, b1);cout 引用传递swap之后a1, b1分别为: a1 , b1 endl;system(pause);return 0;
}result:a1, b1地址分别为: 0000003871CFFB14,0000003871CFFB34引用传递swap之前a1, b1分别为: 666,888x, y地址分别为: 0000003871CFFB14,0000003871CFFB34引用传递swap之前x, y分别为: 666,888引用传递swap之后x, y分别为: 888,666引用传递swap之后a1, b1分别为: 888,666引用作为函数的返回值
要返回局部变量的引用。如果函数的返回是个引用则函数的调用可以作为左值。不能返回函数内部通过new分配的内存的引用。
//不要返回局部变量的引用局部变量在栈区调用完毕后释放有可能第一次使用该引用时编译器可能还没释放但是后面会出错
code:#include iostream#include stringusing namespace std;int test(){int x 100;return x;}int main(){int ref test();cout ref的值1: ref endl;cout ref的值2: ref endl;system(pause);}
result:ref的值1:632365056ref的值2:632365056code:#include iostream#include stringusing namespace std;int test_static(){static int x 0;x 666;return x;}int main(){int ref test_static(); // ref是函数中x的别名test_static() 2000; // test_static()返回的就是x的别名相当对x2000cout ref的值: ref endl;system(pause);}result:ref的值:2000常量引用
可以用于形参防止误操作。 code:#include iostream#include stringusing namespace std;int main(){int a 666;//int b 888; // 报错必须引用合法的内存空间888都不知道地址是什么const int b 888; // 自动转化为 int temp 888; const int b temp; 只能使用别名//b 30; // 不可再修改cout b的值: b endl;system(pause);}code#include iostream#include stringusing namespace std;void print_data(const int a){//a 100; //错误已经不可再修改cout a a endl;}int main(){int a 666;print_data(a);}
resulta 666其它
code:#includeiostreamusing namespace std;float temp;float fn1(float r) {temp r * r * 3.14;return temp;}float fn2(float r) { //说明返回的是temp的引用换句话说就是返回temp本身temp r * r * 3.14;return temp;}int main() {float a fn1(5.0); //case 1返回值//float bfn1(5.0); //case 2:用函数的返回值作为引用的初始化值 [Error] invalid initialization of non-const reference of type float from an rvalue of type float//有些编译器可以成功编译该语句但会给出一个warning float c fn2(5.0); //case 3返回引用 float d fn2(5.0); //case 4用函数返回的引用作为新引用的初始化值cout a endl;//78.5//coutbendl;//78.5cout c endl;//78.5cout d endl;//78.5system(pause);return 0;}用返回值方式调用函数case 1
返回全局变量temp的值时C会在内存中创建临时变量并将temp的值拷贝给该临时变量。当返回到主函数main后赋值语句afn1(5.0)会把临时变量的值再拷贝给变量a。
用函数的返回值初始化引用的方式调用函数case 2
函数fn1()是以值方式返回时首先拷贝temp的值给临时变量。返回到主函数后用临时变量来初始化引用变量b使得b成为该临时变量到的别名。由于临时变量的作用域短暂在C标准中临时变量或对象的生命周期在一个完整的语句表达式结束后便宣告结束也就是在语句float bfn1(5.0);之后 所以b面临无效的危险很有可能以后的值是个无法确定的值 可以如下操作
code:int xfn1(5.0); //x不释放int bx;用返回引用的方式调用函数case3
函数fn2()的返回值不产生副本而是直接将变量temp返回给主函数即主函数的赋值语句中的左值是直接从变量temp中拷贝而来也就是说c只是变量temp的一个拷贝而非别名 这样就避免了临时变量的产生。尤其当变量temp是一个用户自定义的类的对象时这样还避免了调用类中的拷贝构造函数在内存中创建临时对象的过程提高了程序的时间和空间的使用效率。 用函数返回的引用作为新引用的初始化值的方式来调用函数case4
函数fn2()的返回值不产生副本而是直接将变量temp返回给主函数。在主函数中一个引用声明d用该返回值初始化也就是说此时d成为变量temp的别名。由于temp是全局变量所以在d的有效期内temp始终保持有效故这种做法是安全的。 注意 本文中的部分内容来自伯乐在线