精华内容
下载资源
问答
  • 【C++ Lab】 对于解引用符*以及与运算符[]优先级的探索【结论】【验证过程】阶段一 探究初步阶段二 理解解引用符——*阶段三 步入正题——[]与*优先级探索 我想很多人都看过运算符优先级表,但有时候对于一些情况...


    我想很多人都看过运算符优先级表,但有时候对于一些情况可能会混淆,不过一个万能方法是——加括号改变/确保优先级。尽管"加括号"确实是个万能方法,但在有时间去摸索的时候还是尽可能弄清楚优先级为好,这样更有助于理解,甚至可以在摸索的过程中发现"新大陆",这也是做此次探索的目的。

    【结论】

    先把结论摆上吧:
    【结论一】解引用符*不能"解空气",即被解引用的指针变量不能为野地址或NULL

    【结论二】运算符[]的优先级高于解引用符*。
    因此对于一个二级指针如int** a;,如果要用它来表示一个一维数组,则数组中元素表示为(*a)[i],其中的小括号不能少。

    【验证过程】

    阶段一 探究初步

    #include<iostream>
    #include<stdlib.h>
    
    int main(){
    	using namespace std;
    	int ** a=NULL; //注意悬空,防止野指针 
    	//cout<<"a="<<a<<endl;
    	*a = (int*)malloc(sizeof(int)*3);
    	for(int i=0;i<3;++i)
    		(*a)[i] = i+1;
    		
    	for(int i=0;i<3;++i)
    		cout<<(*a)[i]<<endl;
    		
    	return 0;
    }
    

    【运行结果】
    在这里插入图片描述

    阶段二 理解解引用符——*

    以上为我一开始写的代码,但是一运行就发现main函数返回了一个很大的值(如上图),显然是出现了问题(即便我不把指针变量a悬空也是如此),其实原因很简单,我当时并没有给指针变量a本身提供一个"合法处所",即少了一句a=(int**)malloc(sizeof(int));,但这就使得二级指针a充当着二维数组了(我们是想要把二级指针a用于一维数组),因此我把代码改了改,如下代码块所示。

    #include<iostream>
    #include<stdlib.h>
    
    int main(){
    	using namespace std;
    	int ** a=NULL; //注意悬空,防止野指针 
    	int* arr=NULL;
    	a = &arr;
    	//cout<<"a="<<a<<endl;
    	*a = (int*)malloc(sizeof(int)*3);
    	for(int i=0;i<3;++i)
    		(*a)[i] = i+1;
    		
    	for(int i=0;i<3;++i)
    		cout<<(*a)[i]<<endl;
    		
    	return 0;
    }
    

    【运行结果】
    在这里插入图片描述
    可能有人会有疑问了,为何在不改变第一个代码块代码的前提下,仅仅添加了int* arr=NULL; a=&arr;后,就能正常运行了呢?关键在于a指针变量所指的地址是否存在。

    我们要明白*a的意思是"对于a所指的地址解引用,并取其存储的值",对于一开始的int ** a=NULL; *a = (int*)malloc(sizeof(int)*3);,a是空指针,没有指向实际的地址,这时候*a即取虚空地址存储的值,相当于"取空气",这当然是非法的了,这种情况下就需要先给a本身申请一个存储空间,也就是对应着a=(int**)malloc(sizeof(int));,然后再进行后续的解引用等指令。

    对于后面的代码块,这时候a=&arr;,尽管arr=NULL,但是它的地址是非空的,即&arr!=NULL,这时候赋予a的自然就是一个实实在在的"合法处所"了,因此*a——对于a的解引用就是"名正言顺"了。

    到此我们可以得出【结论一】:解引用符*不能"解空气",即被解引用的指针变量不能为野地址或NULL

    阶段三 步入正题——[]与*优先级探索

    这一步其实很简单,我们只要把第二个代码块中(*a)[i]所加的小括号去掉就好,如果运行结果符合预期,那么就说明解引用符*的优先级高于运算符[];若运行出错,则说明解引用符* 的优先级低于运算符[]。

    #include<iostream>
    #include<stdlib.h>
    
    int main(){
    	using namespace std;
    	int ** a=NULL; //注意悬空,防止野指针 
    	int* arr=NULL;
    	a = &arr;
    	cout<<"The address of arr is "<<&arr<<endl;
    	*a = (int*)malloc(sizeof(int)*3);
    	for(int i=0;i<3;++i)
    		*a[i] = i+1;
    		
    	for(int i=0;i<3;++i)
    		cout<<*a[i]<<endl;
    		
    	return 0;
    }
    

    【运行结果】
    在这里插入图片描述
    去掉小括号运行就出错了,从而得到了我们的【结论二】:运算符[]的优先级高于解引用符*

    所以有些时候,如果对于网上的答案持怀疑态度,那么不妨自己设计个简单实验试试,说不定你就找到了答案,并且这远比你去网上搜寻得到的解答印象深刻。

    如果文章中有不妥之处,欢迎大家在评论区指点批评~

    展开全文
  • 指针与引用,取地址符与解引用符

    千次阅读 2017-08-14 21:12:17
    指针与引用,取地址符&与解引用符*引言探讨一下指针、引用、以及具有两种意思两个符号&和*引用引用相当于为对象取一个别名,引用本身不是对象。定义方式:int x=4; int &y=x;//y为变量x的引用,变量x有了另外一个...

    指针与引用,取地址符&与解引用符*

    引言

    探讨一下指针、引用、以及具有两种意思两个符号&和*

    引用

    引用相当于为对象取一个别名,引用本身不是对象。定义方式:

    int x=4;
    int &y=x;//y为变量x的引用,变量x有了另外一个名字y,可以通过y来间接访问x

    指针

    指针也可以实现对对象的间接访问,指针与引用有以下区别:

    • 指针本身就是对象
    • 指针无需在定义时赋初值

    1.使用指针获取对象的地址

    int i=12;
    int *p=&i;//指针p指向i,p的值为i的地址

    2.使用指针间接访问

    int i=12;
    int *p=&i;//&为取地址符
    cout<<*p<<endl;//这里*是解引用符

    示例

    通过下面的实例来理解指针与引用的区别,取地址符&引用的定义&
    指针的定义*解引用符*

    #include <iostream>
    using namespace std;
    int main(){
        //整型变量x
        int x=12;
    
    
        //x的引用y
        int &y=x;
    
        cout<<"x="<<x<<" "<<"y="<<y<<endl;
        //x=12 y=12
    
        y++;
    
        cout<<"x="<<x<<" "<<"y="<<y<<endl;
        //x=13 y=13
    
        //指向整型变量的指针p
        int *p;
        //p的值为x的地址
        p=&x;//这里&为取地址符
    
        cout<<"x="<<x<<" "<<"y="<<y<<" "<<"p="<<p<<endl;
        //x=13 y=13 p=0x68fedc
    
        //地址p所指向的值变为10
        *p=10;//这里为解引用符
    
        cout<<"x="<<x<<" "<<"y="<<y<<" "<<"p="<<p<<endl;
        //x=10 y=10 p=0x68fedc
    
        //p所指对象的引用为z
        int &z=*p;
        z=14;
        cout<<"x="<<x<<" "<<"y="<<y<<" "<<"z="<<z<<" "<<"p="<<p<<endl;
        //x=14 y=14 z=14 p=0x68fedc
    
        //整型变量i
        int i=12;
        //指针q
        int *q;
        //指针q的引用r
        int *&r=q;
        //r指向i,也即q指向i
        r=&i;
        cout<<"i="<<i<<" "<<"q="<<q<<" "<<"r="<<r<<" "<<endl;
        //i=12 q=0x68fed8 r=0x68fed8
    
        //改变r指向的值
        *r=10;
        cout<<"i="<<i<<" "<<"q="<<q<<" "<<"r="<<r<<" "<<endl;
        //i=10 q=0x68fed8 r=0x68fed8
        return 0;
    }
    
    展开全文
  • 解引用运算符一般也应该声明为类的成员函数,但不是必须。2、箭头用算符返回值必须是一个指针,或者是一个重载了箭头运算符的对象。a)如果返回的是一个指针将调用内置的箭头运算符。执行相当于(*(p.operator->())...

    重载要求:

    1、箭头运算符必须是类的成员函数。解引用运算符一般也应该声明为类的成员函数,但不是必须。

    2、箭头用算符返回值必须是一个指针,或者是一个重载了箭头运算符的对象。

    a)如果返回的是一个指针将调用内置的箭头运算符。执行相当于(*(p.operator->()).mem;的操作。

    b)如果返回是一个重载了箭头运算符的对象,则继续对该对象调用其重载了的箭头运算符,直到返回的是

    一个指针,将对该指针调用a)的操作。操作相当于(*(p.operator->().operator->())).mem;

    总的来说重载的箭头运算符就是为了改变从哪个对象中获取成员。

    下面是一个例子,尽管这个例子不是特别有用。

    #include 

    #include 

    using std::cin;

    using std::cout;

    using std::endl;

    class A{

    friend std::ostream& operator<

    public:

    int operator*(){return b;}

    A* operator->(){return this;}

    int geta(){return a;}

    int getb(){return b;}

    private:

    int a=0;

    int b=1;

    };

    std::ostream& operator<

    {

    os<

    return os;

    }

    int main()

    {

    A a;

    A *pa=&a;

    std::cout<

    std::cout<

    std::cout<geta()<getb()<<:endl>

    return 0;

    }

    展开全文
  • C++的解引用概念

    千次阅读 2021-03-11 09:56:53
    那么就开门见山先说解引用——解释引用,说的通俗一点就是,直接去寻找指针所指的地址里面的内容,此内容可以是任何数据类型,当然也可以是指针。 1 #include <iostream> 2 using namespace std; 3 int...

    在c++中,*和&在不同的地方有着不同的意义。那么就开门见山先说解引用——解释引用,说的通俗一点就是,直接去寻找指针所指的地址里面的内容,此内容可以是任何数据类型,当然也可以是指针。

    复制代码

     1 #include <iostream>
     2 using namespace std;
     3 int main(){
     4     int *p ,a=6;
     5     p=&a;
     6     cout<<p<<endl;
     7     cout<<*p<<endl;
     8 //    cout<<&*p<<endl;
     9 //    cout<<*(&*p)<<endl;
    10     return 0;
    11 }

    复制代码

    上面第4行代码声明一个int类型的指针,以及一个int类型的变量a并初始化为6。此时的*表示声明一个指针p,第5行让指针p指向a的地址。因此第6行输出的是a在内存中的地址。而第7行就是解引用。具体解释指针p所指向的内存地址里存放的内容。

    下面介绍引用

    1     int *p ,a=6;
    2     p=&a;
    3     int &c=a;
    4     cout<<c<<endl;

    &表示的是引用,就表示函数内的变量和主函数的变量是同一个,函数内改变它的值,主函数相应的变量也就跟着改变了;没有&符号,就表示函数内的变量是主函数的变量的一个副本,在函数内改变其值,是不会改变主函数中变量的值的。

    下面说一下啥叫脱解引用——就是用&抵消掉*对a的引用效果。

    复制代码

     1 #include <iostream>
     2 using namespace std;
     3 int main(){
     4     int *p ,a=6;
     5     p=&a;
     6     int &c=a;
     7     cout<<c<<endl;
     8     cout<<p<<endl;
     9     cout<<*p<<endl;
    10     cout<<&*p<<endl;
    11     cout<<*(&*p)<<endl;
    12     return 0;
    13 }

    复制代码

    因此代码的第10行输出的是a的内存地址,而代码第11行输出的是a的值。

    结果如下

     c++中(.和->)的区别:

    A *p则使用:p->play(); 左边是结构指针。
    A p 则使用:p.paly(); 左边是结构变量。

    展开全文
  • 取地址符和解引用符的区别Here, we are discussing about the two most useful operators with the pointers, why and how they are used? 在这里,我们用指针讨论两个最有用的运算符 ,为什么以及如何使用它们? ...
  • *,&amp;amp;amp; 在指针操作中的意义 (1)* 大家都知道在写int *p 时,可以声明一个指针。...需要注意的是,在变量声明的时候,*不能当做解引用使用,只是表示你声明的变量是一个指针类型。 exam...
  • #include&lt;iostream&gt; using namespace std; int main() { int i = 42; cout&lt;&lt; "i :\t" &...紧随类型名出现,因此是声明的一部分,r是一个引用 ...
  • 引用 为对象起了另一个名字,引用类型引用另外一种类型 int a = 10; int &b = a; //b指向a(是a的另一个名字) int &c; //错误:引用必须被初始化 一般初始化变量时,初始值会被拷贝到新建的对象中。...
  • C语言指针解引用注意事项

    千次阅读 2018-05-14 11:03:47
    在指针的操作中,间接运算符*,也被称为解引用运算符。注意事项最重要的一点是:不要解引用未初始化的指针如:int * pt;//未初始化的指针*pt=5;//这句话是错的为什么是错的,因为第2行的意思是把5储存在pt指向的...
  • C++解引用操作重载

    千次阅读 2015-11-22 00:54:24
    “*”是一个一元操作,它作用于指针,表示去除指针所指单元的内容。当某个类中对*操作今次那个重载时,是将该类的对象当做一个指针看待,而用*操作提取指针所指向的内容。考察如下程序。#include &lt;...
  • 操作重载之解引用与箭头操作

    千次阅读 2015-01-13 18:02:17
    它可能表现得像二元操作一样:接受一个对象和一个成员名,对对象解引用以获取成员。不管外表如何,箭头操作不接受显式形参。这里没有第二个形参,因为 -> 的右操作数不是表达式,相反,是对应着类成员的一个...
  • 因此 2、其次是单目运算符,包括指针解引用、取地址、前自增/自减等,自右向左的结合性。例如: *P++ 应该解释成 *(P++) ,即取P指向的对象,然后P自增1,虽然后自增++优先级高于*,但是后自增的特性决定了先对P...
  • 解引用和箭头操作

    2016-03-22 13:32:20
    // 解引用操作 String *operator->() const; // 箭头操作, private: String *ptr; static String errorMessage; }; #endif #include #include #include "string.h" String::String(char const *...
  • C++中容器迭代器解引用运算符

    千次阅读 2021-11-11 17:00:09
    因此,在容器迭代器中使用解引用运算符,与在指针上使用解引用运算符类似,其的作用是返回该迭代器所指元素的引用。 2 使用 使用解引用运算符的代码如图1所示。 图1 使用解引用运算符 此时,*it_begin表示对...
  • int *ip; // ip is a pointer to int ... //y is now 1,一元操作*是间接引用或者是解引用操作(注:对指针进行解引用操作获得该指针所指向的对象) *ip = 0; // x is now 0 ip = &z[0]; // ip now points to z[0]
  • #include int main(void) { const char * mesage = "wo,e"; printf("%s", mesage); } 为什么不是printf("%s", mesage);?不用解引用吗?
  • (转F001) Rust : 解引用,自动解引用

    千次阅读 2018-11-25 21:10:19
    解引用(Deref)”是“引用(Ref)”的反操作。比如说,我们有引用类型let p: &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;T;,那么可以用*符号执行解引用操作,let v: T = p;。如果p的类型是&amp;...
  • 解引用

    2016-08-26 10:06:38
    解引用”,我倒觉得可以从另一个角度理解,"*"的作用是引用指针指向的变量,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为“...
  • C++/C字符类指针 解引用问题见解

    千次阅读 2013-07-04 21:34:00
    首先介绍一下引用: 参考:http://www.cnblogs.com/dzry/archive/2011/05/12/2044835.html 1. 指向整型指针 先看如下示例: #include using namespace std; int main() { int a = 5; int * p = &a; cout ...
  • 但对于*,翻译为“解引用”,字面意思不好理解,即使看了后面内容才知道不过是“取指针指向的地址的内容”,也仍然是觉得怪怪的,“解引用”这个词难记也难于从字面直接判断意思,以致时间长了还是感觉像见了熟悉的...
  • char a[ ] = "Hello"; char *p = a; int i = strlen(a);...这句话是先解引用再将p指针++的, 但是我还是太年轻了,不然怎么会有Hello而不是ello呢? 2 但是,运算符的优先级显示后置自增操作
  • 自增、自减、解引用操作

    千次阅读 2014-03-05 22:20:10
    class INT {  //友元函数,可以访问类...返回值为引用类型,因为有时需要这样的操作: cout  friend ostream& operator public:  INT(int i) : m_i(i) {}  //prefix ++  INT& operator++()  {  (this->m_i
  • 但对于*,翻译为“解引用”,字面意思不好理解,即使看了后面内容才知道不过是“取指针指向的地址的内容”,"*"的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解...
  • 文章目录复合类型引用概念与使用引用的定义注意指针概念声明方式取地址指针值空指针利用指针访问对象赋值和指针void* 指针指向指针的指针指向指针的引用初始化所有指针有多重含义的某些符号const限定 ...
  • 解引用NULL指针

    千次阅读 2014-07-18 11:21:44
    一般导致程序崩溃的最重要原因之一就是试图解引用NULL指针。正如上几篇文章中所说的,智能指针RefCountPtr和ScopedPtr提供了运行时的诊断。但是,并不是所有的指针都是拥有某个对象所有的智能指针。因此为了对试图...
  • *的作用

    2020-09-29 06:22:00
    引用 int *p = &a &取址 取出a所在的地址赋值给变量 p >>> p获取到a的地址后用转换为 a内存里的值 输出时一定要记得输出引后的变量即 *p

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 61,129
精华内容 24,451
关键字:

解引用符

友情链接: code.zip