C++之指针与引用(一)

本文详细介绍了C++中的指针和引用概念,包括指针的定义、如何通过指针访问变量、指针作为函数参数的用法。文中通过实例展示了如何通过指针交换变量值,以及如何利用指针实现多个变量值的传递。同时,讲解了引用的概念及其与指针的关系,强调了引用在函数调用中的作用。
摘要由CSDN通过智能技术生成

1. 什么是指针

按变量地址存取变量值的方式称为直接存取方式,或者直接访问方式。程序经过编译后将变量名转换为变量的地址,对变量值的存取都是通过地址进行。
例如,语句cout << i;的执行是这样的:根据变量名与地址的对应关系,找到变量 i 的地址2000,i 是整型变量在内存中占4个字节,因此从2000开始的4个字节中取出数据(变量的值3),把它输出。输入时如果用“cin>>i;,在执行时,就把从键盘输入的值送到地址为2000开始的整型存储单元中。如果有语句“k=i+j;”,则从2000字节开始的整型变量存储单元中取出 i 的值(值为3),从2004字节开始的变量存储单元中取出 j 的值(值为6),将它们相加后再将其和(9)送到 k 所占用的2008字节开始的整型存储单元中。

可以通过下面语句将 i 的起始地址(2000)存放到 i_pointer中, i_pointer被定义用来存放一个整型变量的地址,编译系统给这个变量分配4个字节。将变量 i 的地址存放到一种专门用来存放地址的变量中,称为间接存取(间接访问)的方式。

i_pointer = &i;		//&i 是变量i的存储单元的起始地址

一个变量的地址称为该变量的指针,通过指针能找到所需的变量单元。如果有一个变量是专门用来存放地址(即指针)的,则它称为指针变量。

2. 变量与指针

2.1 定义指针变量

C++规定所有变量在使用前必须先定义,即指定其类型。在编译时按变量类型分配存储空间。在Visual C++中,为每一个指针变量分配4个字节的存储空间。对指针变量必须将它定义为指针类型。下面给出一个具体例子:

int i,j;		//定义整型变量i,j
int * pointer_1, *pointer_2;	//定义指针变量 pointer_1,pointer_2

**指针变量的基类型就是该指针变量指向的变量的类型。**定义指针变量的一般形式为:
基类型 * 指针变量名;

int * pointer_1;	//定义pointer_1为指向int型数据的指针变量
float * pointer_3;	//定义pointer_3为指向float型数据的指针变量
char * pointer_4;	//定义pointer_4为指向char型数据的指针变量

如何使一个指针变量指向另一个变量呢?只需把被指向的变量的地址赋给指针变量即可。例如:

i_pointer = &i;		//将变量 i 的地址存放到指针变量i_pointer中

在定义指针变量时注意:

  1. 在定义指针变量时必须指定基类型
    一个变量的指针包括两个方面的含义,一是以存储单元编号表示的地址,一是它指向的存储单元的数据类型(如int,char,float等),即基类型。指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。
  2. 怎么表示指针类型。
    比如:指向整型数据的指针类型表示为“ int * ”,读作“指向 int 的指针”或简称“ int 指针”。
  3. 不能用一个整数给一个指针变量赋值
  4. 一个指针变量只能指向同一个类型的变量。不能忽而指向一个整型变量,忽而指向一个双精度型变量。指向整型数据的指针变量中只能存放整型数据的地址,而不能存放浮点型或其他类型数据的地址。也就是说,指针变量pointer_1只能用来指向整型数据(例如 i 和 j),而不能指向浮点型变量 a 和 b。

2.2 引用指针变量

&a 为变量 a 的地址,*p 为指针变量 p 所指向的存储单元。
对 & 和 * 运算符的说明:

int a,b;
int * pointer_1, * pointer_2;
a = 100; b = 10;
pointer_1 = &a;
pointer_2 = &*pointer_1;	#等价于pointer_2 = &a	
b = *&a;	#等价于b = *pointer_1 = a
  1. &pointer_1的含义
    & 和 * 两个运算符的优先级别相同,但按自右向左方向结合,因此先进行
    pointer_1的运算,它就是变量 a ,再执行 & 运算。因此 &*pointer_1 与 &a 相同,即变量 a 的地址。
  2. &a 的含义
    先进行 &a 的运算,得 a 的地址,再进行 * 运算,即 &a 所指向的变量,
    &a 与 a 等价。
    下面给出一个例子:
