(使用C语言详解)指针数组、数组指针、函数指针、函数指针的数组、指向函数指针数组的指针_c语言指针数组-程序员宅基地

技术标签: C语言  c语言  数据结构  开发语言  

引言

        在C语言中,指针是一种非常强大且灵活的工具,它可以让我们直接操作内存,处理数据。然而,指针的理解和使用也是C语言学习中的难点。

        本文将深入探讨五种不同的指针类型:指针数组、数组指针、函数指针、函数指针的数组以及指向函数指针数组的指针。通过理解这些指针类型,你可以更深入地理解C语言的底层原理,提高编程效率,为日后的编程工作打下坚实的基础。

一、指针数组

1.概念

        指针数组是一个数组,其元素类型为指针。

2.作用

        在C语言中,指针数组常用于存储和管理多个指针变量。指针数组可以有一维、多维等形式。(本文主要讲解一维指针数组)

3.应用场景

指针数组的应用场景主要有以下几点:
        1. 存储和管理多个指针变量:当我们需要处理多个指针变量时,可以使用指针数组来存储和管理这些指针变量。例如,一个程序可能需要处理多个文件,每个文件都有一个文件指针,我们可以使用一个指针数组来存储这些文件指针。
        2. 用于函数指针数组:函数指针数组是一个包含多个函数指针的数组。每个函数指针都指向一个函数,通过索引访问函数指针数组,可以调用相应的函数。例如,我们可以定义一个函数指针数组,用于存储多个排序算法的函数指针,然后根据需要调用相应的排序函数。
        3. 用于多维数组的行指针或列指针:在处理多维数组时,我们可以使用指针数组来存储每一行或每一列的指针。这样,我们可以通过指针数组的索引来访问多维数组的任意一行或一列。例如,对于一个二维数组,我们可以使用一个指针数组来存储每一行的指针,然后通过索引访问对应的行。
        4. 用于实现字符串数组:在C语言中,字符串是以字符数组的形式存储的,而字符数组的元素类型是字符型指针。因此,我们可以使用指针数组来存储多个字符串,每个字符串的长度可以不同。通过访问指针数组,我们可以获取每个字符串的长度和内容。

4.示例

//数组指针——数组中有10个元素,每个元素都是指针
int *ptrArray[10];

上述代码定义了一个一维指针数组,数组的名称为ptrArray。该数组包含10个元素,每个元素都是指向int类型的指针。

5.应用实验代码举例

以下是是一个使用指针数组的简单项目示例,该项目创建了一个NBA球员信息数组,并使用指针数组来存储每个球员的姓名和得分。

#include <stdio.h>

int main() {
    // 定义球员信息结构体
    struct Players {
        char name[50];
        int points;
    };

    // 定义球员数组
    struct Players players[3] = {
        {"Curry", 37},
        {"Klay", 24},
        {"Wiggins", 14}
    };

    // 定义指针数组
    char* namePtrArray[3] = { players[0].name, players[1].name, players[2].name };
    int* pointsPtrArray[3] = { &players[0].points, &players[1].points, &players[2].points };

    // 使用指针数组访问球员信息
    for (int i = 0; i < 3; i++) {
        printf("name:%s, points:%d\n", namePtrArray[i], *pointsPtrArray[i]);
    }

    return 0;
}

二、数组指针

1.概念

        数组指针:是一种特殊的指针,它指向数组的首元素。

2.作用

        数组指针可以用来存储数组的地址,并通过指针进行索引来访问数组中的元素。在C语言中,数组指针常用于处理多维数组。

3.应用场景

        1. 处理多维数组:数组指针常用于处理多维数组,例如二维数组、三维数组等。通过数组指针,可以简化数组元素的访问,提高代码的可读性和可维护性。
        2. 数组排序:数组指针可以用于数组排序,例如冒泡排序、快速排序等。通过使用数组指针,可以避免在排序过程中对数组元素进行多次解引用操作,提高排序算法的效率。
        3. 数组查找:数组指针可以用于数组查找,例如二分查找等。通过使用数组指针,可以快速定位数组中的目标元素,提高查找算法的效率。
        4. 数组切片:数组指针可以用于数组切片,例如取出数组中的某一部分元素构成一个新的数组。通过使用数组指针,可以避免对原数组进行多次复制操作,提高代码的效率。
        5. 数组拼接:数组指针可以用于数组拼接,例如将两个数组首尾相连构成一个新的数组。通过使用数组指针,可以避免对原数组进行多次复制操作,提高代码的效率。

