文档章节

指针和引用

o
 osc_fmg49rzg
发布于 2019/03/22 08:35
字数 1123
阅读 5
收藏 0

1.复合类型

  复合类型是指基于其他类型定义的类型,指针和引用就是复合类型

2.指针

2.1概念

  指针是一种复合类型,它指向某个对象,它本身也是一个对象,指针的值是它指向对象的地址,同时指针也有它自己的地址

void func(int* p)
{
    int m_value = 1;
    p = &m_value;
}

int main()
{
    int n = 2;
    int *pn = &n;
    cout << *pn << endl;
    func(pn);
    cout << *pn << endl;

    return 0;
}

2.2sizeof指针

  sizeof指针得到是指针本身的大小(字节数),sizeof引用得到的是所引用对象的大小

2.3指针的大小

  指针大小是由CPU实际运行的寻址位数决定,与所指向的对象的类型无关,寻址位数为16位则为2字节,32位为4字节(通常情况下),64位为8字节

2.4空指针

  不指向任何对象的指针,它的值为NULL

2.5跟指针有关的操作符

1)取地址符&

2)解引用符*

2.6指针的比较

  同类型的指针可以比较,不同类型的指针比较会报错

3.引用

3.1概念

  引用仅仅是给对象起了一个别名,实质上跟原来的对象是同一个东西;定义引用时,必须初始化

3.2引用的底层实现

int main()
{
    int x=1;
    int &b=x;
    return 0;
}
//汇编语言:vs编译环境在调试模式下,右键鼠标菜单->反汇编
9:       int x = 1;     //源代码 
00401048   mov         dword ptr [ebp-4],1  //汇编代码  
10:      int &b = x;    //源代码
0040104F   lea         eax,[ebp-4]          //汇编代码
00401052   mov         dword ptr [ebp-8],eax//汇编代码

  mov dword ptr [ebp-4],1   //把1赋值给ebp(栈底指针)-4的地址
  lea eax,[ebp-4]     //把ebp-4的地址赋值给寄存器eax
  mov dword ptr [ebp-8],eax   //把寄存器eax里的值赋值给ebp-8的这块地址
上述三行代码的作用就是将1赋值给x,然后将x的地址赋值给了引用b,所以,在底层,引用存放的是被引用对象的地址
而在内存中,它是这样的:

  所以有这么一种说法:引用的底层是通过类似指针的方式实现的

3.3如何获得引用的地址和其真正的值

int main()
{
    int  a = 1;
    int&  b = a;
    cout << "a:address->" << &a << endl;
    cout << "b:address->" << &b << endl;

    getchar();
    return 0;
}
运行结果: 
a:address->0031FD54 
b:address->0031FD54

  引用b的地址和变量a的地址一样,这种方法不能得到引用b的地址

int main()  
{  
   int x = 1;  
   int y = 2;  
   int &b = x;  
   printf("&x=%x, &y=%x, &b=%x, b=%x\n",&x,&y,&y-1,*(&y-1));  
   return 0;
 }  
运行结果: 
&x=12ff7c, &y=12ff78, &b=12ff74, b=12ff7c

  引用b的地址可以间接通过&y-1来得到b的地址;*(&y-1) 就是b的值,从结果可以知道,b的值即x的地址,从而可以知道,从底层实现来看,引用的确存放的是被引用对象的地址,只不过,这些对于高级程序员来说是透明的,编译器屏蔽了这些细节

4.函数的值传递、指针传递、引用传递

1)值传递:发生拷贝,形参是实参的拷贝,改变形参的值并不会影响实参的值

2)指针传参时,函数会创建一个副本指针(局部变量),这个副本指针的值和实参的值相同,副本指针的地址和实参的地址不同,函数可以通过副本指针对实参指针所指向的对象进行操作

3)引用传参时,从底层看,形参其实也是作为局部变量在栈中开辟了空间,这个局部变量真实存放的其实是实参的地址(可从汇编层看到),在函数体内任何对形参的操作都会通过间接寻址的方式(即通过这个存放的地址去访问主函数中的实参)影响到主函数的实参;但是编译器隐藏了这些细节,通过编译器查看,形参和实参的地址相同,形参和实参的值也相同

   

4)效率上讲,指针传递和引用传递比值传递效率高,编程过程中想要传递大的类对象时,值传递由于要拷贝整个对象将耗费更多的时间和空间

参考资料

https://blog.csdn.net/lws123253/article/details/80353197

上一篇: 信号(signal)
下一篇: select、poll、epoll
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

在云函数 SCF 里为 Next.js 跑 SSR

很多时候我们都希望首屏速度快,SEO 友好,那么相比于客户端渲染,SSR 渲染将是这方面的优势。Next.js、Nuxt.js 都是 SSR 框架。本篇文章将介绍 Next.js。 通常我们在部署 SSR 的时候,会担心...

腾讯云Serverless
28分钟前
19
0
一文带你初窥软件测试行业

三大原始问题一——软件测试是什么? 在一定条件下对软件系统进行审核、运行、评估,检验软件系统是否满足规定需求或者找出预期结果与实际结果之间的差别。为软件产品的质量和评价提供依据。...

a伟正是在下
35分钟前
17
0
如何避免APK文件的反向工程? - How to avoid reverse engineering of an APK file?

问题: I am developing a payment processing app for Android, and I want to prevent a hacker from accessing any resources, assets or source code from the APK file. 我正在开发适用......

富含淀粉
38分钟前
13
0
python 抓取 微信公众号文章

1、下载 Fiddler 安装 具体操作传送门 2、第一步已完成,入门开始吧 首先确保有微信客户端(推荐PC,移动端会多一些操作) 启动微信、Fiddler ,然后找到需要抓取的公众号(还是关注一下吧,...

acclea
55分钟前
9
0
JS深拷贝

let arr1 = [1, 2, 3, 4, { name: 'hh'}]/浅克隆****/// 1,展开运算符let arr2 = [...arr1]// 2.splicelet arr3 = arr1.splice(0)/深克隆****/// 1.基...

何祯粮
58分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部