C++语言程序设计 混乱复习(;—_—) ————指针与引用

一. 指针

const int n=10;
int y=2,z,k,t; 
int a[n]={3,4},b[n][n];

指针的基本使用
指针的定义:
<类型名> *变量名1,*类型名2;
指针的使用必须赋初始值

int *x=NULL;     //0同NULL),即空指针
	x=&y;   //把x指向y所在的地址
	*x=3;   //*x即访问y,即y赋值为3 
	cout<<"x="<<x<<" "<<"*x="<<*x<<" "<<"y="<<y<<endl;

在这里插入图片描述

//----------指针指向一维数组 
	x=a;   //等价于x=&a[0],都是指向一维数组的第一个 元素 
	cout<<"x="<<x<<" "<<"*x="<<*x<<" "<<"a[0]="<<a[0]<<endl;
	x+=1;
	cout<<"x="<<x<<" "<<"*x="<<*x<<" "<<"a[1]="<<a[1]<<endl;

在这里插入图片描述
//---------指针指向二维数组

方法1:通过单个指针直接访问数组首个元素

	x=&b[0][0];  //b数组定义为b[n][n]
	cout<<"x="<<x<<" "<<"*x="<<*x<<" "<<"b[0][0]="<<b[0][0]<<endl;
	x+=1;  //访问a[i][j+1] 
	cout<<"x="<<x<<" "<<"*x="<<*x<<" "<<"b[0][1]="<<b[0][1]<<endl;
	x+=n;  //访问a[i+1][j] 
	cout<<"x="<<x<<" "<<"*x="<<*x<<" "<<"b[1][1]="<<b[1][1]<<endl;

在这里插入图片描述
方法2:通过指针数组访问二维数组

为了更好的理解指针和二维数组的关系,我们先来定义一个指向 a 的指针变量 p:
int (*p)[4] = a;
括号中的*表明 p 是一个指针,它指向一个数组,数组的类型为int [4],这正是 a 所包含的每个一维数组的类型。

[ ]的优先级高于*,( )是必须要加的,如果赤裸裸地写作int *p[4],那么应该理解为int *(p[4]),p 就成了一个指针数组,而不是二维数组指针。

对指针进行加法(减法)运算时,它前进(后退)的步长与它指向的数据类型有关,p 指向的数据类型是int [4],那么p+1就前进 4×4 = 16 个字节,p-1就后退 16 个字节,这正好是数组 a 所包含的每个一维数组的长度。也就是说,p+1会使得指针指向二维数组的下一行,p-1会使得指针指向数组的上一行。

数组名 a 在表达式中也会被转换为和 p 等价的指针!

	int (*x1)[n]; //指针数组 
	b[0][0]=1;
	b[0][1]=2;
	b[1][1]=3; 
	x1=b; //一维数组指针 
	cout<<"x1="<<x1<<" "<<"*x1="<<*x1<<" "<<"**x1="<<**x1
		<<" "<<"b[0][0]="<<b[0][0]<<endl;
	b[4][5]=10;	
	cout<<"(*(x1+4)+5)="
		<<(*(x1+4)+5)   //(*(x1+i)+j)即访问第i行第j列的元素地址 
		<<"*(*(x1+4)+5)="
		<<*(*(x1+4)+5)	//*(*(x1+i)+j)即访问第i行第j列的元素的值 
		<<" "<<"b[4][5]="<<b[4][5]<<endl;

在这里插入图片描述

二. 动态内存

堆:存放动态数据的区域,动态内存也称为堆内存
动态内存时程序执行时才可以申请,使用和释放的内存,即存放动态数据的内存区域

——使用堆内存情况:
1:需要储存大量数据,一般申请使用堆内存
2:需要储存一组数,数据类型相同,但数据个数再编程时无法确定,运行时才能确定,这种时候无法定义数组,只能使用堆内存。

动态内存的申请与释放

1:malloc(size)申请————————free()释放
size表示要申请size个字节大小的内存空间
例:

int *p=(int *)malloc(sizeof(int));
free(p)

2:new申请————————delelte释放

int *p=new int;
delete p;

当new申请的是数组空间时,释放语句变为:
delete []<指针名>;

int *p=new int[10];
	delete []p;

三.引用

引用是变量或者其他编程实体(如对象)的实名

·引用不可以单独定义
·且必须在声明的同时完成初始化
·引用定义之后不可更改

定义格式:
<类型名>&引用名=变量名
例:

int x_n;
int &y_n=x_n;

此时y_n和x_n具有相同的地址
y_n代表x_n的值
&y_n代表x_n的地址
即 sizeof(y_n) 可以得到x_n(所指向的变量)的大小

指针与引用在函数中的应用

1:指针作为函数形参
采用的是地址调用:
函数实参是内存的地址(数组名,变量的地址,用变量地址初始化的指针)
指针(函数形参)指向内存的地址(函数实参)
特点:形参指针通过间接引用直接访问实参,可以改变实参的值,即函数调用后保留对实参变量的操作结果

————————————相当于实现返回多个结果

例:

void swap_(int *a,int *b)
{
	int *t;
	*t=*a;
	*a=*b;
	*b=*t;
}

int main() 
{
	int x=1;
	int y=2;
	cout<<"x="<<x<<" "<<"y="<<y<<endl;
	swap_(&x,&y);
	cout<<"x="<<x<<" "<<"y="<<y<<endl;
}

在这里插入图片描述
2:引用作为函数形参

特点
1:实参是相同类型的变量
2:参数传递属于地址传递
3:形参的引用和实参的变量是同一个实体,实际上没有参数

所以对引用的操作就是对实参的操作,函数调用可以改变实参的值。

void swap_(int &a,int &b)
{
	int t;
	t=a;
	a=b;
	b=t;
}

int main() 
{
	int x=1;
	int y=2;
	cout<<"x="<<x<<" "<<"y="<<y<<endl;
	swap_(x,y);
	cout<<"x="<<x<<" "<<"y="<<y<<endl;
	
}

在这里插入图片描述

3:常指针和指针常量
常指针:
指针指向的内容不可以通过指针的间接引用来改变
定义格式:
const <类型名>*<指针名>;
例:

int x=2;
const int *p=&x;

此时x的值可以自行修改,但无法通过*p进行修改

常引用:
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。
声明方式:
const <类型名> &<引用名>=变量名

int x=2;
const int &y_x=x;

指针常量:
指针本身成为常量,无法修改(即无法更改地址)
声明方式:
<类型名>*const<指针名>=<变量地址(&变量名)>;
例:

int x=2,y=1;
int * const p=&x;

此时可以直接或者修改x的值,但无法更改p指向的地址
若添加语句 p=&y,会报错

const出现在 * 的左边,则说明指针所指向的内容是常量(即可以指向常量)
--------不可以通过指针去修改指向地址的值(已经是常量),但可以通过变量修改
同时可以改变指针的指向
const出现在 * 的右边,则说明指针本身是常量(不可以指向常量)
--------------不可以改变地址的指向,因为本身是常量
如果*左右两边都出现const,那么说明指针本身是常量,它所指向的内容也是常量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值