4.示例

//数组指针-pa指向的数组是10个元素
int* (*pa)[10] = &arr;

以上代码定义了一个指向指针的指针pa,pa指向一个包含10个整型指针的数组。

(*pa)是一个指针,指向的是包含10个元素的数组Arr。

(*pa)指向Arr的类型是int*,因为数组Arr[10]的数据类型为int*。

三、函数指针

1.概念

        函数指针是C语言中的一种特殊类型的指针,它指向函数。

2.作用

        函数指针可以存储函数的地址,通过函数指针可以调用函数。

3.应用场景

        1. 函数表:函数指针可以用于实现函数表,函数表是一种存储多个函数地址的数据结构。通过函数表可以实现对多个函数的调用。这在需要根据不同的条件或参数来选择不同的函数时非常有用。
        2. 回调函数:函数指针可以用于实现回调函数,回调函数是一种在某个时间点自动调用的函数。通过函数指针可以实现定时调用函数,这在需要周期性执行某个任务时非常有用。
        3. 传递函数:函数指针可以用于将函数作为参数传递给其他函数。这在需要根据不同的条件或参数来选择不同的函数时非常有用。
        4. 函数指针数组:函数指针可以用于创建函数指针数组,这样可以在数组中存储多个函数指针。这在需要根据不同的条件或参数来选择不同的函数时非常有用。
 

4.示例

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

int main() {
	//函数指针
    //pAdd存放函数地址的指针
	int(*pAdd)(int, int) = Add;
	int sum = (*pAdd)(11, 30);
	printf("sum =%d\n", sum); 

	return 0;
}

四、函数指针的数组(拓展)

1.概念

        函数指针的数组是C语言中一种非常有用的数据结构,本质是一个数组,它允许你存储多个函数指针,并且可以通过索引来调用这些函数。

2.作用

        存储和管理多个函数指针,使得程序能够在运行时根据需要调用不同的函数。它提供了一种灵活的方式来组织和调用多个函数,特别是在需要根据不同的条件或输入来选择执行不同函数的场景中非常有用。

3.应用场景

        1. 操作系统中的系统调用处理:操作系统需要处理各种不同的系统调用,例如进程创建、进程终止、文件操作等。函数指针数组可以用于存储这些系统调用的处理函数,使得操作系统可以根据系统调用的类型调用相应的处理函数。
        2. 事件处理:在某些程序中,例如图形用户界面(GUI)程序或游戏程序,程序需要处理各种事件,例如鼠标点击、键盘输入等。函数指针数组可以用于存储这些事件的处理函数,使得程序可以根据事件类型调用相应的处理函数。
        3. 软件工程中的模块化设计:函数指针数组可以用于存储一个模块中的所有函数,使得其他模块可以通过函数指针数组来调用该模块中的函数。这种设计方式可以使得程序结构更加清晰,方便程序的维护和扩展。

4.示例

以下代码,    

        pArr首先与方块[]结合,说明是5个元素的数组,去掉pArr[5],

        剩下的是每个元素的类型,每个元素的类型是指针指向一个函数,

        函数的参数是(int,int),返回类型是int

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

int main() {
	//函数指针
	int(*pAdd)(int, int) = Add;//&Add
	//函数指针的数组
	int (*pArr[5])(int, int);

	return 0;
}

5.应用实验代码举例

以下代码,func_array 是一个函数指针数组,它包含了两个函数指针。这些指针分别指向 func1 和 func2 函数。在 main 函数中,我们通过索引 0 和 1 来调用这些函数。

#include <stdio.h>

// 定义一个函数指针类型
typedef void (*func_ptr)(void);

// 一个包含两个函数的数组
func_ptr func_array[] = {func1, func2};

// 数组中函数指针所指向的函数
void func1() {
    printf("Function 1 is called.\n");
}

void func2() {
    printf("Function 2 is called.\n");
}

int main() {
    // 通过索引调用数组中的函数
    func_array[0]();

    // 再次调用另一个函数
    func_array[1]();

    return 0;
}

五、指向函数指针数组的指针(拓展)

1.概念

        指向函数指针数组的指针 本质是一个指针,它指向一个函数指针数组。

2.作用

        可以用来访问和操作函数指针数组中的元素。例如可以通过解引用来获取数组中的元素,或者通过递增或递减指针来遍历数组。

