C++深度解析教程笔记3-const引用,内联函数


本文学习自狄泰软件学院 唐佐林老师的 C++深度解析教程,图片全部来源于课程PPT,仅用于个人学习记录

第5课 - 引用的本质分析

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实验-const引用

#include <stdio.h>

void Example()
{
    printf("Example:\n");
    
    int a = 4;
    const int& b = a;
    int* p = (int*)&b;
    
   // b = 5;
/*
E:\test>c++ 5-1.cpp
5-1.cpp: In function 'void Example()':
5-1.cpp:11:9: error: assignment of read-only reference 'b'
     b = 5;

*/
    
    *p = 5;
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
// 注释*p = 5; 
//a = 4
//b = 4
//不注释*p = 5; 
//a = 5
//b = 5
}

void Demo()
{
    printf("Demo:\n");
    
    const int& c = 1;
    int* p = (int*)&c;
    
    //c = 5;
/*
E:\test>c++ 5-1.cpp
5-1.cpp: In function 'void Demo()':
5-1.cpp:33:9: error: assignment of read-only reference 'c'
     c = 5;
*/
    
    //*p = 5;
    
    printf("c = %d\n", c);
//  //*p = 5;  output :c = 1
//     *p = 5;  output :c = 5               
}

int main(int argc, char *argv[])
{
    Example();
    
    printf("\n");
    
    Demo();

    return 0;
}

在这里插入图片描述

实验-引用的本质

#include <stdio.h>

struct TRef
{
    char& r;
};

int main(int argc, char *argv[])
{ 
    char c = 'c';
    char& rc = c;
    TRef ref = { c };
    
    printf("sizeof(char&) = %d\n", sizeof(char&));
    printf("sizeof(rc) = %d\n", sizeof(rc));
    
    printf("sizeof(TRef) = %d\n", sizeof(TRef));
    printf("sizeof(ref.r) = %d\n", sizeof(ref.r));

    return 0;
}
/*
cmd g++:
sizeof(char&) = 1
sizeof(rc) = 1
sizeof(TRef) = 8
sizeof(ref.r) = 1
codeblock:
sizeof(char&) = 1
sizeof(rc) = 1
sizeof(TRef) = 4
sizeof(ref.r) = 1


*/

在这里插入图片描述

void f(int & a)
{
a=5;}
等价于
void f(int * const a)
{
*a=5;
}

实验-引用所占空间大小

#include <stdio.h>

struct TRef
{
    char* before;
    char& ref;
    char* after;
};

int main(int argc, char* argv[])
{
    char a = 'a';
    char& b = a;
    char c = 'c';

    TRef r = {&a, b, &c};

    printf("sizeof(r) = %d\n", sizeof(r)); //4+1+4 X
    printf("sizeof(r.before) = %d\n", sizeof(r.before));//4 ?
    printf("sizeof(r.after) = %d\n", sizeof(r.after));//4?
    printf("&r.before = %p\n", &r.before);//
    printf("&r.after = %p\n", &r.after);//
    printf("r.before = %p\n", r.before);//4
    printf("r.after = %p\n", r.after);//

    return 0;
}
/*
g++ cmd:
sizeof(r) = 24
sizeof(r.before) = 8
sizeof(r.after) = 8
&r.before = 000000000061FDF0
&r.after = 000000000061FE00
r.before = 000000000061FE17
r.after = 000000000061FE16
DF0 与E00 差16  ;sizeof(r.before) = 8,说明引用占的存储空间为8个字节
24-8-8=8;说明引用占的存储空间为8个字节

codeblock(32):
sizeof(r) = 12
sizeof(r.before) = 4
sizeof(r.after) = 4
&r.before = 0060FEEC
&r.after = 0060FEF4
r.before = 0060FEFB
r.after = 0060FEFA
EC 与F4 差8  ;sizeof(r.before) = 4,说明引用占的存储空间为4个字节
12-4-4=4;说明引用占的存储空间为4个字节

*/

vs2010反汇编

    char a = 'a';
00E836DE  mov         byte ptr [a],61h  //将97放到名称为a的一个字节的内存空间
    char& b = a;
00E836E2  lea         eax,[a]  //将a的地址取出,放到eax寄存器中
00E836E5  mov         dword ptr [b],eax  //将eax中的内容,放入b标识符对应的内存空间 大小为4个字节(dword)

