​​​前言:

我们在初学c语言时都会遇到的一个题目,那就是交换两个数字的大小,我们需要定义两个变量保存两个值,再定义一个temp进行中间值保存

int temp=0;
int a=10;
int b=20;
temp=a;
a=b;
b=temp;

那么在后面我们接触到了指针,我们该如何使用指针进行两个数的交换呢?

一、指针是什么

通过地址能找到所需的变量单元,我们可以说,地址指向该变量单元。
指针就是地址。
指针(地址)变量: 类型*变量名  储存的就是指针  指针变量就是一个变量
指针变量:解引用,间接访问符
例如
int *p=&a   就是定义了一个指针变量,p(指针)变量指向a的地址
*p=100 //a=100   *p指向a的值

(1)指针变量的定义

//分别定义了 int、float、char 类型的指针变量
int *x;
float *f;
char *ch;

如上面的定义,指针变量名为 x、f、ch。并不是*x、*f、*ch

(2)指针变量的使用

取地址运算符&:单目运算符&是用来取操作对象的地址。例:&i 为取变量 i 的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。


指针运算符*(间接寻址符):与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例:x = &i,x 为 i 的地址,*x 则为通过 i 的地址,获取 i 的内容。

(3)指针变量的初始化

	//声明了一个普通变量 a
	int a=10;
	//声明一个指针变量pa,指向变量 a 的地址
	int* pa;
	//通过取地址符&,获取 a 的地址,赋值给指针变量
	pa = &a;
	//*pa指向a的值
	*pa = a;
	//通过间接寻址符,获取指针指向的内容
	printf("%d", *pa);
	return 0;

(4)指针变量的赋值,运算

int main()
{
	int a;
	int b;
	int c;
	//定义p1,指向a,通过p1将a值赋值为50
	int* p1 = &a;
	*p1 = 50;
	printf("%d\n", a);
	//p1指向b,通过p1将b值赋值为100
	p1 = &b;
	*p1 = 100;
	printf("%d\n", b);
	//p1指向c,通过p1将c值赋值为200
	p1 = &c;
	*p1 = 200;
	printf("%d\n", c);
	return 0;
}

(5)二级指针的定义初始化

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里? 这就是二级指针 。

1、*pp通过对pp中的地址进行解引用,这样找到的是 p1 , *pp 其实访问的就是 p1

2、**pp 先通过 *pp 找到 p1 ,然后对 p1 进行解引用操作: *p1 ,那找到的是 a

int main()
{
	int a = 10;

	int* p1 = &a;

	printf("%d\n", &p1);  //p1也是一个变量(指针变量),拥有自己的地址
	printf("%d\n", &a);
	printf("%d\n", p1);   //p1指向a的地址
	printf("%d\n", *p1);

	int** pp = &p1;        //定义了一个二级指针变量pp指向p1的地址
	//*pp = p1;     //*pp其实就是p1 ,p1指向&a,所以*pp也指向&a
	//**pp = *p1;  //**pp其实就等于*p1 ,*p1指向a的值,因此**pp指向a的值
	printf("%d\n", *pp);
	printf("%d\n", **pp);
	return 0;
}

 二、用函数编写两个数交换

实践:

上面我们讲解了指针基本用法,那么我们如何用编写函数,用指针来实现两数交换呢?

实现 Swap 函数,将两个数交换。版本 1(不成功)。
void Swap(int x,int y)//交换不成功
 {
 int tmp = x;
 x = y;
 y = tmp;
 }

 int main()
 {
 int a = 10;
 int b = 20;
 printf("交换前:%d,%d\n",a,b);
 Swap(a,b);
 printf("交换后:%d,%d\n",a,b);
 return 0;
 }

 如果想在 Swap 函数中修改 main 中 a,b 的值,必须突破不同函数间的限制,而

指针就能达到这个效果,版本 2:
void Swap(int *p1,int *p2)
 {
 int *tmp = p1;
 p1 = p2;
 p2 = tmp;
}

int main()
 {
 int a = 10;
 int b = 20;
 printf("交换前:%d,%d\n",a,b);

 Swap(&a,&b);
 printf("交换后:%d,%d\n",a,b);
 return 0;
 }

执行结果如下:

你会发现数据没有交换成功,这是为什么呢?

 

在 Swap 函数中增加解引用操作,版本 3:

 void Swap(int *p1,int *p2)
 {
 int *tmp; //1
 *tmp = *p1; //2
 *p1 = *p2; //3
 *p2 = *tmp; //4
 }

 int main()
 {
 int a = 10;
 int b = 20;
 printf("交换前:%d,%d\n",a,b);
 Swap(&a,&b);
 printf("交换后:%d,%d\n",a,b);
 return 0;
}

上面代码运行到注释的 2 这句时,程序崩溃,在编译时编译器会提醒你”使 用了未初始化的局部变量”,这是因为使用了野指针。

野指针:也称为悬挂指针,是没有访问权限的地址。这个地址有可能不存在,
也有可能存在但是你不能访问。比如”长安街-5 号”这是一个不存在的地址访
问当然会失败,而”中南海”这个地址是存在的,但是你却不能进入(虽然你想)。
NULL:空指针,表示当前是一个无效的指针,注意和野指针区分。
如果你有过网络购物的经验这两个概念就非常好区分。你在网上买了一本书, 但是收货地址的手机号是空的,没有写,这就是 NULL 指针,卖家很容易辨别这个 错误。如果你把手机号写错了”13888889999”,这个卖家是发现不了这个错误的, 只有等到快递小哥给你打电话时才发现电话号是空号或者接电话的是刘先生
把野指针消除,版本 4:
void Swap(int* p1, int* p2)
{
	int tmp;
	tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//实现两个数的交换
int main()
{
	int a;
	printf("请输入a=");
	scanf("%d", &a);

	int b;
	printf("请输入b=");
	scanf("%d", &b);
	
	

	Swap(&a, &b);
	printf("交换后a=%d b=%d\n", a, b);

	return 0;
}

编译结果:

 

 

 如果觉得有帮助麻烦点个赞!!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