c++引用学习

0x01:简单的引用

c语言中没有引用,c++有引用,简化编程

引用的本质就是指针,给已经存在的变量起一个别名,sizeof求大小访问的是引用的变量

引用必须一开始就初始化,一旦初始化,赋值修改将无效;

int num = 10;
int & rnum (num);//变量引用用括号好初始化

1.cpp:

 1 void main()
 2 {
 3     double db(10.9);
 4     double & rdb(db);//引用必须一开始初始化
 5     double dbone(10.8);
 6     rdb = dbone;//引用一旦初始化,代码可以编译,赋值修改无效,
 7     rdb = 8.9;
 8     cout << "db=" << db << " dbone=" << dbone << endl;
 9     cout << "dbsize=" << sizeof(db) << " rdbsize=" << sizeof(rdb) << endl;
10     cin.get();
11 }

1.cpp运行结果:

2.cpp:

 1 struct MyStruct
 2 {
 3     void  print()
 4     {
 5         printf("hello world");
 6     }
 7 };
 8 struct MyStructM
 9 {
10     char  & ch1;//引用的本质是一个地址
11 };
12
13 void main()
14 {
15     cout << sizeof(MyStructM) << endl;//引用的本质就是指针 结果为4
16     cout << sizeof(MyStruct) << endl;//结果是1 表示存在
17         //结构体大小,空结构体一个字节,表示存在
18         //sizeof求结构体,不计入代码区的内容
19     cin.get();
20 }        

引用的声明方法:类型标识符 &引用名=目标变量名;

1     double db(10.9);
2     double & rdb(db);//类型标识符 &引用名=目标变量名
3     cout << &db << &rdb << endl;//取地址,没有类型说明符是取地址
1     double db1 = 10.9;
2     double db2 = 9.8;
3     double *  p(&db1);//定义指针初始化
4
5     double * (&rp)(p);//定义引用的指针,用指针初始化
6
7     double * (&rrp)(rp);//引用可以用另外一个引用初始化
8     

引用可以用另一个引用初始化

0x02:高级引用

引用一个数组:

1         //int a
2     //int & ra;
3         //1,挖掉变量名,2,加上&,3 起别名
4     int a[5] = { 1, 2, 3, 4, 5 };//栈上
5     int(&ra)[5] (a);//引用数组
6     int *p = new int[5]{6, 7, 8, 9, 10};//堆上
7     int * (&rp)(p);//引用堆,引用指针就可以
8             
1 int *p[5] = { &a[0], &a[1], &a[2], &a[3], &a[4] };
2
3 int * (&rp)[5](p);//第一挖掉数组名,第二(& +别名)

任何数组类型的引用:

 1 void main()
 2 {
 3     int a[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }
 4     };
 5
 6     int *p[3][3] = { &a[0][0], &a[0][1], &a[0][2],
 7         &a[1][0], &a[1][1], &a[1][2],
 8         &a[2][0], &a[2][1], &a[2][2] };
 9
10     //int * (&rp)[3][3](p);
11     //任何数组类型的引用
12     //第一挖掉变量名
13     //第二加上()
14     //第三加上&
15     //第四加上引用变量名
16     int * (&rp)[3][3](p);
17
18     for (int i = 0; i < 3; i++)
19     {
20         for (int j = 0; j < 3; j++)
21         {
22             cout << (void *)rp[i][j] << "    " << *rp[i][j] << endl;
23         }
24     }
25     cin.get();
26 }

引用可以突破副本机制:

 1 double db1 = 10.9;
 2 double db2 = 9.8;
 3
 4 void change(double * & p)//突破副本机制,形参,传引用,传地址
 5 {
 6     p = &db2;
 7 }
 8
 9
10 void main()
11 {
12     double *  p(&db1);//定义指针初始化
13     double * (&rp)(p);
14     change(rp);//实际参数传引用形式参数不是引用不能改变成功
15     cout << *p << endl;//结果为9.8
16
17     cin.get();
18 }

0x03:超猥琐的引用

函数指针的引用:

 1 void  print(char *str)
 2 {
 3     cout << str << endl;
 4 }
 5
 6 void main()
 7 {
 8     void  (*p)(char *str)(print);
 9     p("hello world");
10
11     void(* &rp)(char *str)(p);//函数指针的引用
12         cin.get();
13 }    

引用结构体数组:

 1 struct MyStruct
 2 {
 3     int a;
 4     int & ra;
 5
 6 };
 7
 8 void main()
 9 {
10     int num[3]{1, 2, 3};//初始化数组
11     MyStruct  st[3]{{ 10, num[0] }, { 20, num[1] }, { 30, num[2] }};//初始化结构体数组
12     MyStruct * p = new MyStruct[3]{{ 10, num[0] }, { 20, num[1] }, { 30, num[2] }};//堆上
13
14     MyStruct *(&rp)(p);//引用结构体指针
15
16     MyStruct  (& rst)[3](st);//引用结构体数组
17     for (int i = 0; i < 3;i++)
18     {
19         cout << rst[i].a << "  " << rst[i].ra << endl;
20
21     }
22     for (int i = 0; i < 3; i++)
23     {
24         cout << rp[i].a << "  " << rp[i].ra << endl;
25
26     }
27     cin.get();
28 }

引用函数指针数组:

 1 int  add(int a, int b)
 2 {
 3     return a + b;
 4 }
 5 int  sub(int a, int b)
 6 {
 7     return a - b;
 8 }
 9 int  mul(int a, int b)