实验-局部变量的引用

#include <stdio.h>
//返回引用,局部变量
// warning: reference to local variable 'd' returned [-Wreturn-local-addr]
    // int d = 0;
int& demo()
{
    int d = 0;

    printf("demo: d = %d\n", d);

    return d;
}
//返回引用,静态变量
int& func()//int * const
{
    static int s = 0;

    printf("func: s = %d\n", s);

    return s;
}

int main(int argc, char* argv[])
{
    int& rd = demo();
    int& rs = func();

    printf("\n");
    printf("main: rd = %d\n", rd);
    printf("main: rs = %d\n", rs);
    printf("\n");

    rd = 10;
    rs = 11;

    demo();
    func();

    printf("\n");
    printf("main: rd = %d\n", rd);
    printf("main: rs = %d\n", rs);
    printf("\n");

    return 0;
}
/*
demo: d = 0
func: s = 0

main: rd = 1980251346  //野指针
main: rs = 0

demo: d = 0
func: s = 11

main: rd = 1980251346  //rd代表的内存空间无意义
main: rs = 11
*/

小结

引用作为变量别名而存在旨在代替指针
const引用可以使得变量具有只读属性
引用在编译器内部使用指针常量实现
引用的最终本质为为指针
引用可以尽可能的避开内存错误

第6课 - 内联函数分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验-内联函数

在这里插入图片描述

    int c = func(++a, b);
001536EC  mov         eax,dword ptr [a]  
001536EF  add         eax,1  
001536F2  mov         dword ptr [a],eax  
001536F5  mov         ecx,dword ptr [b]  
001536F8  push        ecx  
001536F9  mov         edx,dword ptr [a]  
001536FC  push        edx  
001536FD  call        func (1511DBh)  //编译器未允许内联请求
00153702  add         esp,8  
00153705  mov         dword ptr [c],eax 

设置允许编译器内联

在这里插入图片描述
在这里插入图片描述

实验-forceinline

//vs2010
#include <stdio.h>

__forceinline   //vs2010 设置内联函数扩展
//__attribute__((always_inline))//gcc
//inline 与 __forceinline作用一样
int add_inline(int n);

int main(int argc, char *argv[])
{
    int r = add_inline(10);

    printf(" r = %d\n", r);

    return 0;
}

inline int add_inline(int n)
{
    int ret = 0;

    for(int i=0; i<n; i++)
    {
        ret += i;
    }

    return ret;
}
    int c = func(++a, b);
00271036  mov         eax,dword ptr [a]  
00271039  add         eax,1  
0027103C  mov         dword ptr [a],eax  
0027103F  mov         ecx,dword ptr [a]  
00271042  cmp         ecx,dword ptr [b]  
00271045  jge         main+3Fh (27104Fh)  
00271047  mov         edx,dword ptr [a]  
0027104A  mov         dword ptr [ebp-10h],edx  
0027104D  jmp         main+45h (271055h)  
0027104F  mov         eax,dword ptr [b]  
00271052  mov         dword ptr [ebp-10h],eax  
00271055  mov         ecx,dword ptr [ebp-10h]  
00271058  mov         dword ptr [c],ecx  

在这里插入图片描述
在这里插入图片描述

//内联不成功
    int r = add_inline(10);
0010101C  push        0Ah  
0010101E  call        add_inline (10100Ah)  
00101023  add         esp,4  
00101026  mov         dword ptr [r],eax  

//内联成功
    int r = add_inline(10);
0026102C  mov         dword ptr [ebp-8],0  
00261033  mov         dword ptr [ebp-0Ch],0  
0026103A  jmp         main+35h (261045h)  
0026103C  mov         eax,dword ptr [ebp-0Ch]  
0026103F  add         eax,1  
00261042  mov         dword ptr [ebp-0Ch],eax  
00261045  cmp         dword ptr [ebp-0Ch],0Ah  
00261049  jge         main+46h (261056h)  
0026104B  mov         ecx,dword ptr [ebp-8]  
0026104E  add         ecx,dword ptr [ebp-0Ch]  
00261051  mov         dword ptr [ebp-8],ecx  
00261054  jmp         main+2Ch (26103Ch)  
00261056  mov         edx,dword ptr [ebp-8]  
00261059  mov         dword ptr [r],edx  

在这里插入图片描述

小结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值