指针
什么是指针?
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:
type *var-name;Code language: JavaScript (javascript)
在这里,type 是指针的基类型,它必须是一个有效的 C++ 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:
int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
double *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */Code language: JavaScript (javascript)
int a;
a = 1;
int b = 2;
int *c = &b; //c是指针 并不是*c 星c
//&是取地址符 &b就是获取b的地址 赋值到c这个指针Code language: JavaScript (javascript)
#include <iostream>
using namespace std;
int main() {
float a,b,c;
cout << &a << endl;
cout << &b << endl;
int *_a;
_a = &a;
cout << _a << endl;
return 0;
}Code language: PHP (php)
获取一个变量的地址 可以使用 & 例如
int a;
a = 123;
int *_zz = &a;Code language: HTML, XML (xml)
#include <iostream>
using namespace std;
int main() {
int a;
a = 123;
int *_zz = &a;//变量的地址 只能使用相同类型的指针 例如这里的int指针 来存放 否则
float *_ff = &a;//类型不一样会报错
return 0;
}Code language: PHP (php)
我们的例子
//指针也有数据类型
int *_pc;
float *_pf;
double *_pd;
bool *_pb;
//指针的类型之间有什么区别
//可能有些同学有疑问?
//明明说指针是存储地址 地址都是整数吧 虽然是十六进制
//正常来说 应该都是整数类型的指针来存储就行了
//指针的类型和里面存储内容的类型是不一样的
int age = 1;
float price = 1.2f;
// *c = &age; //使用指针的时候 如果放在是左边 也就是对它赋值 是使用不带*的
_pc = &age;
//_pf = &age; //不能使用int的地址存储到float的指针里面Code language: JavaScript (javascript)
取地址符
//取地址符 &
int a = 1;
float f = 1.2f;
cout << &a << endl;
cout << &f << endl;Code language: JavaScript (javascript)
#include <iostream>
using namespace std;
int main() {
int *ip; //整型指针
int age; //整型变量
age = 100; //初始化变量
ip = &age; //把变量的地址存放给指针
cout << "age:" << age <<endl;
cout << "&age:" << &age <<endl;
cout << "ip:" << ip <<endl; //当不带星号的时候 就是获取指针中的地址 十六进制的数
cout << "*ip:" << *ip <<endl; //这里是获取指针所指向地址的内存的值 要注意和指针定义的时候的区别 int *ip;
return 0;
}Code language: PHP (php)
#include <iostream>
using namespace std;
int main() {
int age;
int *_age;
//*_age = &age;//出错 不能把地址赋给指针所指向的变量
_age = &age;//给指针的时候是这样使用
*_age = 100;//给指针所指向的变量复制
cout << age << endl; //100
age = 120;
cout << *_age << endl;//120
return 0;
}Code language: PHP (php)
没有初始化的指针
#include <iostream>
using namespace std;
int main() {
int *_zz;
cout << _zz << endl;
cout << *_zz << endl;
return 0;
}Code language: PHP (php)
我们的代码
//取地址符 &
int a = 1;
float f = 1.2f;
cout << &a << endl;
cout << &f << endl;
int *_pa = &a;//声明和赋值一起 所以左边可以带*
float *_pf = &f;
cout << a << endl; //普通的输出变量
cout << *_pa << endl; //通过指针来读取它保存的地址的变量的值
//如果对于右值 *_pa是获取指向的变量的值
//对于指针 不同星号 就是地址 用星号就是通过地址取值
cout << _pa << endl; //输出指针的保存地址Code language: JavaScript (javascript)
左值右值
| 场景 | 说明 |
|---|---|
声明的时候 *p 例子 int *p = &age; | 不存在非声明不带星号 p int *a; a = &age; |
*p 取地址的变量的值 int *a = &age; cout << *a; | 读取的是 age 的值 |
不带星号 则是取指针保存地址 cout << a; | 输出 age 的地址 |
空指针
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。
赋为 NULL 值的指针被称为空指针。
NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:
#include <iostream>
using namespace std;
int main ()
{
int *ptr = NULL;
cout << "ptr 的值是 " << ptr ;
return 0;
}Code language: PHP (php)
当上面的代码被编译和执行时,它会产生下列结果:
ptr 的值是 0
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,您可以使用 if 语句,如下所示:
if(ptr) /* 如果 ptr 非空,则完成 */
if(!ptr) /* 如果 ptr 为空,则完成 */Code language: JavaScript (javascript)
因此,如果所有未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。
我们的程序
int *ptr = NULL;
cout << "ptr 的值是 " << ptr ; //0 在C++ 0 是false
//我们可以通过它来进行空指针判断
if(ptr){
cout << "prt不是空指针" << endl;
}
else{
cout << "prt是空指针" << endl;
}Code language: PHP (php)
我们的代码
int *a = NULL;//NULL就是0 0是操作系统保护的 不会给人使用
cout << a << endl;
if(a) //控制着 NULL => 0 bool类型里面 => false
{
cout << "空指针" << endl;
}
else
{
//不是空指针
cout << *a << endl;
}Code language: PHP (php)
指针的算术运算
指针是一个用数值表示的地址。因此,您可以对指针执行算术运算。可以对指针进行四种算术运算:++、–、+、-。
假设 ptr 是一个指向地址 1000 的整型指针,是一个 32 位的整数,让我们对该指针执行下列的算术运算:
int *ptr; // 保存的地址是1000
ptr++;Code language: JavaScript (javascript)
在执行完上述的运算之后,ptr 将指向位置 1004,因为 ptr 每增加一次,它都将指向下一个整数位置,即当前位置往后移 4 个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果 ptr 指向一个地址为 1000 的字符,上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001。
它经常应用到数组上面。
递增一个指针
我们喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,因为数组是一个常量指针。下面的程序递增变量指针,以便顺序访问数组中的每一个元素:
int ages[3] = { 10, 100, 200 };
int *ptr;
int a = 12;
//ptr = &a; //普通的变量 通过取地址符获取地址
//对于数组来说 直接数组名就可以
ptr = ages;//ages是第一个元素10的地址
for(int i = 0;i<3;i++)
{
//cout << ages[i] << endl;以前的写法
cout << ptr << endl;
cout << *ptr << endl;
//移动到下一个位置
ptr++; //++并不是+1 而是+4 为什么 因为每次它是增加一个格子 一个格子4个字节
}
//0x70fe00
//0x70fe04
//0x70fe08Code language: JavaScript (javascript)
递减一个指针
同样地,对指针进行递减运算,即把值减去其数据类型的字节数,如下所示:
int ages[3] = { 10, 100, 200 };
int *ptr;
ptr = &ages[2];//获取最后一个元素的地址
for(int i = 2;i>=0;i--)
{
cout << ptr << endl;
cout << *ptr << endl;
ptr--;
}Code language: JavaScript (javascript)
获取最后一个元素的地址 和第一个元素的地址不一样。最后一个元素 需要 &,第一个元素 直接数组名就可以。
指针的比较
指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。
下面的程序修改了上面的实例,只要变量指针所指向的地址小于或等于数组的最后一个元素的地址 &ages[2],则把变量指针进行递增:
int ages[3] = {1,2,3};
int *ptr = ages;
while(ptr <= &ages[2]) //只要少于等于最后一个元素的地址 则循环
{
cout << *ptr << endl;
ptr++;
}
cout << *ptr << endl;//超出了数组的范围 最后一个元素的下一个地址Code language: JavaScript (javascript)
指针与数组
指针和数组是密切相关的。事实上,指针和数组在很多情况下是可以互换的。
例如,一个指向数组开头的指针,可以通过使用指针的算术运算或数组索引来访问数组。请看下面的程序:
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指针中的数组地址
ptr = var;
for (int i = 0; i < MAX; i++)
{
cout << "var[" << i << "]的内存地址为 ";
cout << ptr << endl;
cout << "var[" << i << "] 的值为 ";
cout << *ptr << endl;
// 移动到下一个位置
ptr++;
}
return 0;
}Code language: PHP (php)
下面通过指针来修改数组的值。
#include <iostream>
using namespace std;
const int MAX = 3;
int main()
{
int var[MAX] = { 10, 100, 200 };
for (int i = 0; i < MAX; i++)
{
*var = i; // 这是正确的语法
//var++; // 这是不正确的
}
*(var + 2) = 500;
for (int i = 0; i < MAX; i++)
{
cout << var[i] << endl;
}
return 0;
}Code language: PHP (php)
我们的代码
int ages[3] = {1,2,3};
int *prt = NULL;
//prt = &ages; //对于数组不能像普通变量那样使用 取地址符
prt = ages; //直接通过数组名 就是数组的地址
//以前的方式输出数组的元素
cout << "-------以前的写法" << endl;
for(int i=0;i<3;i++)
{
cout << ages[i] << endl;
}
//通过指针的写法
cout << "通过指针的方式" << endl;
for(int i=0;i<3;i++)
{
cout << "ages["<< i<<"]:" << prt << endl;
cout << "ages["<< i<<"]的值:" << *prt << endl;
prt++;//让地址改变为下个元素的地址
}
prt = ages;//让指针回到第一个元素
//通过指针来修改元素
cout << "通过指针来修改元素" << endl;
for(int i=0;i<3;i++)
{
*prt = i+10; //*prt是表示元素的值
//ages[i] = 10;
prt++;//让地址改变为下个元素的地址
}
prt = ages;
*(prt+2) = 500;
cout << "修改元素之后"<< endl;
for(int i=0;i<3;i++)
{
cout << ages[i] << endl;
}
int a = 1;
int *_a = &a; //以前的写法Code language: PHP (php)
指针运算符 * 应用到 var 上是完全可以的,但修改 var 的值是非法的。这是因为 var 是一个指向数组开头的常量,不能作为左值。
由于一个数组名对应一个指针常量,只要不改变数组的值,仍然可以用指针形式的表达式。例如,下面是一个有效的语句,把 var[2] 赋值为 500:
*(var + 2) = 500;Code language: JavaScript (javascript)
上面的语句是有效的,且能成功编译,因为 var 未改变。
int ages[3] = {1,2,3};
int *prt = NULL;
//prt = &ages; //对于数组不能像普通变量那样使用 取地址符
prt = ages; //直接通过数组名 就是数组的地址
*(prt+2) = 500;
for(int i=0;i<3;i++)
{
cout << ages[i] << endl;
}
for(int i=0;i<3;i++)
{
ages++; //数组名是常量 不能改变的
prt = ages;
cout << *prt << endl;
}Code language: PHP (php)
ages 是一个地址,是第一个元素的地址,但是它是一个常量。我们如果要遍历,可以通过赋值给指针来进行遍历。
指针数组
在我们讲解指针数组的概念之前,先让我们来看一个实例,它用到了一个由 3 个整数组成的数组:
#include <iostream>
using namespace std;
const int MAX = 3;
int main()
{
int var[MAX] = { 10, 100, 200 };
for (int i = 0; i < MAX; i++)
{
cout << "Value of var[" << i << "] = ";
cout << var[i] << endl;
}
return 0;
}Code language: PHP (php)
可能有一种情况,我们想要让数组存储指向 int 或 char 或其他数据类型的指针。下面是一个指向整数的指针数组的声明:
int *ptr[MAX];Code language: CSS (css)
在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成。
因此,ptr 中的每个元素,都是一个指向 int 值的指针。
下面的实例用到了三个整数,它们将存储在一个指针数组中,如下所示:
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr[MAX];
for (int i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; // 赋值为整数的地址
}
for (int i = 0; i < MAX; i++)
{
cout << "Value of var[" << i << "] = ";
cout << *ptr[i] << endl;
}
return 0;
}Code language: PHP (php)
#include <iostream>
using namespace std;
const int MAX = 3;
int main()
{
int ages[MAX] = { 10, 100, 200 };
for (int i = 0; i < MAX; i++)
{
cout << "Value of ages[" << i << "] = ";
cout << ages[i] << endl;
}
//变量指针
int *p;
int age = 123;
p = &age;
cout << *p << endl;
//指针数组 就是一个用来存储指针的数组
int *prtages[MAX];
for (int i = 0; i < MAX; i++)
{
prtages[i] = &ages[i];
}
cout << "遍历数组指针读取每个元素指向的变量的值" << endl;
for (int i = 0; i < MAX; i++)
{
cout << *prtages[i] << endl;
}
return 0;
}Code language: PHP (php)
您也可以用一个指向字符的指针数组来存储一个字符串列表,如下:
#include <iostream>
using namespace std;
const int MAX = 4;
int main()
{
const char *names[MAX] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
for (int i = 0; i < MAX; i++)
{
cout << "Value of names[" << i << "] = ";
cout << names[i] << endl;
}
return 0;
}Code language: PHP (php)
指向指针的指针
int **c 是一个指向指针的指针,它保存了另外一个指针的地址。它需要两个星号。
指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。
当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。
一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如,下面声明了一个指向 int 类型指针的指针:
int **var;Code language: JavaScript (javascript)
当一个目标值被一个指针间接指向到另一个指针时,访问这个值需要使用两个星号运算符,如下面实例所示:
#include <iostream>
using namespace std;
int main()
{
int var;
int *ptr;
int **pptr;
var = 3000;
// 获取 var 的地址
ptr = &var;
// 使用运算符 & 获取 ptr 的地址
pptr = &ptr;
// 使用 pptr 获取值
cout << "var 值为 :" << var << endl;
cout << "*ptr 值为:" << *ptr << endl;
cout << "**pptr 值为:" << **pptr << endl;
return 0;
}Code language: PHP (php)
int a = 1;
int *p = &a; //*p保存普通变量的地址
//int **c = &*p; //非声明的时候 *p 表示是指向变量 &*p 等同&a
//如果这样写 报错 因为**c 应该是保存指针的地址
int *p2 = &*p;//这样写没问题 这样写其实有点多余 等于下面
int *p3 = p;
cout << "a:" << a << endl;
cout << "*p:" << *p << endl;
cout << "*p2:" << *p2 << endl;
cout << "*p3:" << *p3 << endl;
//int **c = p; //这样写也是会报错 p是普通变量的地址 不是指针的地址
int **c = &p; //对指针取地址符
cout << "**c:" << **c << endl;//通过指针的指针获取值
int ***t = &c;//取c的地址
cout << "***t:" << ***t << endl;Code language: JavaScript (javascript)
指针作为函数参数
就是指针作为函数的参数。传递给函数内部使用。函数内部有了这个指针就可以操作指针指向的变量。
C++ 允许您传递指针给函数,只需要简单地声明函数参数为指针类型即可。
下面的实例中,我们传递一个无符号的 long 型指针给函数,并在函数内改变这个值:
#include <iostream>
using namespace std;
void getSeconds(int *par);
int main()
{
int age = 40;
getSeconds(&age); //把变量的地址付给函数
cout << age << endl;
return 0;
}
void getSeconds(int *par)
{
*par = 100;//把指针所指向的变量的值改为了100 就相当于修改了age的值
return;
}Code language: PHP (php)
能接受指针作为参数的函数,也能接受数组作为参数,如下所示:
#include <iostream>
using namespace std;
// 函数声明
double getAverage(int *arr, int size);
int main()
{
// 带有 5 个元素的整型数组
int balance[5] = { 1000, 2, 3, 17, 50 };
double avg;
// 传递一个指向数组的指针作为参数
avg = getAverage(balance, 5);
// 输出返回值
cout << "Average value is: " << avg << endl;
return 0;
}
double getAverage(int *arr, int size)
{
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}Code language: PHP (php)
可以通过指针来和下标来获取每个元素的值
int ages[3] = {1,20,45};
int *prt = ages;
for(int i = 0;i<3;i++)
{
//cout << ages[i] << endl;
cout << prt[i] << endl;//直接通过指针和下标来读取数组的每个元素
}Code language: JavaScript (javascript)
函数返回指针
我们先来复习一下 以前函数的写法
#include <iostream>
using namespace std;
//以前的函数的写法 返回一个整数
int getMax(int a,int b)
{
if(a > b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int x = 23;
int y = 54;
int r = getMax(x,y);
cout << r << endl;
return 0;
}Code language: PHP (php)
C++ 允许您从函数返回指针。为了做到这点,您必须声明一个返回指针的函数,如下所示:
int* myFunction()
{
}Code language: CSS (css)
如果把上面的改为返回指针
#include <iostream>
using namespace std;
//以前的函数的写法 返回一个整数
int * getMax(int a,int b)
{
if(a > b)
{
return &a;
}
else
{
return &b;
}
}
int main()
{
int x = 23;
int y = 54;
int *r = getMax(x,y);
y = 120;
cout << *r << endl;
return 0;
}Code language: PHP (php)
现在,让我们来看下面的函数,它会生成 10 个随机数,并使用表示指针的数组名(即第一个数组元素的地址)来返回它们,具体如下:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int * getRandom()
{
static int r[10];
// 设置种子
srand((unsigned)time(NULL));
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r; //返回来的是数组的第一个元素的地址
}
int main()
{
//一个指向整数的指针
int *p;
//调用函数 函数返回指针
p = getRandom();
//通过指针 读取里面的值
for (int i = 0; i < 10; i++)
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl; //通过递增指针 读取里面的值
}
return 0;
}Code language: PHP (php)
引用
引用和指针有点类似。但是并不是指针。
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
int a = 1;
假设给 a 起一个别名,可以理解为绰号。
就好比一个人有两个名字。那么这两个名字 一个叫变量名 一个叫引用 那么这两个名字 都可以表示这个人。
int a = 1;
int b = a; //把a的值 付给b 那么b的值也是1 a和b 在这里是没有关系。只是把b的值改为和a的值一样。Code language: JavaScript (javascript)
引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。
引用的声明方法:类型标识符 &引用名=目标变量名;
【例1】:
int a;
int &ra=a; //定义引用ra,它是变量a的引用,即别名Code language: JavaScript (javascript)
说明:
(1)& 在此不是求地址运算,而是起标识作用。
(2)类型标识符是指目标变量的类型。
(3)声明引用时,必须同时对其进行初始化。
(4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
ra=1; 等价于 a=1;
(5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra 与 &a 相等。
(6)不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。
int a = 1;
int &ra=a; //定义引用ra,它是变量a的引用,即别名
cout << ra << endl;
ra = 2;
cout << a << endl;
return 0;Code language: JavaScript (javascript)
C++ 引用 vs 指针
引用很容易与指针混淆,它们之间有三个主要的不同:
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
创建引用
试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。
因此,您可以通过原始变量名称或引用来访问变量的内容。例如:
int i = 17;
我们可以为 i 声明引用变量,如下所示:
int& r = i;
double& s = d;
在这些声明中,& 读作引用。因此,第一个声明可以读作 “r 是一个初始化为 i 的整型引用”,第二个声明可以读作 “s 是一个初始化为 d 的 double 型引用”。下面的实例使用了 int 和 double 引用:
#include <iostream>
using namespace std;
int main()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}Code language: PHP (php)
int a = 1;
//int &ra; //不能创建空引用
int *pa = &a;
int b = 2;
pa = &b;
int &ra = a; //引用创建的时候 必须绑定一个变量
//&ra = b; //引用一旦创建 就不能更改
float &rf = a;//类型要和变量一样
return 0;Code language: JavaScript (javascript)
引用作为函数参数
下面的实例使用了引用来实现引用调用函数。
#include <iostream>
using namespace std;
// 函数声明
void swap(int& x, int& y);
int main()
{
// 局部变量声明
int a = 100;
int b = 200;
cout << "交换前,a 的值:" << a << endl;
cout << "交换前,b 的值:" << b << endl;
/* 调用函数来交换值 */
swap(a, b);
cout << "交换后,a 的值:" << a << endl;
cout << "交换后,b 的值:" << b << endl;
return 0;
}
// 函数定义
void swap(int& x, int& y)
{
int temp;
temp = x; /* 保存地址 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 x 赋值给 y */
return;
}Code language: PHP (php)
如果不使用引用
#include <iostream>
using namespace std;
void Swap(int a,int b);
int main()
{
int x = 23;
int y = 12;
Swap(x,y);
cout << "x:"<<x << endl;
cout << "y:"<<y << endl;
return 0;
}
void Swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
}Code language: PHP (php)
a b 和 x y 完全是两个不同的变量 所以 a b 交换了 不影响 x y
如果把它换成引用参数 那么就可以解决这个问题了
#include <iostream>
using namespace std;
void Swap(int &a,int& b);
int main()
{
int x = 23;
int y = 12;
Swap(x,y);
cout << "x:"<<x << endl;
cout << "y:"<<y << endl;
return 0;
}
void Swap(int& a,int &b)
{
int temp = a;
a = b;
b = temp;
}Code language: PHP (php)
如果使用引用,那么 x 和 a 是一个变量,a 是 x 的别名;y 和 b 是一个变量,b 是 y 的别名。
通过使用引用来替代指针,会使 C++ 程序更容易阅读和维护。C++ 函数可以返回一个引用,方式与返回一个指针类似。
当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。例如,请看下面这个简单的程序:
#include <iostream>
using namespace std;
double vals[] = { 10.1, 12.6, 33.1, 24.1, 50.0 };
double &setValues(int i)
{
return vals[i]; // 返回第 i 个元素的引用
}
// 要调用上面定义函数的主函数
int main()
{
cout << "改变前的值" << endl;
for (int i = 0; i < 5; i++)
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
setValues(1) = 20.23; // 改变第 2 个元素 之所以可以把一个值付给一个引用 是因为这个函数是返回一个引用
setValues(3) = 70.8; // 改变第 4 个元素
//相当于 返回一个变量 所以我们可以给这个变量赋值
cout << "改变后的值" << endl;
for (int i = 0; i < 5; i++)
{
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
return 0;
}Code language: PHP (php)
之所以可以把一个值付给一个引用,是因为这个函数是返回一个引用。
引用返回的函数 是在 = 号的左边,这个比较特别。