零基础C语言学习日志15(深入理解指针(4))

目录

 

字符指针变量

数组指针变量

数组指针变量是什么?

数组指针变量怎么初始化

二维数组传参的本质

函数指针变量

函数指针变量的创建

两段代码

typedef关键字

函数指针数组 

转移表


 

字符指针变量

字符数组中可以存放字符串,字符数组的内容可以修改。

常量字符串:和数组是非常相似的,也是在一个连续空间中存放了多个字符,但是常量字符串的内容不能修改。

《剑指offer》中收录了一道和字符串相关的笔试题,我们一起来学习一下!

str1 == str2 比较的是数组首元素的地址。

str3 == str4 比较的是两个指针变量中存放的地址。

为什么str3和str4相等呢?

这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,
当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。

数组指针变量

数组指针变量是什么?

我们已经了解到了很多指针变量,比如整形指针变量(int*)和浮点形指针变量(float*)。那么数组指针变量应该是存放数组地址,指向数组的指针变量。

解释:p先和*结合,说明p是一个指针变量,然后指针指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫 数组指针。

这里要注意: [ 的优先级要高于 * 号的,所以必须加上 () 来保证 p 先和 * 结合

数组指针变量怎么初始化

怎么存放数组的地址?

二维数组传参的本质

二维数组的每一行其实是一个一维数组,那么二维数组其实可以理解为是一维数组的数组,也就是说二维数组的每个元素其实是一个一维数组。

函数指针变量

函数指针变量的创建

什么是函数指针变量呢?

函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数的。

那么函数也有地址吗?

可以从上图中看到,函数当然是有地址的。函数名就是函数的地址,当然也可以用&函数名得到函数的地址,没有区别。

两段代码

出自《c陷阱与缺陷》2.1理解函数的声明

1. 将0这个整数强制类型转换成函数指针类型

2. 去调用0地址处的这个函数

上面的代码是一个函数的声明,函数的名字是signal,signal函数的参数有2个,第一个是int类型,第二个是函数指针类型void(*)(int),这个函数指针指向的函数有一个int参数,返回类型是void,signal函数的返回值类型,也是一个函数指针类型L:void(*)(int),这个函数指针指向的函数有一个int参数,返回类型是void。

typedef关键字

typedef是用来类型重命名的,可以将复杂的类型,简单化 

如果是指针类型,能否重命名呢?其实也是可以的,比如,将int*重命名为 ptr_t,这样写:

但是对于数组指针和函数指针稍微有点区别:
比如我们有数组指针类型 int(*)[5] ,需要重命名为 parr_t,那可以这样写:

函数指针类型的重命名也是一样的,比如,将 void(*)(int)类型重命名为 pf_t,就可以这样写:

 

 

 

以上就是我们一些重命名的格式

 

函数指针数组 

那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

int (*parr[4])();

parr 先和 [ ] 结合,说明 parr 是数组,数组的内容是什么呢?是 int(*)( ) 类型的函数指针。

转移表

函数指针数组的应用:转移表

例如:写一个简易的计算机

#include<stdio.h>
void menu()
{
	printf("****************************\n");
	printf("***** 1.add    2.sub  ******\n");
	printf("***** 3.mul    4.div  ******\n");
	printf("*****   0. exit       ******\n");
	printf("****************************\n");
}

int Add(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{
	return x - y;
}

int Mul(int x, int y)
{
	return x * y;
}

int Div(int x, int y)
{
	return x / y;
}

int main()
{
	int input = 0;
	int (*pfArr[])(int, int) = {NULL, Add, Sub, Mul, Div};
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		int a = 0;
		int b = 0;
		int r = 0;
		if(input == 0)
			printf("退出计算器\n");
		else if (input >= 1 && input <= 4)
		{
			printf("请输入2个操作数:");
			scanf("%d %d", &a, &b);
			r = pfArr[input](a, b);
			printf("r = %d\n", r);
		}
		else
			printf("选择错误,重新选择!\n");
	} while (input);
	return 0;
}

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值