zoukankan      html  css  js  c++  java
  • C++指针&引用简笔

    1.困惑的二级指针

    #include <iostream>
    using namespace std;
    
    void pt(int* *t) {
    	cout<<t<<endl<<*t<<endl<<**t<<endl;
    }
    
    int main() {
    	int a = 1;
    	cout<<&a<<endl;
    	int* p = &a;
    	pt(&p);
    	return 0;
    }
    

      注意pt这个函数,使用的是就是二级指针作为参数:

      我们这样理解所有的变量

    变量名 地址

      好了我们的例子:

      变量a表示为(我们的地址都是瞎编的):

    a 1 11FA

      变量p表示为:

    p 11FA 10BC

      那么&p如何表示呢?假如我另外设变量int* q = &p;

    q(其实就是&p) 10BC 1F1B

      这样理解我们的函数pt(int* *p)会打印出什么了吧? 

      应该依次打印:t *t **t,即为:&p(也就是我们假设的q的值) p a的值,分别为:10BC 11FA 1。

      注意几点就好:

      1.无论怎么变化,请理解指针变量必须指向地址,就是说,定义了一个指针变量,那么这个指针变量的值一定是个地址,不论这个地址里面对应的值到底是什么东西。

        2.不管怎么在变量前面使用修饰符,比如int *p, int **p, 哪怕是int ********p(这个我也搞不懂了),只需记住,我就是定义了一个变量p而已,其它的都是类型,就像我们定义的int p; p是变量,只不过是int型的变量,p的值就只能是int型,同理,int *p;p是变量,只不过这个变量是int*类型的,值就只能是地址。那么int **p,p是变量,只不过是int**类型的,那么p的值就只能是地址在地址的一个值,比如上面例子中变量q,他的值就是10BC这个地址,儿10BC这个地址里面的值有事11FA这个地址。

      3.这里pt函数的参数int **p,注意传入的时候,就只能是地址的地址了。

    2.const & *说明

    请看如下代码(注释掉的代码就是错误的):

    #include <iostream>
    using namespace std;
    
    void reffun() {
    }
    
    void poinfun() {
    }
    
    int main() {
    	int a = 1;
    	int b = 2;
    	const int c = 3;
    
    	int* p1 = &a;
    	p1 = &b;
    	//p1 = &c;
    	const int* p2 = &a; //<==>int const* p2 = &a;
    	//*p2 = 5;
    	p2 = &b;
    	p2 = &c;
    	int* const p3 = &a;
    	//p3 = &b;
    
    	int &ref1 = a;
    	ref1 = b;
    	ref1 = c;
    
    	//int &ref2 = 10;
    	const int& ref2 = a; //<==>int const &ref2 = a;
    	//ref2 = b;
    	//ref2 = c;
    	//ref2 = 4;
    
    	int& const ref3 = a; //<==> int & ref3 = a;
    	ref3 = b;
    	ref3 = c;
    	ref3 = 10;
    
    	//int &ref4 = 10;
    	const int &ref4 = 10;
    
    	return 0;
    }
    

      const与指针:请在*号后画一条竖线,const修饰哪个,那么它的值就不能变。

      const与引用:其实引用最开始就是不能const的,即int & const a = b;和int &a = b是等价的。但是const int& a;这个const修饰的是&a,表明&a(这里不是取址符号,是指它本身,不能变。即a是不能改变b的值,但是b的值改变,会反映到a上。就理解为a是一个指向b的常量,int *const a = b ????)

      最重要的注意const修饰的引用和指针要对应常量的情况。比如const int &ref = 10;其中10是一个不能变的常量,如果使用int & const ref=10就错了,因为ref的值是可以变的。

    3.函数形式参数与引用和指针

    其实很好理解,指针传递进来就是地址,我对这个地址的值进行了修改,那么原始变量(地址还是这个地址)的值也会变化

    如果是引用,就相当于给原来的地址上配置了两个变量名,修改其中任何一个,都将对这个地址对应的值进行修改。

    指针:

    变量a 值为1 地址是1A1B

    其中有一个指针变量p指向了a,那么p的值就是1A1B,*p就是1,现在修改*p的值为2,那么

    变量a 值为2 地址是1A1B

    如果是引用:

    变量a 值为1 地址是1A1B

    有一个引用int &b = a;

    变量b 值为1 地址是1A1B

    那么修改a或者b都会影响另外一个的值。 

    注意下面的调用的影响:

    #include <iostream>
    using namespace std;
    
    void my_swap(int* m, int* n) {
    	int x = 3;
    	m = &x;
    }
    
    void my_ref_swap(int& m, int& n) {
    	m = 3;
    }
    
    int main() {
    	int a = 1;
    	int b = 2;
    	my_swap(&a, &b);
    	//my_ref_swap(a, b);
    	cout<<a<<endl;
    	return 0;
    }
    

      其中my_swap函数里面对指针变量m的指向进行了修改,注意:相当于对m这个形式参数进行修改,并不会对调用函数的a的值有任何影响。

      其实按照如下理解就可以了:

      my_swap函数int *m = &a, int *n = &b,那么m或者n的指向变化后,是不会对a b的原始值有影响的

      my_ref_swap函数int &m = a, int &n = b,a和b已经绑定在了m n上.

    4.指针 引用与多台

    看代码:

    #include <iostream>
    using namespace std;
    
    class A {
    public:
    	void test1() {
    		cout<<"A:test1()"<<endl;
    	}
    
    	virtual void test2() {
    		cout<<"A:test2()"<<endl;
    	}
    };
    
    class B:public A {
    public:
    	void test1() {
    		cout<<"B:test1()"<<endl;
    	}
    
    	void test2() {
    		cout<<"B:test2()"<<endl;
    	}
    };
    
    class C:public B {
    public:
    	void test1() {
    		cout<<"C:test1()"<<endl;
    	}
    
    	void test2() {
    		cout<<"C:test2()"<<endl;
    	}
    };
    
    int main() {
    	A a;
    	B b;
    	A *p = NULL;
    	p = &b;
    	p->test1();
    	b.test1();
    	a.test1();
    
    	p->test2();
    	b.test2();
    	a.test2();
    
    	C c;
    	B *d = NULL;
    	d = &c;
    	d->test2();
    	p = &c;
    	p->test2();
    
    	A m;
    	B n;
    	A &refa = n;
    	refa.test2();
    
    	return 0;
    }
    

      一目了然,不用说什么。virtual 基类指针 是多态的核心。

    骑着毛驴看日出
  • 相关阅读:
    c#实现串口操作 SerialPort
    ASP.NET Core 上传大文件无法接收的问题
    如何将qlv格式的腾讯视频转换为mp4格式
    C#中HttpWebRequest的GetRequestStream执行的效率太低,甚至偶尔死掉
    LGPL 与GPL的区别
    ffmpeg
    HTTP协议/RTSP协议/RTMP协议的区别
    C#写的CRC16检验算法
    VS里属性窗口中的生成操作释义
    iOS:APNS推送主要代码
  • 原文地址:https://www.cnblogs.com/linsir/p/4698626.html
Copyright © 2011-2022 走看看