【Linux C++ 系列 】05 C++ 指针和引用

举报
jackwangcumt 发表于 2022/07/04 12:16:20 2022/07/04
【摘要】 C++语言和C语言类似,都可以直接对内存进行操作,而这个操作就需要借助指针(pointer)。所谓的指针,就是可以存储变量地址或者内存位置。指针存储的不是变量的值,而是变量值在内存中的地址,由于指针本身所占内存大小非常小,如果他指向的对象非常大,比如一个图片,那么通过指针的传递和操作,可以共享内存,而避免了对象在不同函数堆栈中进行拷贝,从而降低内存占用和提升程序效率。C++中的引用(referen

1 指针和引用


     C++语言和C语言类似,都可以直接对内存进行操作,而这个操作就需要借助指针(pointer)。所谓的指针,就是可以存储变量地址或者内存位置。指针存储的不是变量的值,而是变量值在内存中的地址,由于指针本身所占内存大小非常小,如果他指向的对象非常大,比如一个图片,那么通过指针的传递和操作,可以共享内存,而避免了对象在不同函数堆栈中进行拷贝,从而降低内存占用和提升程序效率。C++中的引用(reference)也可以避免变量的相互拷贝,它可以看作是一个变量名的别名,通过别名可以直接操作被引用的变量。C++语言中的 & 符号可以取变量地址。

2 指针示例


     C++语言的指针是用 * 进行定义的,一般和 & 进行配套使用。声明指针对象需要同时指定指向的变量是什么类型的,声明语法如下所示:

dataType  *ptr_name ;

     下面给出一个简单的示例 :

#include <iostream>
using namespace std;

namespace mycom{
    namespace subns{
        int a = 7 ;
    }
    class Car{
        public:
            float h = 1.5 ;
            void Drive(){
                cout << " Car Drive..." << endl ;
            } 

    };
} 

int main()
{
    int a = 5 ;
    int *ptr_a ;
    cout << " *ptr_a -> " << ptr_a << endl ;
    ptr_a = &a ;
    cout << " *ptr_a -> " << ptr_a << endl ;
    *ptr_a = 6 ;
    cout << " a -> " << a << endl ;
    int b = 7 ;
    ptr_a = &b ;
    *ptr_a = 8 ;
    cout << " a -> " << a << endl ;
    cout << " b -> " << b << endl ;

    ptr_a = &mycom::subns::a ;
    *ptr_a = 9 ;
    cout << " mycom::subns::a -> " << mycom::subns::a << endl ;
    mycom::Car car ;
    car.Drive();  
    float* ptr_f = &car.h ; 
    *ptr_f = 1.6 ; 
    cout << " car.h -> " << car.h << endl ;
    
    return 0;
}

     指针可以在不同变量地址进行切换,比如 int *ptr_a 定义的指针ptr_a可以指向Int类型的变量,那么只要通过&var方式获取到了变量地址,那么就可以通过*ptr_a修改变量的值。同样的值,对于命名空间中的变量以及类实例来说,都是适用的。执行如下代码进行编译和执行:

g++ demo05.cpp -o demo05
./demo05

   输出结果如下所示:

05.jpg

3 引用示例


     C++语言的指针是用 * 进行定义的,一般和 & 进行配套使用。而引用的定义也用到符号 & ,不过位置不同,这里需要注意二者区别。引用声明语法如下所示:

dataType  &ref_name = var_name;

     下面给出一个简单的示例 :

#include <iostream>
using namespace std;

namespace mycom{
    namespace subns{
        int a = 7 ;
    }
    class Car{
        public:
            float h = 1.5 ;
            void Drive(){
                cout << " Car Drive..." << endl ;
            } 

    };

    void change(Car &c){
        c.h = 1.6 ;
    }
    void change_val(Car c){
        c.h = 1.7 ;
    }
} 


int main()
{
    int a = 5 ;
    int &ref_a = a;
    ref_a = 6 ;
    cout << " a -> " << a << endl ;
    a = 9 ;
    cout << " ref_a -> " << ref_a << endl ;
   
    // int b = 7 ;
    // &ref_a = b ; //error
    
    mycom::Car car ;
    car.Drive();  
    mycom::change_val(car) ; 
    cout << " car.h -> " << car.h << endl ;
    mycom::change(car) ; 
    cout << " car.h -> " << car.h << endl ;    
    return 0;
}

执行如下代码进行编译和执行:

g++ demo06.cpp -o demo06
./demo06

   输出结果如下所示:

06.jpg

   通过上述示例对比分析可知,引用和指针具有异同点,引用好比一个常量的指针,只能指向一个变量,不能再次赋值,而指针则可以。引用可以避免大变量的内存拷贝,当作为一个函数参数时,共享内存地址,也可以修改变量的值。下面为了验证指针和引用都指向同一个变量,下面再给一个打印内存地址的示例 :

#include <iostream>
using namespace std;

namespace mycom{
    namespace subns{
        int a = 7 ;
    }
    class Car{
        public:
            float h = 1.5 ;
            void Drive(){
                cout << " Car Drive..." << endl ;
            } 

    };

    void change(Car &c){
        cout << " car addr in change -> " << &c << endl ;
        c.h = 1.6 ;
    }
    void change_val(Car c){
        cout << " car addr in change_val -> " << &c << endl ;
        c.h = 1.7 ;
    }
    void change_ptr(Car* c){
        cout << " car addr in change_ptr -> " << c << endl ;
        *c.h = 1.8 ;
    }
} 


int main()
{
    int a = 5 ;
    int &ref_a = a;
    ref_a = 6 ;
    cout << " a -> " << a << endl ;
    a = 9 ;
    cout << " ref_a -> " << ref_a << endl ;
   
    // int b = 7 ;
    // &ref_a = b ; //error
    
    mycom::Car car ;
    cout << " car addr -> " << &car << endl ; 
    car.Drive();  
    mycom::change_val(car) ; 
    cout << " car.h -> " << car.h << endl ;
    mycom::change(car) ; 
    cout << " car.h -> " << car.h << endl ; 
    mycom::change_ptr(&car) ; 
    cout << " car.h -> " << car.h << endl ;  
    return 0;
}

     其中的mycom::change_ptr(&car) 是把指针作为函数函数,编译执行后打印如下结果:

root@ega-VirtualBox:/home/ega/mycpp# g++ demo07.cpp -o demo07
root@ega-VirtualBox:/home/ega/mycpp# ./demo07
 a -> 6
 ref_a -> 9
 car addr -> 0x7ffcab2be08c
 Car Drive...
 car addr in change_val -> 0x7ffcab2be06c
 car.h -> 1.5
 car addr in change -> 0x7ffcab2be08c
 car.h -> 1.6
 car addr in change_ptr -> 0x7ffcab2be08c
 car.h -> 1.8
root@ega-VirtualBox:/home/ega/mycpp# 

     由此可见,mycom::change_ptr(&car) 函数内打印的地址和mycom::change(car)打印的地址是一致的,即 0x7ffcab2be08c 。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。