一、 函数返回值
1.如果返回值小于4byte 用寄存器eax带回返回值
2.如果返回值大于4byte小于8btye,用两个寄存器eax edx带回返回值
3.如果返回值大于8byte,在调用前main函数中产生临时量接受返回值
二、临时量生成的三种情况
1.函数调用之前产生,目的是为了接受函数的返回值
2.函数的return语句处
3.函数调用之后
三、引用的条件
1.必须进行初始化
2.必须能取地址
内置类型产生的临时量都是常量 通过eax edx带回 不能修改
自定义类型产生的临时量是变量 可以进行修改
四、函数传参
1.传值
函数调用过程会产生一个临时变量用形参的形式代替,
最终把实参得值传给新分配的临时变量,这种传值避免了
函数恶意修改所传的值;
2.传地址
传地址坏处就是不能控制该值被程序恶意修改
好处就是如果程序需要改变这个值 那么就可以改变 无束缚
3.传引用
传引用并没有引用新的变量 只是给已存在的变量起了一个别名
编译器不会为这个别名开辟内存空间 这个引用和引用的变量使用同一内存空间
五、普通类型作为返回值
//函数返回值为普通类型的返回值接收情况
int GetInt()
{
int value = 10;
return value;
}
int main ()
{
//int &a = GetInt(); //error 函数返回值大小为4byte 由寄存器eax带回 对立即数不能取地址
//引用的条件 :必须进行初始化 必须能取地址
//int a = GetInt();// OK //用一个与函数返回值同类型的变量接收
//int *a= &GetInt(); //error 函数的返回值是一个立即数 不能取地址
/*使用常引用接收返回值的实质有两步
1.在调用GetInt函数后产生一个常临时量
const int tmp = GetInt();
2.然后在main函数的常引用 引用这个临时量 从而接收到返回值
const int &a = tmp;
*/
const int &a = GetInt();//error a引用的是一个常临时量的地址
cout<<"a = "<<a<<endl;
return 0;
}
六、指针作为返回值的情况
//函数返回值为指针的返回值接收情况
int* GetIntPtr()
{
static int value = 10;//数据存放在.data段
return &value;
//lea eax [value]
//将return之后的内容的地址通过eax带回
}
int main()
{
//int *p = &GetIntPtr();//error 返回值等于4byte字节 由eax带回 对立即数不能取地址
//int *&p = GetIntPtr();//error 指针引用 由于函数返回值有eax带回 不能对立即数取地址
/*使用常引用接收返回值的实质有两步
1.在GetIntPtr()函数调用之后产生常临时量接收返回值
int *const tmp = GetIntPtr();
2.然后在main函数的常引用 引用这个常临时量 从而接收到返回值
int *const &a = tmp;
*/
// int *const &p = GetIntPtr();// 0K
//int a = *GetIntPtr();// OK 后面返回指针在解引用 是一个具体的值 可以用a接收
//int &a = *GetIntPtr(); //OK a引用的是解引用之后的变量的内存 类似于下面的例子
/*
int a = 10;
int *p = &a;
int &b = *p;//成立 b引用的是p所指向的a那块内存 而不是a里的内容
所以上述的int &a = *GetIntPtr();成立
*/
cout<<a<<endl;
return 0;
}
七、引用作为返回值
int& GetIntRef()
{
static int value = 10;//数据存放在.data段
return value;
//lea eax [value]
//将return之后的内容的地址通过eax带回
}
int main()
{
//int p = GetIntRef();// OK 会对eax带回的地址进行解引用 将值赋给p p = *eax
//int *p = &GetIntRef(); // OK eax直接带回的就是地址 所以指针p可以指向这片空间 int *p = &value;
int &p = GetIntRef(); //OK p引用eax带回来的地址 级int &p = &value;
}