C++ 引用和指针

以下为代码运行环境:

环境 版本
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:

  1. 不能返回局部变量的值
  2. 不能返回函数内部new分配的内存的引用
  3. 可以返回类成员的引用,但最好是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;
注意:
  1. 对数组名使用sizeof将得到整个数组的长度。
  2. 将地址运算符&用于数组名时,将返回整个数组的地址。
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] = 4

pa[0] = 5, pa[0] address : 0x7ffee7217828
pa[1] = 1, pa[1] address : 0x7ffee7217830

pa[0][0] = 5, pa[0][0] address : 0x7ffee7217828
pa[0][1] = 6

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容