(使用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

智能推荐

从零开始搭建Hadoop_创建一个hadoop项目-程序员宅基地

文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目

心脏滴血漏洞HeartBleed CVE-2014-0160深入代码层面的分析_heartbleed代码分析-程序员宅基地

文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析

java读取ofd文档内容_ofd电子文档内容分析工具(分析文档、签章和证书)-程序员宅基地

文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat

基于FPGA的数据采集系统(一)_基于fpga的信息采集-程序员宅基地

文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集

微服务 spring cloud zuul com.netflix.zuul.exception.ZuulException GENERAL-程序员宅基地

文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception

邻接矩阵-建立图-程序员宅基地

文章浏览阅读358次。1.介绍图的相关概念  图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为:  G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图

随便推点

MDT2012部署系列之11 WDS安装与配置-程序员宅基地

文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc

python--xlrd/xlwt/xlutils_xlutils模块可以读xlsx吗-程序员宅基地

文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗

关于新版本selenium定位元素报错:‘WebDriver‘ object has no attribute ‘find_element_by_id‘等问题_unresolved attribute reference 'find_element_by_id-程序员宅基地

文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver

DOM对象转换成jQuery对象转换与子页面获取父页面DOM对象-程序员宅基地

文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象

什么是算法?-程序员宅基地

文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法

【网络安全】网络安全的标准和规范_网络安全标准规范-程序员宅基地

文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范