热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c语言基础指针数组,【c语言基础必备】指针数组and数组指针

对于指针数组和数组指针,单从字面上似乎很难分清它们是什么,先来看看指针数组和数组指针各自的定义形式。指针数组的定义形式为:(是一个数组)类

对于指针数组和数组指针,单从字面上似乎很难分清它们是什么,先来看看指针数组和数组指针各自的定义形式。

指针数组的定义形式为:(是一个数组)

类型名 * 数组名[ 数组长度]; 如:

int *p[8];

数组指针的定义形式为:(是一个指针)         类型名 (* 指针名)[ 数组长度];

如:

int (*p)[8];

现在来分析上述两种定义形式,通过“int *p[8];”这条定义语句可以定义一个指针数组。因为优先级的关系,所以p 先与[] 结合,说明p 是一个数组,然后再与* 结合说明数组p 的元素是指向整型数据的指针。元素分别为p[0], p[1], p[2], ...,p[7],相当于定义了8 个整型指针变量,用于存放地址单元,在此,p 就是数组元素为指针的数组,本质为数组。如果使用的定义方式为“int (*p)[8];”, p 先与* 号结合,形成一个指针,该指针指向的是有8 个整型元素数组,p 即为指向数组首元素地址的指针,其本质为指针。介绍了指针数组和数组指针的含义,接下来,我们通过下面一段代码来看看指针数组和数组指针如何访问二维数组。(这里使用右左法则,通过变量先看右边,再看左边)

include

void main(int argc,char *argv[])

