以下为代码运行环境:
环境 | 版本 |
---|---|
OS | macOS Mojave version10.14.6 |
cmake | 3.15.3 |
vscode | 1.40.2 |
一、 什么是引用?换句话说就是另一变量的别名。
[数据类型] & 名称 = 变量名;
int a = 0;
int &b = a;
这里的b
就是引用。
注意:
- & 不是取地址运算符
- int 是数据类型
- 引用的声明一定要初始化
- 数组没有引用
引用有什么用?
- 做函数参数(可以提高效率,在数据量大的时候是这样)
- 常引用(即在引用的定义前加上
const
);这样在做参数的时候可以防止数据被修改。
int a = 1;
const int &b = a;
b = 2;// wrong
a = 2; // right
- 引用作为函数返回值( [数据类型] & 函数名(参数列表){})
#include <iostream>
using std::printf;
int &fun1(int x);
int ref;
int main(){
int c = fun1(5);
printf("ref = %d, c = %d, &c = %p, &ref = %p\n",
ref,c,&c,&ref);
int &d = fun1(10);
printf("ref = %d, c = %d, &d = %d, &d = %p, &ref = %p\n",
ref,c,d,&d,&ref);
return 0;
}
int &fun1(int x){
ref =x*x;
return ref;
}
打印的结果如下:
ref = 25, c = 25, &c = 0x7ffee1b70848, &ref = 0x10e090018
ref = 100, c = 25, &d = 100, &d = 0x10e090018, &ref = 0x10e090018
Notes:
- 不能返回局部变量的值
- 不能返回函数内部new分配的内存的引用
- 可以返回类成员的引用,但最好是
const
的
结论:
引用就是一个目标变量的别名,可用以函数的参数及返回值,还用作常引用。
二 、指针介绍
1. 1 指针与const
- 让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值。
-- [const 数据类型 *
] - 将指针本身声明为常量,可以防止改变指针指向的位置。
-- [数据类型 * const
]
int a = 39;
int b = 40;
const int * pa = &a; // pa指向一个const int,因此不能用pa来修改这个值。
pa = &b;//正确,但是pa一样不能修改值。
1. 2 指针与数组
- 数组名为数组的
第一个元素的地址
。
int apple[5] = {1,2,3,4,5};
int * pt = apple;//等同于 * pt = &apple[0]; 即 apple == &apple[0];
- 数组表示法(即用方括号:apple[5])等同于对指针解除引用。
apple[0] 与 *apple 是相等的。
apple[3] 与*(apple+3) 也是相等的。
//以下这个是恒等式
arr[i] == *(arr +i);
&arr[i] == arr +i;
注意:
- 对数组名使用
sizeof
将得到整个数组的长度。- 将地址运算符
&
用于数组名时,将返回整个数组的地址。
2. 函数指针
- 声明指向某种数据类型的指针时,必须指定指针指向的类型。声明指向函数的指针时,也必须指定指针指向的函数类型。声明应像函数原型那样指出有关函数的信息。
int power(int);//函数原型
int (*pp)(int);//函数指针原型
这个与power()声明类似,只是将power替换为(*pp)。
注意:
这里加了()
,因为括号的优先级比*
运算符高。因此 :
1. *pp(int) 意味着pp()是一个返回指针的函数
。
2. (*pp)(int)意味着pp是一个指向函数的指针
。
#include <iostream>
using std::printf;
int power(int);
void mypp(int x, int (*p)(int));
int main(){
mypp(12, power);
return 0;
}
int power(int x){
return x * x;
}
void mypp(int x, int (*p)(int)){
printf("print (*p)() = %d\n", (*p)(x));
printf("print p() = %d\n", p(x));
}
最后,回顾下
数组指针
,指针数组
,函数指针
1.int * pa[2]; //定义了指针数组pa,元素是指向int型的指针。
2.int (*pa)[2];//定义了数组指针pt,元素是指向int[2]数组的指针。//****
3.int * pf(int);//定义了一个函数,返回指针类型值。
4.int (*pf)(int);//定义了一个函数指针,返回int型值。
为配合说明,以下是代码及输出:
#include <iostream>
using std::printf;
int main(){
int a[2][2] = {{1,2},{3,4}};
int b[2] = {5,6};
int (*p)[2];
int (*pa)[2];
p = a;
for(int i = 0;i<2;i++){
for(int j = 0;j<2;j++){
printf("p[%d][%d] = %d \n",i,j,p[i][j]);
}
}
printf("\n");
pa = &b;
for(int i=0;i<2;i++){
printf("pa[%d] = %d, pa[%d] address : %p \n",
i,*pa[i],i,pa[i]);
}
printf("\n");
printf("pa[0][0] = %d, pa[0][0] address : %p\n",
pa[0][0],&pa[0][0]);
printf("pa[0][1] = %d\n",pa[0][1]);
return 0;
}
输出:
p[0][0] = 1
p[0][1] = 2
p[1][0] = 3
p[1][1] = 4pa[0] = 5, pa[0] address : 0x7ffee7217828
pa[1] = 1, pa[1] address : 0x7ffee7217830pa[0][0] = 5, pa[0][0] address : 0x7ffee7217828
pa[0][1] = 6