C++指针&引用简笔

摘要:
1.混淆的辅助指针#include<无效pt(int**t){cout<int*p=&pt(&p11FA10BC)然后,假设我设置了变量int*q=&q(事实上,它与我们定义的intp;int*p;usingspacestd;intb=2;const*p2=&aamp;c;//p3=&amp,//ref2=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表示为(我们的地址都是瞎编的):

a111FA

  变量p表示为:

p11FA10BC

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

q(其实就是&p)10BC1F1B

  这样理解我们的函数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++指针&amp;amp;引用简笔》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Jasper Report 教程深入理解Enum(枚举类)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

前端缓存http请求

需求: 1、 重复的请求,使用缓存 2、 不重复的请求,允许发送 3、 连续两次重复的发送,两次返回的结果是一样的,且第二次不发送请求 1、搭建前端服务 vue-cli 一步到位  <template> <div class="hello"> <button v-on:click="getrs(1)">...

C++第三十九篇 -- 研究一下Windows驱动开发(二)-- 驱动程序中重要的数据结构

数据结构是计算机程序的核心,I/O管理器定义了一些数据结构,这些数据结构是编写驱动程序时所必须掌握的。驱动程序经常要创建和维护这些数据结构的实例。 一、驱动对象(DRIVER_OBJECT) 每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候,被内核中的对象管理程序所创建的。 驱动对象用DRIVER_OBJECT数据结构表示,它作为...

OpenCV截取图像的某一区域

一、概述   案例:加载一张彩色图片,并截取其中的部分输出。 二、示例图片 三、示例代码 #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char con...

Docker容器内无法解析DNS的问题 Could not resolve host

在docker容器内使用  yum 或者 wget 命令,会提示  cannot resolving host address 无法解析主机地址  ,也就是容器内无法解析DNS。 Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&...

Redis学习笔记之延时队列

目录 一、业务场景 1.1 实践场景 1.2 实现方式 二、Redis延时队列 2.1 Redis列表实现 2.2 Redis集合实现 一、业务场景 所谓延时队列就是延时的消息队列,下面说一下一些业务场景比较好理解 1.1 实践场景 订单支付失败,每隔一段时间提醒用户 用户并发量的情况,可以延时2分钟给用户发短信 ... 1.2...

4.docker学习之镜像

镜像我们知道,我们想在Windows操作系统上跑Linux,需要安装一个虚拟机程序,然后下载一个Linux镜像,在该虚拟机程序中创建一个虚拟机,并使用该镜像安装对应的Linux操作系统,安装好之后,即可在Windows系统下跑虚拟机中的Linux系统。此时,我们发现,这里所说的镜像,类似于操作系统的安装包,这里所提到的镜像中包含了对应的操作系统。这是传统镜...