C语言之深入理解指针(进阶)

  • 根据博客C语言之简单理解指针和深入理解数组中了解到指针是一个变量,它存储的地址,了解到指针的类型是由指针中的地址中存储中的数据类型决定的,有整型指针、字符指针等,还了解到指针操作等。本文将带大家深入理解指针。

1.数组指针与指针数组

  • 数组指针和指针数组的理解:
    首先,先看两个式子
    int (*p1)[200];
    int * p2[200];
    上面两个式子中的p1和p2有什么区别呢?-------p1和p2一个是数组指针一个是指针数组。
    那么哪个是数组指针?哪个是指针数组呢?--------这个要根据运算符的优先级来看("[ ]"的优先级要高于“ * ”,虽然“( )”的优先级和“[ ]”的优先级是一样高的,但是它们的结合顺序是从左到右的),所以p1先和“ * ”结合,变成一个指针,再和“[ ]”结合,表示该指针中存放的地址是一个数组的地址,故p1时数组指针(是一个指针)。p2先和“[ ]”结合,变成一个数组,再和“ * ”结合,表示该数组中存的是一个一个的指针,故p2时指针数组(是一个数组)。

  • 数组指针的使用:
    根据上面,我们知道,数组指针是一个指针,该指针中存放的地址是一个数组的地址。

#include <stdio.h>

int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int(*p)[5] = &arr;

	printf("&arr[0] = %p\n", &arr[0]);
	printf("&arr = %p\n", &arr);
	printf("*p = %p\n", *p);

	return 0;
}

在这里插入图片描述

  1. 代码中是将arr数组的地址给p,p是一个数组指针。
  2. 数组的地址就是数组首元素的地址。
  • 指针数组的使用:
    根据上面对指针数组的理解,我们知道,指针数组是一个数组,数组中存放的是一个一个指针。
#include <stdio.h>

int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int a = 10;
	int arr1[] = { 0 };
	int *p[] = { arr, &a, arr1 };

	printf("&arr  = %p, p[0] = %p\n", &arr, p[0]);
	printf("&a    = %p, p[1] = %p\n", &a, p[1]);
	printf("&arr1 = %p, p[2] = %p\n", &arr1, p[2]);

	return 0;
}

在这里插入图片描述

  1. 上面代码中p是一个指针数组,数组里存放的是一个一个的指针。
  2. p中存放了指向数组arr、整型变量a和数组arr1的地址的指针。

2.指针传参

  1. 一级指针传参
    当函数需要实际参数的地址的时候,用一级指针进行传参。
#include <stdio.h>

void swap(int *pa, int *pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}
int main()
{
	int a = 2, b = 3;

	swap(&a, &b);

	printf("a = %d, b = %d\n", a, b);

	return 0;
}

在这里插入图片描述
2. 二级指针的传参
当需要将一个指针作为实际参数传到函数中时,需要用二级指针作为形式参数。
如果在上面的代码的基础上,想要通过两个指针,然后交换a和b的值,而不是直接交换,就要用到二级指针传参,如下所示:

#include <stdio.h>

void swap(int **ppa, int **ppb)
{
	int tmp = **ppa;
	**ppa = **ppb;
	**ppb = tmp;
}
int main()
{
	int a = 2, b = 3;
	int *pa = &a, *pb = &b;

	swap(&pa, &pb);

	printf("a = %d, b = %d\n", a, b);

	return 0;
}

在这里插入图片描述

3.函数指针与函数指针数组

  1. 函数指针的理解
    函数指针,是一个指针,指针里存放的是函数的地址。而函数的地址是函数第一句指令的地址。
  2. 函数指针的使用
    函数指针的定义:函数返回值类型 (*p) (参数);
#include <stdio.h>

void sheena()
{
	printf("sheena~~~~~~~~~\n");
}
int main()
{
	void(*p)() = sheena;//函数指针的初始化

	p();//相当于sheena();
	(*p)();//相当于sheena();

	return 0;
}

在这里插入图片描述

  • 当函数指针特别复杂时,可以用typedef来简化。
    void (*swap (int, void( * )(int))) (int);
    可以写作:
    typedef void(*p_func) (int);
    p_func swap(int , p_func);
  1. 函数指针数组的理解
    就相当于指针数组,函数指针数组也是一个数组,指针数组里存放的是一个一个指针,函数指针数组里存放的也是一个一个指针,只不过这些指针不是不同的指针,而是函数指针。
  2. 函数指针数组的定义
    函数指针数组的定义: 函数返回值 (*p_func[5]) (参数);
    或者 函数返回值 *p_func[5] (参数);
    或者 函数返回值 ( * )(参数) p_func[5];
  3. 函数指针数组的使用:
    详细请见C语言之指针进阶之函数指针数组的使用
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值