10 {
11     return a * b;
12 }
13 int  divv(int a, int b)
14 {
15     return a / b;
16 }
17
18 void mainY()
19 {
20     //函数指针数组int(*p[4])(int, int);
21     int(*p[4])(int, int){ add, sub, mul, divv };
22
23     int(*(&rp)[4])(int, int)(p);//引用函数指针数组
24     for (int i = 0; i < 4;i++)//下标循环
25     {
26         cout << rp[i](100, 10) << endl;
27     }
28     for (int(**pp)(int, int) = p; pp < p + 4; pp++)//指针循环
29     {
30         int(** &rpp)(int, int)(pp);//引用二级函数指针
31         cout << (*rpp)(100, 10) << endl;
32
33     }
34     cin.get();
35
36 }

0x04:右值引用

C++11,引用右值

//如果不是左值,手动先拷贝到内存实体,才能引用
//我们无需拷贝,右值引用,编译器会自动帮我们拷贝到内存/

 1 void print(int && rint)//右值引用,一旦引用常住内存,编译器自己维护
 2 {
 3     cout << rint << endl;
 4     cout << (void*)&rint << endl;
 5     cout << "\n\n";
 6 }
 7
 8
 9 void  main()
10 {
11     int x = 30;
12     print(x + 1);
13
14     cout << "\n\n";
15     print(x + 2);
16
17     cout << "\n\n";
18     print(x + 3);
19
20     cout << "\n\n";
21     print(x + 4);
22     cin.get();
23
24 }
 1 void  main()
 2 {
 3     int x = 3;
 4     print(x + 1);
 5     int && rint(x + 3);//&&引用没有内存实体的临时变量
 6     cout << rint << endl;
 7     cout << "\n\n";
 8
 9     cout << rint << endl;
10     cout << (void*)&rint << endl;
11     cin.get();
12 }

//如果不是左值,手动先拷贝到内存实体,才能引用
//我们无需拷贝,右值引用,编译器会自动帮我们拷贝到内存/

时间: 2024-10-11 12:13:49

c++引用学习的相关文章

C++语言引用学习

//C++的引用类型: //这里理解为别名 //1.基本数据类型的引用:& #include <iostream> using namespace std; int main() { int a = 3; int &b = a; //引用类型必须初始化 b = 10; cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; retu

转发:PowerDesigner的常用设置(引用学习绘制类图、ER图等)

1.由pdm生成建表脚本时, 字段超过15字符就发生错误(oracle) 原 因未知,解决办法是打开PDM后,会出现Database的菜单栏,进入Database - Edit Current DBMS -script-objects-column-maxlen,把value值调大(原为30),比如改成60.出现表或者其它对象的长度也有这种错误的 话都可以选择对应的objects照此种方法更改! 或者使用下面的这种方法: 生成建表脚本时会弹出Database generation提示框:把opt

web.xml文件的 xsd引用(或dtd引用)学习

1. 为什么web.xml会有不同版本的xsd引用: JDK依赖变化: 或 servlet(JAVA EE)自身API的改变: 2. 为什么会有dtd和xsd两个版本的区别 我是在这篇文章中看到的,作者似乎拷贝了一段API说明: There are two ways to specify the schema for a the web.xml file (Deployment Descriptor). DTD - Document Type Definition XSD - XML Schem

DDL、DML和DCL的比较【引用学习】

1.DDL 1-1.DDL的概述 DDL(Data Definition Language 数据定义语言)用于操作对象和对象的属性,这种对象包括数据库本身,以及数据库对象,像:表.视图等等,DDL对这些对象和属性的管理和定义具体表现在Create.Drop和Alter上.特别注意:DDL操作的“对象”的概念,”对象“包括对象及对象的属性,而且对象最小也比记录大个层次.以表举例:Create创建数据表,Alter可以更改该表的字段,Drop可以删除这个表,从这里我们可以看到,DDL所站的高度,他不

C 语言指针 引用学习

举个实例 1 #include<stdio.h> 2 int test_num; 3 void func(int *p) 4 { 5 p = &test_num; 6 } 7 int main(void) 8 { 9 int *p; 10 func(p); 11 *p = 1000; 12 return 0; 13 } 运行出core 反汇编: gcc -S t3.c -o t3.s .file "t3.c" .comm test_num,4,4 .text .gl

gulp学习

说明:文章内容来源http://www.ydcss.com/archives/424,此处做引用学习. 1.gulp.src(globs[, options]) 1.1.说明:src方法是指定需要处理的源文件的路径,gulp借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入,gulp.src返回当前文件流至可用插件: 1.2.globs:  需要处理的源文件匹配符路径.类型(必填):String or StringArray: 通配符路径匹配示例: "src/a.j

学术休假期 项目4-点和距离

问题及代码: 读程序,写出函数的定义,注意其中枚举类型的用法 /* *Copyright (c)2014,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:点和距离.cpp *作 者:冷基栋 *完成日期:2015年2月26日 *版 本 号:v1.0 */ #include <iostream> #include <Cmath> using namespace std; enum SymmetricStyle {axisx,axisy,point}

HTTP报文

引用 学习Web开发不好好学习HTTP报文,将会“打拳不练功,到老一场空”,你花在犯迷糊上的时间比你沉下心来学习HTTP的时间肯定会多很多. HTTP请求报文解剖 HTTP请求报文由3部分组成(请求行+请求头+请求体): 下面是一个实际的请求报文: ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE.HEAD.OPTIONS.PUT.TRACE.不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter

JAVA面试题最全集

JAVA面试题最全集 2009-01-19 15:40 3458人阅读 评论(0) 收藏 举报 java面试ejbservletstringhashmap 一.Java基础知识1.Java有那些基本数据类型,String是不是基本数据类型,他们有何区别.2.字符串的操作:  写一个方法,实现字符串的反转,如:输入abc,输出cba  写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc.3.数据类型之间的转换  如何将数值型字符转换为数字(Integer,Doubl