int array[5] = {1, 2, 3, 4, 5}; // 定义数组
int *intptr = array; // 定义指向数组元素的指针
int (*arrayptr)[5] = &array; // 定义指向数组的指针

上述三条语句分别定义了数组, 指向数组元素的指针和指向数组的指针. 内存情况如图示:

对于指向数组元素的指针很好理解, 但是怎样理解 指向数组的指针呢?

  • 怎样理解指针?
    指针可以认为是一个变量, 该变量标记了一段内存, 这段内存的特点是其中存储了固定类型的数据.
    比如上面的ptr初始时标记了array[0]所在的一段内存单元, 这段内存单元存储的是int类型的数据(因为ptr是int类型的指针). 也可以令 ptr = &array[3] , 这样ptr标记的就是array[3]所占的内存单元, 但是其中存储的仍然必须是int类型.
    考虑结构体的情况:
struct student {char name[10];int age;
};
student Jane = {"Jane', 18};
student *studentptr = Jane;

studetptr初始时标记的是Jane所占的内存空间, 该内存空间存储的数据必须是struct student类型的.
从上面可以看出, 只要有一段内存, 并且这段内存存储的内容具有固定的类型我们就可以定义一个指向它的指针.

  • 数组是一种类型吗?
    所谓类型, 不过是对内存中数据的解释的约定, 我们将Jane所占的前10个字节中的内容解释为字符, 后4个字节解释为整数, 然后我们就约定约定这14个字节的类型是struct student. 数组 不是一种固定的类型, 但是我们可以将 具有5个int元素的数组 认为是一种类型, 这种类型在内存上的特点是连续存储5个整形数据. 我们自然可以位0x1000到0x1004这段内存定义一个指针.

  • 如何解释语句 int (*arrayptr)[5] = &array?
    *arrayptr 表示arrayptr是一个指针;[5] 表示指针指向的对象的类型是具有五个元素的数组;int 表示该数组的元素是int类型的. array 是一个int [5] 类型的数组, 取它的地址初始化arrayptr. 值得注意的是此时数组名array不再表示数组首元素的地址.

  • 如何通过指向数组的指针访问数组的元素?

    • (*arrayptr)[0] == array[0] 首先arrayptr是指向 int [5] 型数组的指针, 那么解引 *arrayptr 得到一个 int [5] 型数组, 然后自然可以通过下标访问数组的元素了.
    • arrayptr[0][0] == array[0] 想弄清楚这个表达式要明白以下几个问题:
      (1) 二维数组实际上就是元素为一维数组的数组
      (2) 二维数组名可以看做指向其第一个元素(一维数组)的指针
      (3) 在内存中2 x 5的二维数组的存储方式是下图所示:

      (4) 一维数组array可以看做一个1 x 5的二维数组
      现在我们将array看作一个只有一个元素的二维数组, 并且该二维数组的元素是 int [5] 类型的, 显然arrayptr指向了该二维数组的第一个元素(相当于二维数组名) 所以我们可以通过下标运算符 arrayptr[0] 获得二维数组的第一个元素(实际上就是array数组), 然后再次利用下标运算符 arrayptr[0][0] 获取array数组的第一个元素. 注意到无法使用 arrayptr[1]是错误的, 因为该二维数组只有一个元素.
      下面的程序展示了指向一维数组的指针:
// 指向一维数组的指针
#include <stdio.h>int main()
{int array[] = {1, 2, 3, 4, 5};int *ptr = array;int (*arrayptr)[5] = &array;// ptr与arrayptr都是指针类型printf("ptr所占字节数: %zu\tarrayptr所占字节数: %zu\n", sizeof(ptr), sizeof(arrayptr));// *ptr是int类型 *arrayptr是int [5]类型printf("*ptr所占字节数: %zu\t*arrayptr所占字节数: %zu\n", sizeof(*ptr), sizeof(*arrayptr));// 使用指向一维数组的指针访问数组元素int sum = 0;int product = 1;for(int i = 0; i < 5; i++) {sum += (*arrayptr)[i];product *= arrayptr[0][i];}printf("一维数组array元素的和是: %d\t乘积是: %d\n", sum, product);int matrix[3][5] = {{1, 2, 3, 4, 5},{6, 7, 8, 9, 10},{11, 12, 13, 14, 15}};// 指向一维数组的指针指向二维数组的元素arrayptr = matrix;      // 相当于arrayptr = &matrix[0]arrayptr[0][0]++;       // 相当于matrix[0][0]++printf("matrix[0][0]: %d\n", matrix[0][0]);(*(arrayptr + 1))[0]++; // 相当于matrix[1][0]++printf("matrix[1][0]: %d\n", matrix[1][0]);arrayptr[2][0]++;       // 相当于matrix[2][0]++printf("matrix[2][0]: %d\n", matrix[2][0]);return 0;
} 

C语言之指向一维数组的指针相关推荐

  1. 一维数组所有元素是否大于_【C语言】- 指向一维数组元素的指针!你今天学习了吗?...

    前面我们已经学习了指针,如果指针存储了某个变量的地址,我们就可以说指针指向这个变量.数组及其数组元素都占有存储空间,都有自己的地址,因此指针变量可以指向整个数组,也可以指向数组元素. 一.用指针指向一 ...

  2. 对C语言 结构数组 指向结构变量的指针 指向结构数组的指针

    一.结构数组的定义 数组的元素可以是结构类型的.结构数组的每一个元素都是具有相同的结构类型的下标结构变量.在实际应用中,经常用结构数组来表示具有相同数据结构的一个群体. 如:一个班的学生的档案,一个车 ...

  3. C语言复习篇之数组与指针

    C语言复习篇之数组与指针 学习了一段时间的嵌入式linux了,学习中有很多的东西需要总结,有经验有教训,我觉得把他写下来会更好,就当做是一种笔记的形式,记录学习中的点点滴滴,不仅仅自己可以经常复习,也 ...

  4. c语言数组与指针的基础知识,C语言学习笔记之数组与指针的关系

    首先,大家先需知道一个关于基类型的概念 基类型:组成一个新类型的基础类型 这句话是什么意思呢?举个例子: int a[3] = {1,2,3}; 上面是由三个int类型的数组成一个新的类型也就是数组, ...

  5. c语言定义指向结构体的指针,C语言入门教程-指向结构体的指针

    指向结构体的指针 在C语言中几乎可以创建指向任何类型的指针,包括用户自定义的类型.创建结构体指针是极常见的.下面是一个例子: typedef struct {char name[21];char ci ...

  6. c语言数组的一维编程,【C语言】转换一维数组

    #include #define MAX_SIZE 20 /* 最大数组个数 */ void TransposeArray(int *arr,int size); int main() { int s ...

  7. 最大值_期末C语言特辑 计算一维数组中最大值

    点击蓝字 关注我们 期末C语言特辑 计算一维数组中最大值 [问题描述]输入10个整型数据,存入数组a中,计算其最大值及其所在元素的下标位置. [输入形式]"%d" [输出形式]&q ...

  8. c语言一维数组教学设计,C语言教学中一维数组教学设计.doc

    C语言教学中一维数组教学设计 C语言教学中一维数组教学设计 [摘 要] 数组是C语言中非常重要的概念,通常学生在初次接触到这一概念时感到很抽象.本文通过生活中常常接触到的超市储物柜与数组进行类比,将数 ...

  9. c++如何打印一维数组首地址_C语言之二维数组和指针的结合

    最近在练习 C 语言计算机二级的程序设计题,碰到了二维数组和指针的结合,当时怎么调试都不对,自己也记不清楚该怎么用了就跑去看书翻资料重新复习.自己纠结的问题是二维数组 int a[3][4]的数组名是 ...

最新文章

  1. opencv机器学习线性回归_全面讲解手推实战机器学习之线性回归
  2. 人物-商界-张茵:张茵
  3. 小D课堂 - 新版本微服务springcloud+Docker教程_5-02 Netflix开源组件断路器
  4. 疫情期间怎么上班?用电脑或手机远程办公很简单
  5. 西门子estop指令_西门子6RA80直流调速器调试步骤和参数设置
  6. 软件设计师 2022年上半年下午题
  7. jks文件转换成ctr,key文件
  8. 使用binlog备份恢复myqsl数据
  9. iOS中Emoji表情的判断
  10. Qt下的国际化方法—翻译文件(.ts .qm文件)的使用
  11. python3.6爬虫库_python3.6 网络爬虫
  12. python基础代码汇总
  13. 此主机不支持“Intel EPT”硬件辅助的 MMU 虚拟化。。
  14. vue-cropper
  15. 如何使用Workless(源码下载)做积分管理?
  16. iMindMap汉化免费下载序列号
  17. Tableau绘制甘特图、瀑布图
  18. 微擎--登录页跳转修改
  19. 2021 Google AdWords认证证书
  20. android查找本地图片数据库,Android 图片数据库那些事儿

热门文章

  1. 文科生学计算机能考研吗,求推荐文科生可以跨考计算机的名校
  2. 后台集成解决方案 avue
  3. Python基础入门:(一)从变量到异常处理 --阿里云天池
  4. 再生龙给分区安装linux,用Clonezilla再生龙备份还原UBUNTU(LINUX)系统分区(可以备份MAC系统分区)...
  5. 云计算如何运用在政府行业--解决方案
  6. 程序员vs计算机教师,薪资大PK!教师VS程序员,你想不到的事实!
  7. linux 开启rsh权限,开启rsh服务
  8. larval 策略模式
  9. 使用v-show v-if 设置元素显示和隐藏
  10. 前端开发者应该知道的 Centos/Dokcer/Nginx/Node/Jenkins 操作( 长文)