3.应用场景

        指向函数指针数组的指针在C语言中应用场景较少,我们更倾向于直接操作函数指针数组。
        1. 动态分配函数指针数组:当函数指针数组的大小需要在运行时动态确定时,可以使用指向函数指针数组的指针来动态分配内存。例如,可以使用`malloc`或`calloc`函数来分配一个适当大小的函数指针数组,并将其地址赋给指向函数指针数组的指针。
        2. 获取函数指针数组的大小:通过指向函数指针数组的指针,可以获取函数指针数组的大小。这可以通过递减指针并检查数组元素的值来实现,直到找到一个`NULL`值。
        3. 遍历函数指针数组:指向函数指针数组的指针可以用来遍历函数指针数组中的元素。这可以通过递增或递减指针来实现,从而调用数组中的每个函数。
        4. 模块化编程:在大型项目中,可能需要将不同的功能模块分配给不同的团队开发。使用指向函数指针数组的指针可以方便地将不同的功能模块集成到主程序中。通过调用不同的函数指针数组元素,可以实现对各个功能模块的调用。

4.示例

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

int main() {
	//函数指针
	int(*pAdd)(int, int) = Add;//&Add
	//函数指针的数组
	int (*pArr[5])(int, int);
    //指向函数指针数组的指针——基于函数指针的数组去写
	int (*(*ppArr)[5])(int, int)=&pArr;
	return 0;
}

        

六、总结

        本文主要讲解了C语言中的五种指针类型:指针数组、数组指针、函数指针、函数指针的数组以及指向函数指针数组的指针。这些指针类型在C语言编程中有着广泛的应用,掌握它们对于深入理解C语言以及进行高效的C语言编程都具有重要意义。

  1. 指针数组是一种数组,其元素为指针;
  2. 数组指针则是一个指向数组的指针,它可以指向数组的首地址,也可以指向数组的任一元素。
  3. 函数指针则是指向函数的指针,通过它我们可以调用函数。
  4. 函数指针的数组则是一个数组,其元素为函数指针;
  5. 指向函数指针数组的指针则是一个指针,它指向函数指针数组。

总的来说,掌握这五种指针类型,可以帮助我们更好地理解C语言的底层原理,提高我们的编程效率,同时也可以为我们在日后的编程工作中遇到的一些复杂问题提供有效的解决方案。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Prayer41/article/details/135063840

智能推荐

874计算机科学基础综合,2018年四川大学874计算机科学专业基础综合之计算机操作系统考研仿真模拟五套题...-程序员宅基地

文章浏览阅读1.1k次。一、选择题1. 串行接口是指( )。A. 接口与系统总线之间串行传送,接口与I/0设备之间串行传送B. 接口与系统总线之间串行传送,接口与1/0设备之间并行传送C. 接口与系统总线之间并行传送,接口与I/0设备之间串行传送D. 接口与系统总线之间并行传送,接口与I/0设备之间并行传送【答案】C2. 最容易造成很多小碎片的可变分区分配算法是( )。A. 首次适应算法B. 最佳适应算法..._874 计算机科学专业基础综合题型

XShell连接失败:Could not connect to '192.168.191.128' (port 22): Connection failed._could not connect to '192.168.17.128' (port 22): c-程序员宅基地

文章浏览阅读9.7k次,点赞5次,收藏15次。连接xshell失败,报错如下图,怎么解决呢。1、通过ps -e|grep ssh命令判断是否安装ssh服务2、如果只有客户端安装了,服务器没有安装,则需要安装ssh服务器,命令:apt-get install openssh-server3、安装成功之后,启动ssh服务,命令:/etc/init.d/ssh start4、通过ps -e|grep ssh命令再次判断是否正确启动..._could not connect to '192.168.17.128' (port 22): connection failed.

杰理之KeyPage【篇】_杰理 空白芯片 烧入key文件-程序员宅基地

文章浏览阅读209次。00000000_杰理 空白芯片 烧入key文件

一文读懂ChatGPT,满足你对chatGPT的好奇心_引发对chatgpt兴趣的表述-程序员宅基地

文章浏览阅读475次。2023年初,“ChatGPT”一词在社交媒体上引起了热议,人们纷纷探讨它的本质和对社会的影响。就连央视新闻也对此进行了报道。作为新传专业的前沿人士,我们当然不能忽视这一热点。本文将全面解析ChatGPT,打开“技术黑箱”,探讨它对新闻与传播领域的影响。_引发对chatgpt兴趣的表述

