第八章 善于使用指针

什么是指针

由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元
在C语言中,将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元。

  • 直接按变量名进行的访问,称为“直接访问”形式。
  • 将变量a的地址放在另一个变量中。然后通过后面的变量来找到变量a的地址,从而访问变量a,称为“间接访问”形式。
    在这里插入图片描述
    指针是一个地址
    指针变量是存放地址的变量。

指针变量

使用指针变量访问变量的例子

在这里插入图片描述

#include<stdio.h>
int main() {
	int a, b;
	int* pointer_1, * pointer_2;
	a = 100; b = 10;
	pointer_1 = &a;
	pointer_2 = &b;
	printf("a=%d,b=%d\n", a, b);
	printf("*pointer_1=%d,*pointer_2=%d\n", *pointer_1, *pointer_2);
	return 0;
}

"*"表示所定义的变量是指针变量。

怎样定义指针变量

定义指针变量的一般形式为

基类型 * 指针变量名;
如: int *pointer_1;

在定义指针变量时要注意:

  • 指针变量名前面的“*”表示该变量的类型为指针型变量。
  • 在定义指针变量时必须指定基类型
  • 赋给指针变量的是变量地址而不是任意类型的数据,而且只能是与指针变量的基类型相同类型的变量的地址。
  • 指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量。

怎样引用指针变量

在引用指针变量时,可能有3种情况:

  1. 给指针变量赋值
    如 p=&a;
  2. 引用指针变量指向的变量。
    如 printf(“%d”,*p); *p=1;
  3. 引用指针变量的值
    如 printf(“%o”,p); 即输出a的地址=&a;

在这里插入图片描述

在C语言中用到的“地址”都是指带类型的地址。只有纯地址是无法对内存单元进行访问的。

指针变量作为函数参数

它的作用是将一个变量的地址传送到另个一函数中。
在这里插入图片描述
在这里插入图片描述

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main() {
	int a, b;
	void swap(int* p1, int* p2);
	scanf("%d,%d", &a, &b);
	int* p1 = &a, * p2 = &b;
	printf("a=%d,b=%d\n", *p1, *p2);
	swap(p1, p2);
	printf("max=%d,min=%d\n", a, b);

	return 0;
}

void swap(int* p1, int* p2) {
	if (*p1 < *p2)
	{
		int temp = *p1;
		*p1 = *p2;
		*p2 = temp;
	}
}

在这里插入图片描述

通过指针引用数组

数组元素的指针

所谓数组元素的指针就是数组元素的地址。
在这里插入图片描述
在这里插入图片描述

通过指针引用数组元素

引用一个数组元素有两种方法:

  1. 下标法,用数组名加下标,如a[i]形式。
  2. 指针法,即地址法。由于数组名代表数组首元素的地址,因此可以通过数组名计算出数组中序号为i的元素的地址,其形式为*(a+i)。用一个指针变量p指向数组首元素,然后用*(p+i)调用a数组中序号为i的元素。

在这里插入图片描述
在这里插入图片描述

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main() {
	int a[10] = { 19,17,20,18,16,22,24,15,23,25 };
	int i, * p = a;
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(a + i));
	}
	printf("\n");

	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));
	}
	printf("\n");

	for (p; p < (a+10); p++)
	{
		printf("%d ", *p);
	}
	printf("\n");
	return 0;
}

指针运算:
通过指针的运算,可以方便地引用数组中的元素。

  1. 如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素。
    在这里插入图片描述

  2. 如果指针变量p的初值为 &a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,它们指向a数组的第i个元素。
    在这里插入图片描述

  3. (p+i)或(a+i)是p+i或a+i所指向的数组元素,即a[i]。

  4. 如果p原来指向a[0],执行++p后p的值改变了,在p的原值基础上加d,这样p就指向数组的下一个元素a[1]。

  5. 如果指针变量p1和p2都指向同一数组,若执行p2-p1,结果是两个地址之差除以数组元素的长度。结果就是这两个数组元素直接差几个元素。但是两个地址不能相加,如果p1+p2是无实际意义的。

注意以下几点问题:
在这里插入图片描述

用数组名作函数参数

在这里插入图片描述

  • 实参数组名代表一个固定的地址,或者说是指针常量,但形参数组并不是一个固定地址值,而是作为指针变量,在函数调用开始后,它的值等于实参数组首元素的地址,在函数执行期间,它可以再被赋值。
    在这里插入图片描述

在这里插入图片描述

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main() {
	void inv(int* x, int n);
	int a[10] = { 3,7,9,11,0,6,7,5,4,2 };
	printf("原始数组元素为:\n");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	inv(a, 10);
	printf("逆序后数组元素为:\n");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	return 0;
}
void inv(int* x, int n) {
	int* p, temp, * i, * j, m = (n - 1) / 2;
	for (i=x,j=(x+n-1),p=(x+m); i <=p ; i++,j--)
	{
		temp = *i;
		*i = *j;
		*j = temp;
	}
}

在这里插入图片描述
在这里插入图片描述

通过指针引用字符串

字符串的表示形式

在C语言中,可以用两种方法访问一个字符串。

  • 用字符数组存放一个字符串,然后用字符数组名和下标访问字符数组中的元素,也可以通过字符数组名用%s格式输出一个字符串。
  • 用字符指针指向一个字符串。可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。

在这里插入图片描述

字符指针作函数参数

在这里插入图片描述

使用字符指针变量和字符数组的区别

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

提高部分

指向函数的指针

在这里插入图片描述

返回指针值的函数

在这里插入图片描述

指针数组

在这里插入图片描述

多重指针——指向指针的指针

在这里插入图片描述

小结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值