自学内容网 自学内容网

【c语言篇】指针进阶

目录

一、字符指针

二、指针数组

​编辑

三、数组指针

3.1数组指针的定义

3.2数组指针的使用

四、函数指针

五、函数指针数组

六、回调指针

前言

💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!

👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对C++感兴趣的朋友,让我们一起进步!                     

之前我们初步了解了指针,今天进一步学习指针,


一、字符指针

1.1在指针类型中我们知道有一种指针类型叫字符指针char*

一般使用:

int main()
{
    char ch='w';
    char *pc=&ch;
    *pc='w';
    return 0;

还有一种使用方式,也是更合适的方式:

int main(){
        const char* p="abcde";  //这里是将字符串abcde首字符的地址放到p中;

        printf("%s\n",p);

        return 0;

}

二、指针数组

所谓指针数组,就是存放地址的数组。

int *arr1[10];        //整型指针的数组

char *arr2[10];     //一级字符指针的数组

char**arr3[4];        //二级字符指针的数组

先看一个例子:

int main()
{
const char* arr[4] = { "abc","def","cbd","sad"};
for (int i = 0; i < 4; i++)
{
printf("%s\n", arr[i]);
}
return 0;
}

运行结果如下,很显然将arr里面所有值打印出来了

三、数组指针

3.1数组指针的定义

数组指针其实是指针。看下面例子

int (*p1)[10];

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

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

3.2数组指针的使用

既然数组指针指向的是数组,那数组指针中存放的应该是数组地址

具体如何使用呢,先看如下代码:

#include<stdio.h>
void print2(int(*p)[4], int r, int c)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j< c; j++)
{
//(*(p+i))[j]
printf("%d", p[i][j]);
}
printf("\n");
}

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

我们在print2函数里用到了数组指针,目的就是将arr里的数依次打印出来。

先看下示例,能帮助你更好的分清:

int arr[5];  //整型数组数组是5个元素

int *pa[10]; //指针数组,数组10个元素,每个元素int型

int (*pa1)[10];  //数组指针,该指针指向一个数组,数组是10个元素,每个元素是int类型

int (*pa2[10])[5];  //该类型是数组指针,pa2是数组,有10个元素,数组中每个类型是:int(*)的数组指针类型。

四、函数指针

函数指针,指向函数的指针,我们通过一个简单例子来解释:

我们先定义一个add函数,

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

在主函数中定义一个ps,用来存放函数地址的指针变量,add前&符号可有可无,都不影响结果。

int main()
{
int(*ps)(int, int) = &add;
    
//ps就是一个存放函数地址的指针变量--函数指针
//&函数名和函数名都是函数的地址
int res = ps(2, 3);
    //int res=(*ps)(2,3);
}

五、函数指针数组

数组是一个存放相同类型数据的存储空间,已经学习了指针数组,例如:

int *arr[10];

//数组的每一个元素是int*

那要把函数的地址存到一个数组中,那这个数组叫函数指针数组,具体定义如下:

int (*par1[10])();

par1先和 [ ]结合,说明par1是数组,数组的内容就是 int (*)( )类型的函数指针

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

具体案例如下:加减法计算器

#include<stdio.h>
#include<iostream>
using namespace std;
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
void menu(){
printf("******************\n");
printf("***1.sub 2.add****\n");
printf("**** 0.excit ****\n");
}

我们选定一个加减函数和一个菜单函数(用来选择+还是减),

再定义一个指针数组用来存上述函数地址

int (*pf[4])(int, int) = {NULL, add, sub};

再通过主函数调用,我们用res = pf[input](x, y)来调用

int main() {
int input = 0;
int x, y, res;
do {
menu();
printf("请选择\n");
std::cin >> input;
if (input == 0) {
cout << "退出" << endl;
}
else if (input >= 1 && input <= 4) {
cin >> x >> y;
res = pf[input](x, y);
cout << res << endl;
}
} while (input);
return 0;
}

六、回调指针

        回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用,用于该事件或条件进行反映

继续用刚才的计算器例子,不过增加了一个calc函数:

void calc(int (*pt)(int, int)) {
int x = 0, y = 0, ret = 0;
cin >> x >> y;
ret = pt(x, y);
cout << ret << endl;
}
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
void menu(){
printf("******************\n");
printf("***1.sub 2.add****\n");

printf("**** 0.excit ****\n");

}

再看主函数,我们直接用calc调用add sub 函数,被调用的就是回调函数,calc就相当于一个中介。

int main() {
int input = 0;
int x, y, res;
do {
menu();
printf("请选择\n");
std::cin >> input;
switch (input)
{
case 1:
calc(add);
break;
case 2:
calc(sub);
break;
case 0:
cout << "推出计算器" << endl;
break;
default:
cout << "选择错误" << endl;
break;
}
} while (!input);
return 0;
}


原文地址:https://blog.csdn.net/2401_83157962/article/details/142741458

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!