指针(4)有点难

指针(4)

来做个简单的回顾:

指针数组

1.是数组
2.是存放指针的数组

char* arr1[5];

int*arr2[3];

数组指针

1 .是指针
2 .指向数组的指针

字符指针:char*pc;

整型指针:int*pi;

int (*p) [10];//P就是数组指针,p指向的数组有10个元素,每个元素的类型是int
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int(*p)[10] = &arr;//取的是整个数组的地址
	return 0;
}

例子

想使用p这个数组访问arr数组的内容

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int(*p)[10] = &arr;//取的是整个数组的地址

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

1 .二维数组传参的本质

代码如下:

void Print(int arr[3][5], int r, int c)//int (*arr)[5]
{
	int i = 0;
	for (i = 0; i <=r; i++)
	{
		for (int j = 0; j <=c; j++)
		{
			printf("%d", arr[i][j]);//*(*(arr+i)+j)
            //*(arr+i)==arr[i]
            //arr[i]是第i行的数组名,数组名又是数组首元素的地址,arr[i]=&arr[i][0]
		}
		printf("\n");
	}
}

int main()
{
	int arr[3][5] = { (1,2,3,4,5),(2,3,4,5,6),(3,4,5,6,7) };
	Print(arr, 3, 5);
	return 0;
}

前情回顾

一维数组传参

数组名是首元素的地址,一维数组传参的时候,其实传递的是首元素的地址。

函数的参数可以写成数组,也可以写成指针。

那二维数组呢?

其实二维数组的数组名也是数组首元素的地址,二维数组的数组名就是它第一行的地址,第一行是一个一维数组,传过去的是第一行这个一维数组的地址

[外链图片转存中…(img-Lf2wiLHP-1715345940161)]

[外链图片转存中…(img-HzRavJos-1715345940162)]

总结

arr[i]==*(arr+i)

arr[i] [j]=* (*(arr+i)+j)

不管是一维数组还是二维数组,形参可以写成数组,也可以写成指针,这里要对数组名做深入理解

2 .函数指针变量

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

int main()
{
	int a = 2;
	int b = 6;
	Add(a, b);
	printf("%p\n", &Add);
	return 0;
}

运行结果:

[外链图片转存中…(img-lowcQ39K-1715345940163)]

小小的不同

&函数名和函数名的地址没有不同

[外链图片转存中…(img-815uKMMu-1715345940163)]

[外链图片转存中…(img-1Si0XL6D-1715345940163)]

函数指针变量的注意点

我们之前学习调用函数的时候

形式如下:

int ret2 = Add(4, 5);

其实函数指针变量也可以写成另外一种形式,也是可以的:

int ret3 = pf(4, 5);

但是写上*的时候,不要忘记加(),因为这时候pf会和(4,5)相结合,调用的·是函数值的地址,这就有问题了

函数指针类型解析:

int (*pf3) (int x, int y)
|     | ------------
|     |         |
|     |     pf3指向函数的参数类型和个数的交代
|   函数指针变量名
pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型

3 .两段有趣的代码

代码1:

(*(void (*)())0)();

[外链图片转存中…(img-pL9wxN6Q-1715345940163)]

代码2:

void (*signal(int , void(*)(int)))(int);

[外链图片转存中…(img-FNyDCtyc-1715345940164)]

[外链图片转存中…(img-3hjNYgd0-1715345940164)]

可以这样理解,但是语法不允许这样写

4 .typedef关键字

typedef unsigned int unit;
int main()
{
	unsigned int num;
	unit num;
	return 0;
}

对数组指针重命名:

typedef int(*parr_t)[10]//一定要把指针放里面
int main()
{
	int arr[6] = { 0 };
	int(*p) = &arr;
	parr_t p2 = &arr;
	return 0;
}

对函数指针重命名:

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

int main()
{
	int(*pf)(int, int) = Add;
	pf_t pf2 = Add;
	return 0;
}

那么我们在有趣的代码这一节中那个函数的声明也可以写成:

typedef void(*pf_t)(int)
    int main()
{
    pf_t signal(int,pf_t);
    return 0;
}

5 .函数指针数组

int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Plus(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}
int main()
{
	int(*pf[4])(int,int) = {Add,Sub,Plus,Div};//函数指针数组
                           //0,  1  ,2  ,3
    int i=0;
    for(i=0;i<4;i++)
    {
        int ret=pf[i](6,2);
        printf("%d\n",ret);
}
	return 0;
}

6 .转移表

函数指针数组的⽤途:转移表

例子:计算器

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void menu()
	{
	printf("**************************\n");
	printf("*******1 .Add 2 .Sub******\n");
	printf("*******3 .Plus4 .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 Plus(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		int(*prArr[5])(int,int) = {0,Add,Sub,Plus,Div};//函数指针数组
		if (input >= 1 && input <= 4)
		{
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			ret = prArr[input](x, y);
			printf("%d\n", ret);
		}
		if (input == 0)
		{
			printf("您已退出计算器\n");
		}
		else
		{
			printf("请重新做选择\n");
		}
	} while (input);
	
	return 0;
}

7 .回调函数是什么?

回调函数就是⼀个通过函数指针调⽤的函数。

如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。

[外链图片转存中…(img-wA8XZowf-1715345940164)]

ret);
}
if (input == 0)
{
printf(“您已退出计算器\n”);
}
else
{
printf(“请重新做选择\n”);
}
} while (input);

return 0;

}


## 7 .回调函数是什么?

回调函数就是⼀个通过函数指针调⽤的函数。

 如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。



[外链图片转存中...(img-wA8XZowf-1715345940164)]

Calc起到了封装的作用

相关推荐

  1. 指针4有点

    2024-05-14 00:00:06       32 阅读
  2. c语言上机小练(有点

    2024-05-14 00:00:06       55 阅读
  3. 学习(指针4

    2024-05-14 00:00:06       56 阅读
  4. C语言--指针4

    2024-05-14 00:00:06       36 阅读
  5. C语言.指针4

    2024-05-14 00:00:06       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-14 00:00:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-14 00:00:06       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-14 00:00:06       82 阅读
  4. Python语言-面向对象

    2024-05-14 00:00:06       91 阅读

热门阅读

  1. 高精度模拟算法

    2024-05-14 00:00:06       25 阅读
  2. Oracle中long和clob的区别和例子

    2024-05-14 00:00:06       34 阅读
  3. Redis——RDB、AOF和混合持久化机制

    2024-05-14 00:00:06       36 阅读
  4. @Validated校验多层json

    2024-05-14 00:00:06       36 阅读
  5. centos7下vim命令笔记-查找字符

    2024-05-14 00:00:06       32 阅读
  6. 【C++】防止头文件被重复包含

    2024-05-14 00:00:06       34 阅读
  7. Cocos Creator 3.8.x报错:5302

    2024-05-14 00:00:06       26 阅读
  8. 消息 队列

    2024-05-14 00:00:06       36 阅读