{

int arr[4][4]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

int (*p1)[4];

int *p2[4];

int i,j,k;

p1=arr;

printf("使用数组指针的方式访问二维数组arr\n");

for(i&#61;0;i<4;i&#43;&#43;)

{

for(j&#61;0;j<4;j&#43;&#43;)

{

printf("arr[%d][%d]&#61;%d\t",i,j,*(*(p1&#43;i)&#43;j));

}

printf("\n");

}

printf("使用指针数组的方式访问二维数组arr\n");

for(k&#61;0;k<4;k&#43;&#43;)

{

p2[k]&#61;arr[k];

}

for(i&#61;0;i<4;i&#43;&#43;)

{

for(j&#61;0;j<4;j&#43;&#43;)

{

printf("arr[%d][%d]&#61;%d\t",i,j,*(p2[i]&#43;j));

}

printf("\n");

}

return;

}

fengpeng&#64;ubuntu:~/workspace/work1$ ./test

使用数组指针的方式访问二维数组arr

arr[0][0]&#61;0

arr[0][1]&#61;1

arr[0][2]&#61;2

arr[0][3]&#61;3

arr[1][0]&#61;4

arr[1][1]&#61;5

arr[1][2]&#61;6

arr[1][3]&#61;7

arr[2][0]&#61;8

arr[2][1]&#61;9

arr[2][2]&#61;10

arr[2][3]&#61;11

arr[3][0]&#61;12

arr[3][1]&#61;13

arr[3][2]&#61;14

arr[3][3]&#61;15

使用指针数组的方式访问二维数组arr

arr[0][0]&#61;0

arr[0][1]&#61;1

arr[0][2]&#61;2

arr[0][3]&#61;3

arr[1][0]&#61;4

arr[1][1]&#61;5

arr[1][2]&#61;6

arr[1][3]&#61;7

arr[2][0]&#61;8

arr[2][1]&#61;9

arr[2][2]&#61;10

arr[2][3]&#61;11

arr[3][0]&#61;12

arr[3][1]&#61;13 arr[3][2]&#61;14

arr[3][3]&#61;15

我们成功地使用数组指针和指针数组的方式访问了二维数组&#xff0c;在分析它们各自的访问方式之前&#xff0c;先通过下图了解二维数组中元素的存放方式。

0818b9ca8b590ca3270a3433284dd417.png

在分析指针数组和数组指针如何访问二维数组中的各个元素之前&#xff0c;我们要明白二维数组每行的起始地址并不是只能用图1-5 中的那种表示方式&#xff0c;还有很多方法可以表示每行的起始地址&#xff0c;如*(arr&#43;i) 和arr&#43;i 等。为了帮助读者更好地记忆&#xff0c;我们通过下面一段代码来学习其他表示二维数组每行起始地址的方式。

#include

void main(int argc,char *argv[])

{

int arr[4][4]&#61;{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

int i;

for(i&#61;0;i<4;i&#43;&#43;)

{

printf("使用arr&#43;i求得二维数组arr第%d行的起始地址为&#xff1a;%d\n",i&#43;1,arr&#43;i);

printf("使用arr[i]求得二维数组arr第%d行的起始地址为&#xff1a;%d\n",i&#43;1,arr[i]);

printf("使用*(arr&#43;i)求得二维数组arr第%d行的起始地址为&#xff1a;%d\n",i&#43;1,(arr&#43;i));

printf("使用&arr[i]求得二维数组arr第%d行的起始地址为&#xff1a;%d\n",i&#43;1,&arr[i]);

printf("\n");

}

return;

}

fengpeng&#64;ubuntu:~/workspace/work1$ ./test

使用arr&#43;i 求得二维数组arr 第1 行的起始地址为:1244996

使用arr[i] 求得二维数组arr 第1 行的起始地址为:1244996

使用*(arr&#43;i) 求得二维数组arr 第1 行的起始地址为:1244996

使用&arr[i] 求得二维数组arr 第1 行的起始地址为:1244996

使用arr&#43;i 求得二维数组arr 第2 行的起始地址为:1245012

使用arr[i] 求得二维数组arr 第2 行的起始地址为:1245012

使用*(arr&#43;i) 求得二维数组arr 第2 行的起始地址为:1245012

使用&arr[i] 求得二维数组arr 第2 行的起始地址为:1245012

使用arr&#43;i 求得二维数组arr 第3 行的起始地址为:1245028

使用arr[i] 求得二维数组arr 第3 行的起始地址为:1245028

使用*(arr&#43;i) 求得二维数组arr 第3 行的起始地址为:1245028

使用&arr[i] 求得二维数组arr 第3 行的起始地址为:1245028

使用arr&#43;i 求得二维数组arr 第4 行的起始地址为:1245044

使用arr[i] 求得二维数组arr 第4 行的起始地址为:1245044

使用*(arr&#43;i) 求得二维数组arr 第4 行的起始地址为:1245044

使用&arr[i] 求得二维数组arr 第4 行的起始地址为:1245044

在上面的代码中&#xff0c;我们使用了4 种方式来获得每行的起始地址&#xff0c;因此行起始地址的表示方式并不唯一&#xff0c;读者在使用的时候可以自行选择。         下面接着讲解数组指针和指针数组是如何访问二维数组的&#xff0c;先看数组指针的访问方式。因为数组指针指向的是一个有4 个整型元素的数组&#xff0c;所以可以把二维数组arr 看成由4 个元素arr[0]&#xff0c;arr[1]&#xff0c; arr[2]&#xff0c;arr[3] 组成&#xff0c;每个元素都是含有4 个整型元素的一维数组&#xff0c;所以当在代码中使用p1&#61;arr 的时候&#xff0c;p1 就指向了二维数组的第一行的首地址。在接下来的访问中&#xff0c;由于p1 指向的类型是int [4]&#xff0c;所以从p1 到p1&#43;1 的变化值为44 个字节&#xff0c;即p1&#43;1&#61;1245012。从前面的运行结果中可以发现&#xff0c;p1&#43;1 刚好指向第二行的起始地址。至于为什么刚好能指向二维数组arr 的第二行的首地址&#xff0c;这个问题将在第4 章进行讲解。通过p1&#43;i 刚好能够取遍每行的起始地址&#xff0c;有了每行的起始地址之后&#xff0c;就可以通过“*(*(p1&#43;i)&#43;j)”来取出二维数组中每行的每一个元素。指针数组的访问方式要更容易一些&#xff0c;因为定义的指针数组p2 由4 个元素p2[0]&#xff0c;p2[1]&#xff0c;p2[2]&#xff0c; p2[3] 组成&#xff0c;每个元素都是一个整型指针&#xff0c;所以只需要在程序中取出每行的起始地址并放到p2 指针数组对应的元素中&#xff0c;就可以访问二维数组arr 中的元素了。所以&#xff0c;在程序中使用指针数组和数组指针的时候&#xff0c;必须对它们有清晰的认识&#xff0c;要知道它们的本质是什么&#xff0c;以及如何使用。



推荐阅读
  • 无论是计算机专业学生还是非计算机专业的学习者,在掌握C语言的过程中可能会遇到诸多挑战,不清楚从何入手。为此,本文系统地梳理了2019年福建省C语言的核心知识点,并结合最新的技术进展进行了详细总结,旨在为初学者提供全面的学习指导。文章不仅涵盖了基础语法和数据结构,还深入探讨了指针、内存管理和算法优化等高级主题,帮助读者快速提升编程能力。 ... [详细]
  • 具备括号和分数功能的高级四则运算计算器
    本研究基于C语言开发了一款支持括号和分数运算的高级四则运算计算器。该计算器通过模拟手算过程,对每个运算符进行优先级标记,并按优先级从高到低依次执行计算。其中,加减运算的优先级最低,为0。此外,该计算器还支持复杂的分数运算,能够处理包含括号的表达式,提高了计算的准确性和灵活性。 ... [详细]
  • 2012年9月12日优酷土豆校园招聘笔试题目解析与备考指南
    2012年9月12日,优酷土豆校园招聘笔试题目解析与备考指南。在选择题部分,有一道题目涉及中国人的血型分布情况,具体为A型30%、B型20%、O型40%、AB型10%。若需确保在随机选取的样本中,至少有一人为B型血的概率不低于90%,则需要选取的最少人数是多少?该问题不仅考察了概率统计的基本知识,还要求考生具备一定的逻辑推理能力。 ... [详细]
  • 在Linux系统中,通过使用`read`和`write`函数可以实现文件的高效复制操作。`open`函数用于打开或创建文件,其返回值为文件描述符,成功时返回一个有效的文件描述符,失败时返回-1。`path`参数指定了要操作的文件路径,而`oflag`参数则定义了文件的打开模式和属性。此外,为了确保数据的完整性和一致性,还需要合理处理文件读取和写入过程中的错误和异常情况。 ... [详细]
  • 在探讨P1923问题时,我们发现手写的快速排序在最后两个测试用例中出现了超时现象,这在意料之中,因为该题目实际上要求的是时间复杂度为O(n)的算法。进一步研究题解后,发现有选手使用STL中的`nth_element`函数成功通过了所有测试点。本文将详细分析这一现象,并提出相应的优化策略。 ... [详细]
  • 深入解析C语言中的动态规划算法:以背包问题为例
    本文深入探讨了C语言中动态规划算法的应用,以经典的背包问题为例进行详细解析。通过实例分析,展示了如何利用动态规划解决复杂优化问题,并提供了高效的代码实现方法。文章不仅涵盖了算法的基本原理,还讨论了其在实际编程中的应用技巧和优化策略,为读者提供了全面的理解和实践指导。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • C语言中类型自动转换的深入解析与应用
    C语言中类型自动转换的深入解析与应用 ... [详细]
  • NOIP2000的单词接龙问题与常见的成语接龙游戏有异曲同工之妙。题目要求在给定的一组单词中,从指定的起始字母开始,构建最长的“单词链”。每个单词在链中最多可出现两次。本文将详细解析该题目的解法,并分享学习过程中的心得体会。 ... [详细]
  • 本文详细介绍了在CodeUp平台中实现大数进制转换的技术方法。具体而言,该问题要求将一个最多包含30位数字的十进制非负整数转换为二进制表示。输入数据包含多行,每行包含一个不超过30位的十进制非负整数。通过高效的算法设计,确保了大数转换的准确性和性能。 ... [详细]
  • 单链表的高效遍历及性能优化策略
    本文探讨了单链表的高效遍历方法及其性能优化策略。在单链表的数据结构中,插入操作的时间复杂度为O(n),而遍历操作的时间复杂度为O(n^2)。通过在 `LinkList.h` 和 `main.cpp` 文件中对单链表进行封装,我们实现了创建和销毁功能的优化,提高了单链表的使用效率。此外,文章还介绍了几种常见的优化技术,如缓存节点指针和批量处理,以进一步提升遍历性能。 ... [详细]
  • 本文探讨了在硬币找零问题中使用枚举法的具体应用。具体而言,题目要求将一定数额的零钱换成5分、2分和1分的硬币,并且每种硬币至少需要使用一枚。研究旨在找出所有可能的换法组合。输入数据为一行,包含一个在8到100之间的整数,表示待换的零钱数额。通过详细的枚举分析,本文提供了高效的解决方案,并验证了其在实际应用中的可行性和有效性。 ... [详细]
  • 在洛谷 P1344 的坏牛奶追踪问题中,第一问要求计算最小割,而第二问则需要找到割边数量最少的最小割。通过为每条边附加一个单位权值,可以在求解最小割时优先选择边数较少的方案,从而同时解决两个问题。这种策略不仅简化了问题的求解过程,还确保了结果的最优性。 ... [详细]
  • C语言中fprintf函数写入文件出现空白问题及解决方法
    C语言中fprintf函数写入文件出现空白问题及解决方法 ... [详细]
  • FastDFS Nginx 扩展模块的源代码解析与技术剖析
    FastDFS Nginx 扩展模块的源代码解析与技术剖析 ... [详细]
author-avatar
mobiledu2502894115
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有