中文字符频率统计python_用Python数据分析方法进行汉字声调频率统计分析-程序员宅基地

文章浏览阅读259次。用Python数据分析方法进行汉字声调频率统计分析木合塔尔·沙地克;布合力齐姑丽·瓦斯力【期刊名称】《电脑知识与技术》【年(卷),期】2017(013)035【摘要】该文首先用Python程序,自动获取基本汉字字符集中的所有汉字,然后用汉字拼音转换工具pypinyin把所有汉字转换成拼音,最后根据所有汉字的拼音声调,统计并可视化拼音声调的占比.【总页数】2页(13-14)【关键词】数据分析;数据可..._汉字声调频率统计

linux输出信息调试信息重定向-程序员宅基地

文章浏览阅读64次。最近在做一个android系统移植的项目,所使用的开发板com1是调试串口,就是说会有uboot和kernel的调试信息打印在com1上(ttySAC0)。因为后期要使用ttySAC0作为上层应用通信串口,所以要把所有的调试信息都给去掉。参考网上的几篇文章,自己做了如下修改,终于把调试信息重定向到ttySAC1上了,在这做下记录。参考文章有:http://blog.csdn.net/longt..._嵌入式rootfs 输出重定向到/dev/console

随便推点

uniapp 引入iconfont图标库彩色symbol教程_uniapp symbol图标-程序员宅基地

文章浏览阅读1.2k次,点赞4次,收藏12次。1,先去iconfont登录,然后选择图标加入购物车 2,点击又上角车车添加进入项目我的项目中就会出现选择的图标 3,点击下载至本地,然后解压文件夹,然后切换到uniapp打开终端运行注:要保证自己电脑有安装node(没有安装node可以去官网下载Node.js 中文网)npm i -g iconfont-tools(mac用户失败的话在前面加个sudo,password就是自己的开机密码吧)4,终端切换到上面解压的文件夹里面,运行iconfont-tools 这些可以默认也可以自己命名(我是自己命名的_uniapp symbol图标

C、C++ 对于char*和char[]的理解_c++ char*-程序员宅基地

文章浏览阅读1.2w次,点赞25次,收藏192次。char*和char[]都是指针,指向第一个字符所在的地址,但char*是常量的指针,char[]是指针的常量_c++ char*

Sublime Text2 使用教程-程序员宅基地

文章浏览阅读930次。代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大、灵活的编辑器,相信你和我一样,都不会例外。我用过的编辑器不少,真不少~ 但却没有哪款让我特别心仪的,直到我遇到了 Sublime Text 2 !如果说“神器”是我能给予一款软件最高的评价,那么我很乐意为它封上这么一个称号。它小巧绿色且速度非

对10个整数进行按照从小到大的顺序排序用选择法和冒泡排序_对十个数进行大小排序java-程序员宅基地

文章浏览阅读4.1k次。一、选择法这是每一个数出来跟后面所有的进行比较。2.冒泡排序法,是两个相邻的进行对比。_对十个数进行大小排序java

物联网开发笔记——使用网络调试助手连接阿里云物联网平台(基于MQTT协议)_网络调试助手连接阿里云连不上-程序员宅基地

文章浏览阅读2.9k次。物联网开发笔记——使用网络调试助手连接阿里云物联网平台(基于MQTT协议)其实作者本意是使用4G模块来实现与阿里云物联网平台的连接过程,但是由于自己用的4G模块自身的限制,使得阿里云连接总是无法建立,已经联系客服返厂检修了,于是我在此使用网络调试助手来演示如何与阿里云物联网平台建立连接。一.准备工作1.MQTT协议说明文档(3.1.1版本)2.网络调试助手(可使用域名与服务器建立连接)PS:与阿里云建立连解释,最好使用域名来完成连接过程,而不是使用IP号。这里我跟阿里云的售后工程师咨询过,表示对应_网络调试助手连接阿里云连不上

<<<零基础C++速成>>>_无c语言基础c++期末速成-程序员宅基地

文章浏览阅读544次,点赞5次,收藏6次。运算符与表达式任何高级程序设计语言中,表达式都是最基本的组成部分,可以说C++中的大部分语句都是由表达式构成的。_无c语言基础c++期末速成