C/C++/Linux

指针与引用

2019-08-28  本文已影响0人  ninedreams

指针

指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元。

引用

引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。(教科书标准)

指针与引用的区别

函数传参

指针传参数

演示代码如下,编译g++ main.c -o main -std=c++11

#include <iostream>
#include "stdio.h"
using namespace std;
void swap(int *a, int *b) {
    int *tmp = a;
    a = b;
    b = tmp;
}
void testp(int *p) {
    int c = 5;
    p = &c;
    cout << p << " " << *p << endl;
}
int main(int argc, char** argv) {
    int a = 1, b = 2;
    swap(&a,&b);
    cout << a << " " << b << endl;

    int *p = nullptr;
    testp(p);
    if (p == nullptr)
        cout << "p is nullptr" << endl;
    else
        cout << p << " " << *p << endl;

    return 0;
}

编译运行之后的结果:


image.png

可以观察到的结果:

  1. swap函数没有交换a,b的值
  2. testp函数中指针p是地址,*p取到了变量c的值
  3. testp函数没有返回后没有改变传入的指针参数p
引用传参数
#include <iostream>
#include "stdio.h"
using namespace std;
void testp(int &p) {
    cout << &p << " " << p << endl;
    p = 5;
    cout << &p << " " << p << endl;
}
int main(int argc, char** argv) {
    int p = 1;
    cout << &p << " " << p << endl;
    testp(p);
    return 0;
}

可以看到结果:

  1. 变量P三次地址都没有改变
  2. 变量P的值在函数testp中最后一次改变了

运行如下:


image.png

引用实质

我们知道在C语言中无法使用引用传参数,引用传参数是C++的语法。那么C语言中如何实现类似的功能呢?

#include "stdio.h"
void swap(int *const a, int *const b) {
     int tmp = *a;
     *a = *b;
     *b = tmp;
}
int main(int argc, char** argv) {
    int x=10,y=20;
    swap(&x,&y);
    printf("%d %d\n", x, y);
    return 0;
}

如上代码就是C语言中的实现,同样也能实现x,y的值交换,只不过函数传的参数是int *const类型。
实际上,在引用中int &b=a这一句代码可被编译器看做int * const b=&a,加上const的作用是表明指针b的自身的值(a的地址)不能改变,而指向的值(a的值)可以改变。也就是说引用相当于指针,引用与指针在编译时的方法一样,指向的都是变量的内存地址。但是也有一些不同点如下:

  1. 在定义方式中引用储存的是值,而指针是一个变量的拷贝,存储的是地址
  2. 引用只能对已经存在的变量或对象实现引用,而指针则不需要,可以定义为空
  3. 在函数的传参中,如果传递的是一个引用,意味着这个变量或对象已经存在了;如果传递的是一个指针,则不能判断这个指针是不是有效的,是不是空的,因此在函数体 中大多数都得进行指针是否为空的判断。但是虽然引用较为安全,但是利用指针来传参效率较快
  4. 引用是直接访问变量,不用分配自己的内存空间,而指针是间接访问,需要定义,需要有自己的内存空间

所以实际开发中,使用哪种方式应该由开发者自己来定,按照开发的需求来定。

上一篇下一篇

猜你喜欢

热点阅读