引用 数组引用与指针引用 值传递\引用传递\指针传递

引用

引用是给一个变量起别名,引用没有自己独立的空间,引用要与它所引用的变量共享空间。引用在定义的时候要进行初始化,引用一经初始化,不能重新指向其他变量

const 引用

const引用是指向const对象的引用

const int ival = 1024;
const int& refVal = ival; //ok:both reference and object are const
int &ref2 = ival;         //error:nonconst reference to a const object 防止对引用的更改,更改了const对象

int ival = 1024;
const int& refVal = ival; // ok

const引用,类型转换的情况

double val3 = 3.14;
const int& ref4 = val3;  //等价于 int tmp = val3; const int& ref4 = temp;

int val4 = vals3;    //erro:duoble不能转为int

引用作参数传递

值传递,对形参值的改变不能对实参产生影响。引用作为参数对形参的任何操作都能改变相应的实参的数据。
引用作参数时,函数的实参与形参在内存中共用存储单元,因此形参的变化会使实参同时变化

函数返回引用

函数返回引用的一个主要目的是可以将函数放在赋值运算符的左边

int a[] = {0,1,2,3,4};

int &index(int i)
{
    return a[i];
}

int main()
{
    index(3) = 100; //函数放在赋值运算符的左边,引用在函数返回的时候初始化
}

函数返回引用需要注意的地方是不能返回对局部变量的引用

#include <iostream>
using namespace std;


int &add(int a, int b)
{
    int sum;
    sum = a + b;
    return sum;
}

int main(void)
{
    int n = add(3, 4);
    int &n2 = add(5, 6);
    cout << "n2=" << n2 << endl;
    cout << "n=" << n << endl;
    cout << "n2=" << n2 << endl;
    return 0;
}

程序结果输出

n2=11
n=7
n2=1474313670

返回局部变量的引用导致的后果。函数返回的是局部变量sum的引用,而n2 本身又是引用,即引用着原来sum拥有的那块区域,第一次打印没有出错是因为本来写在sum 区域上的值11尚未被覆盖,而再运行两条打印语句后再次打印,很可能原来属于sum的区域变dirty了,被覆盖了其他不确定的值,每次打印都不会是一个定值

n本身是个变量,函数返回时立马保存了sum所属区域的值,局部变量在函数栈上释放,但本来区域的值第一时间还是原来的值,但经过程序运行,堆栈内存区域重用,一般就被覆盖了

引用与指针区别

  1. 引用访问一个变量是直接访问,而指针是间接访问
  2. 引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间
  3. 引用一经初始化不能再引用其它变量,而指针可以
    c++建议尽可能使用引用,不得已时使用指针

数组引用与指针引用

#include<iostream>
using namespace std;

void func1(char s[10]) // char *s 
{
    cout<<"func1"<<endl;
    cout<<sizeof(s)<<endl;
    cout<<s[1]<<endl;
    s[1] = 'B';
    cout<<s[1]<<endl;   
}

void func2(char (&ss)[100])  // 数组引用
{
    cout<<"func2"<<endl;
    cout<<sizeof(ss)<<endl;
    cout<<ss[1]<<endl;
    char * f2 = ss;
    f2[1] = 'D';
    cout<<f2[1]<<endl;
}


void func3(char * const &  sss)// 指针引用
{
    cout<<"func3"<<endl;
    cout<<sizeof(sss)<<endl;
    cout<<sss[1]<<endl;
    char * f3 = sss;
    f3[1] = 'F';
    cout<<f3[1]<<endl;
}

int main(void)
{

    char s[10] = {'a', 'b'};
    char ss[100] = {'c', 'd'};
    char sss[1000] = {'e', 'f'};

    cout<<"main fun"<<endl;
    cout<<sizeof(s)<<endl;

    func1(s);
    func2(ss);
//  func2(sss);  error
    func3(sss);

    return 0;
}

值传递\引用传递\指针传递

值传递 实参初始化形参,分配空间,将实参内容拷贝到形参
引用传递 实参初始化形参时,不分配空间
指针传递 本质是值传递,实参初始化形参,分配指针本身的空间。如果要修改指针的地址 ,单纯的用指针传递是不行的。需要采用**,*&的方式传递