引用和指针都是存放变量的首地址的,区别在于,指针的话,要同过 *操作符来访问变量内存的值,即要程序员手动来操作。 指针可通过加减(只能加减)来改变该指针变量中的地址的值。而引用的话不能修改地址值,而是封装了访问变量这一步,即自动解引用,不需要额外的操作符,对引用变量的修改,是解析该引用变量里存的地址值访问变量的首地址直接改了该变量的值。而指针是通过*操作符手动解引用。
/*************************数组引用*************************/
#include<iostream>
#include<stdlib.h>
#define Main(n) main##n()
// int a[10]
// int (&ra)[10]
// int a[2][5]
// int (&ra)[2][5]
int main1()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int(&ra)[10](a);//引用一个数组
int i = 0;
for (auto data: ra)//C++11的循环
{
data = i + 5;
std::cout << data << std::endl;
}
std::cout << a << ra << std::endl;
std::cout << &a << &ra << std::endl;
system("pause");
return 0;
}
int main2()
{
int a[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int(&ra)[2][5](a);//引用就是给原来的变量有一个别名同一个地址
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 5; j++)
{
std::cout << " " << ra[i][j];
}
std::cout << "\n";
}
std::cout << a << ra << std::endl;
std::cout << &a << &ra << std::endl;
system("pause");
return 0;
}
/*************************函数指针引用*************************/
int jia(int a, int b)
{
return a + b;
}
int jian(int a, int b)
{
return a - b;
}
//引用函数指针作为函数参数:可以修改函数指针指向的函数
int change( int(* &rp)(int,int) )
{
rp = jian;
}
int main3()
{
int(* p)(int a, int b)(jia);
std::cout << p(1, 2) << std::endl;
int(* &rp)(int a, int b)(p);//引用函数指针
rp=jian;//括号仅仅用于初始化,赋值则只能用 =
//通过引用修改函数指针指向的函数
change(p);
std::cout << p(1, 2) << std::endl;
system("pause");
return 0;
}
/************************函数返回值是一个函数指针的引用***************************/
//changep函数的参数是一个函数指针的引用,而changep函数的返回值还是一个函数指针的引用
int(*& changep(int (*&rp)(int,int)) )(int, int)
{
rp = jian;
return rp;
}
int main4()
{
int(*p)(int a, int b)(jia);
std::cout << p(1, 2) << std::endl;
p = changep(p);
std::cout << p(1, 2) << std::endl;
system("pause");
return 0;
}
/*************************引用的本质*************************/
int main5()
{
//int *p[4];
int a = 1, b = 2, c = 3;
int *px[3] = { &a, &b, &c };
//int& p [4] = {a,b,c };
//引用数组是非法的
system("pause");
return 0;
}
struct mystr
{
int b;
double a;
char c;
//代码区的函数不计入结构体的sizeof
int go()
{
std::cout << "123456789" << std::endl;
}
};
class MyClass
{
char & a;
char & b;
char & c;//引用的本质是指针,直接sizeof引用,就是求引用的数据大小
//引用变量占据4个字节
};
int main6()
{
int num = 10;
int& rnum(num);
double db = 10.9;
double& rdb(db);//直接作用引用的变量
std::cout << sizeof(rnum) << std::endl;
std::cout << sizeof(rdb) << std::endl;
std::cout << sizeof(MyClass) << std::endl;
system("pause");
return 0;
}
/*************************右值引用&&*************************/
int getdata(int&& num)//右值引用,节约内存拷贝,内存优化所必须,直接在寄存器上操作
{
std::cout << num << std::endl;
num += 10;
return num;
}
int main7()
{
int a = 5;
int b = 4;
std::cout << getdata(a+1) << std::endl;
system("pause");
return 0;
}
/*************************引用*************************/
//左值引用和右值引用的区别
//左值,一般可以取地址就是左值
//右值某些情况可以,某些情况不可以取地址
int main8()
{
int a = 3;
int b = a + 1;//右值变左值
std::cout << getdata(std::move(a) ) << std::endl;
//std::move将左值转换为右值,C++11
system("pause");
return 0;
}
/*************************const*************************/
int main9()
{
//const int num(6);
//char str[10]("hello");//限定字符串不被修改
char str[10]="hello";//限定字符串不被修改
const char *pc(str);//指向常量的指针限定了指向的数据无法修改,+1,+2,+3
str[3] = 'x';//可以,
//pc[3] = 'y';//不可以
//*(pc + 3) = 'y';//不可以
pc = "world";
system("pause");
return 0;
}
/*************************const引用*************************/
int main10()
{
// char str[10]("hello");
char str[10]="hello";//限定字符串不被修改
const char(&rstr)[10](str);//常量引用
const char(&rrstr)[10](rstr);//引用可以给另一个引用初始化
str[4] = 'X';
//rstr[4] = 'Y';//不可以
system("pause");
return 0;
}
int main11()
{
int(*p)(int a, int b)(jia);
std::cout << p(1, 2) << std::endl;
int(* const &rp)(int a, int b)(p);//常量引用函数指针
//rp=jian;//不可以
system("pause");
return 0;
}
int main()
{
std::cout<<"/********************main1***************/"<< std::endl;
Main(1);
std::cout<<"/********************main2***************/"<< std::endl;
Main(2);
std::cout<<"/********************main3***************/"<< std::endl;
Main(3);
std::cout<<"/********************main4***************/"<< std::endl;
Main(4);
std::cout<<"/********************main5***************/"<< std::endl;
Main(5);
std::cout<<"/********************main6***************/"<< std::endl;
Main(6);
std::cout<<"/********************main7***************/"<< std::endl;
Main(7);
std::cout<<"/********************main8***************/"<< std::endl;
Main(8);
std::cout<<"/********************main9***************/"<< std::endl;
Main(9);
std::cout<<"/********************main10***************/"<< std::endl;
Main(10);
std::cout<<"/********************main11***************/"<< std::endl;
Main(11);
system("pause");
return 0;
}
输出结果
/********************main1***************/
5
5
5
5
5
5
5
5
5
5
0x22fe500x22fe50
0x22fe500x22fe50
请按任意键继续. . .
/********************main2***************/
1 2 3 4 5
6 7 8 9 10
0x22fe5c0x22fe5c
0x22fe5c0x22fe5c
请按任意键继续. . .
/********************main3***************/
3
-1
请按任意键继续. . .
/********************main4***************/
3
-1
请按任意键继续. . .
/********************main5***************/
请按任意键继续. . .
/********************main6***************/
4
8
12
请按任意键继续. . .
/********************main7***************/
6
16
请按任意键继续. . .
/********************main8***************/
3
13
请按任意键继续. . .
/********************main9***************/
请按任意键继续. . .
/********************main10***************/
请按任意键继续. . .
/********************main11***************/
3
请按任意键继续. . .