//例 输入a,b两个整数,按先大后小的顺序输出a,b(用指针变量处理)
int main(){
	int *p1, *p2, *p, a, b;
	cout << "提示:请输入两个整数" << endl;
	cin >> a >> b;   //输入两个整数
	p1 = &a;    //使p1指向a
	p2 = &b;   //使p2指向b
	if (a < b){
		p = p1; p1 = p2; p2 = p;   //如果a<b,使p1与p2的值互换  p1指向大的值
	}
	cout << "a=" << a << " b=" << b << endl;
	cout << "max=" << *p1 << " min=" << *p2 << endl;
	return 0;
}

解题思路:定义两个(int*)型指针变量 p1 和 p2,使它们分别指向 a 和 b 。使 p1 指向 a 和 b 中的较大者,p2 指向较小者。顺序输出 *p1 、 *p2就实现了按先大后小的顺序输出 a 和 b。
这个问题的算法是不交换整型变量的值,而是交换两个指针变量的值。变量 a 和 b 的内容并未交换,但 p1 和 p2 的值改变了。

2.3 用指针作函数参数

函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送给被调用函数的形参。
下面给出一个指针作函数参数的例子:

//例 对输入的两个整数按大小顺序输出 今用函数处理 而且用指针类型的数据作函数参数
int main(){
	void swap(int *p1, int *p2);   //函数声明
	int *pointer_1, *pointer_2, a, b;
	cin >> a >> b;
	pointer_1 = &a;
	pointer_2 = &b;
	if (a < b) swap(pointer_1, pointer_2);
	cout << "max=" << a << " min=" << b << endl;
	return 0;
}

void swap(int *p1, int *p2){ //函数swap的作用是将*p1和*p2的值互换
	int temp;
	temp = *p1;  //temp是整型变量,而不是指针变量
	*p1 = *p2;
	*p2 = temp;
}

本例采取的方法是交换 a 和 b 的值,而 p1 和 p2 的值不变。 虚实结合是采用单向的“值传递”方式,只能从实参向形参传数据,形参值的改变无法回传给实参。 为了使在函数中改变了的变量值能被main函数所用,不能采取要把改变值的变量作为实参的办法,而应该用指针变量作为函数实参。在函数执行过程中使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变化依然保留下来,这样就实现了 “通过调用函数使变量的值发生变化,在主调函数中使用这些改变了的值” 的目的。
如果想通过函数调用得到 n 个要改变的值,可以采取下面的步骤:

  1. 在主调函数中设 n 个变量,用 n 个指针变量指向它们;
  2. 编写被调用函数,其形参为 n 个指针变量,这些形参指针变量应当与主调函数中的 n 个指针变量具有相同的基类型。
  3. 在主调函数中将 n 个指针变量作实参,将它们的值(是地址值)传给所调用函数的 n 个形参指针变量,这样,形参指针变量也指向这 n 个变量;
  4. 通过形参指针变量的指向,改变该 n 个变量的值;
  5. 在主调函数中就可以使用这些改变了值的变量。

函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作函数参数,就可以通过指针变量改变主调函数中变量的值,相当于通过函数调用从被调用的函数中得到多个值。如果不用指针变量是难以做到这一点的。
下面给出一个例子:

//例 输入a,b,c 3个整数,按由大到小的顺序输出
int main(){
	void exchange(int *, int *, int *);  //对exchange函数的声明
	int a, b, c, *p1, *p2, *p3;
	cin >> a >> b >> c;      //输入3个整数
	p1 = &a;
	p2 = &b;
	p3 = &c;
	exchange(p1, p2, p3); //交换p1,p2,p3指向的3个整型变量的值
	cout << a << " " << b << " " << c << endl;  //按由大到小的顺序输出3个整数
	return 0;
}

void exchange(int *q1, int *q2, int *q3){
	void swap(int *, int *); //对swap函数的声明  
	if (*q1 < *q2)  swap(q1, q2);	//调用 swap,将 q1 与 q2 所指向的变量的值互换
	if (*q1 < *q3) swap(q1, q3);	//调用 swap,将 q1 与 q3 所指向的变量的值互换
	if (*q2 < *q3)  swap(q2, q3);	//调用 swap,将 q2 与 q3 所指向的变量的值互换
	
void swap(int *pt1, int *pt2){ //函数swap的作用是将pt1和pt2所指向的变量的值互换
	int temp;
	temp = *p1;  //temp是整型变量,而不是指针变量
	*p1 = *p2;
	*p2 = temp;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值