之前的学习数组的文章中,已经知道一维数组作为函数参数的时候,最终会被编译器编译为指针。今天来看看二维数组的情形

文章目录

  • 1 为什么C语言中的数组作为函数参数会退化为指针?
  • 2 二维数组作为函数参数如何退化
    • 2.1 代码案例分析(传递二维数组给函数参数)
  • 3 总结

1 为什么C语言中的数组作为函数参数会退化为指针?

C语言是一种高效的语言:

  1. 当参数传递的时候如果将整个数组都拷贝过来的话,拷贝数组的过程会非常的低效,开销比较大
  2. 如果数组过大,参数位于栈上,很容易导致栈溢出

2 二维数组作为函数参数如何退化

二维数组可以看做是一维数组,该一维数组存的元素是另一个一维数组。

二维数组中第一维的参数可以省略。如下图所示:

  • 下图中是不同的数组类型作为函数参数的时候,会被编译器编译成的样式:

注意区分:指针数组与二维数组退化后的不同形式。

同时我们需要非常注意以下几点:

  • C语言中无法向一个函数传递任意的多维数组(所以说不是所有的数组维度都能作为函数参数)

  • 必须提供除第一维之外的所有维长度

    1. 第一维之外的所有维度信息用于完成指针运算
    2. N维数组的本质是一维数组,元素是N-1维的数组
    3. 对于多维数组的函数参数,第一维的元素个数必须以函数参数的形式传给函数,否则在函数体内无法得到整个函数

2.1 代码案例分析(传递二维数组给函数参数)

  • 代码:35-1.c
#include <stdio.h>void access2d(int a[][3], int row){    int col = sizeof(*a)/sizeof(int);  //int a[][3] ==> int(*a)[3],a是指针,指向类型为int[3]的数组int i=0,j=0;                     //所以sizeof(*a) 的大小是3*4=12;printf("sizeof(a) = %d\n",sizeof(a)); //4printf("sizeof(*a) = %d\n",sizeof(*a)); //12for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ",a[i][j]);}printf("\n");}printf("\n");
}void access3d(int a[][2][3], int n){int i=0,j=0,k=0;printf("sizeof(a) = %d\n",sizeof(a)); //4printf("sizeof(*a) = %d\n",sizeof(*a));//24,int a[][2][3]==>int(*a)[2][3] a指向int[2][3]的数组for(i=0; i<n; i++){for(j=0; j<2; j++){for(k=0; k<3; k++){printf("%d ",a[i][j][k]);}}printf("\n");}printf("\n");
}
int main(){int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};int b[1][2][3] = {0};access2d(a, 3);access3d(b, 1);return 0;
}
  • 编译运行结果为:

3 总结

注意,C语言中只会以值拷贝的方式传递函数参数,所以如果想要修改某一个内存中的内容,就必须向函数传递该内容所在内存的地址。

  • 多维数组作为函数参数的时候,必须传递除了第一维之外的所有维的大小信息。
  • 最终多维数组在函数中被编译器编译为指针。
  • 一定要牢记各个数组类型最终退化为什么样的指针。参考本中的图表

【C语言进阶深度学习记录】三十一 数组作为函数参数时退化为指针相关推荐

  1. 【C语言进阶深度学习记录】十一 C语言中enum,sizeof,typedef分析

    文章目录 1 enum 枚举类型的使用方法 1.1 enum枚举类型的特殊意义 1.2 代码分析:enum的使用 2 sizeof 关键字的用法 2.1 代码案例分析:sizeof的本质 3 type ...

  2. 【C语言进阶深度学习记录】三十八 C/C++语言中的函数声明与函数定义

    文章目录 1 函数的声明和定义 1.1 代码分析 2 总结 1 函数的声明和定义 声明的意义在于告诉编译器程序单元的存在.只是告诉编译器它存在但是不在声明这里定义,有可能在当前文件中的其他地方或者其他 ...

  3. 【C语言进阶深度学习记录】三十五 程序中的堆、栈以及静态存储区(数据区)

    学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 在我之前学习底层的知识的时候,也写过相关的内容.可以对比的学习:[软 ...

  4. 【C语言进阶深度学习记录】二十六 C语言中的字符串与字符数组的详细分析

    之前有一篇文章是学习了字符和字符串的,可以与之结合学习:[C语言进阶深度学习记录]十二 C语言中的:字符和字符串 文章目录 1 字符串的概念 1.1 字符串与字符数组 1.2 字符数组与字符串代码分析 ...

  5. 【C语言进阶深度学习记录】十九 #pragma使用与分析

    文章目录 1 #pragma 概念简介 1.1 #pragma message 的用法 1.2 #pragma once 的用法 1.3 #pragma pack 的用法 1.31 struct占用的 ...

  6. 【C语言进阶深度学习记录】十六 静态库与动态库的创建与使用

    上一篇文章学习了编译的过程,点击链接查看:[C语言进阶深度学习记录]十五 编译过程简介,每一个C源文件编译后将会生成目标文件,那么这些目标文件,还需要链接起来,生成可执行文件. 文章目录 1 链接的意 ...

  7. 【C语言进阶深度学习记录】八 C语言中void的分析

    文章目录 1 void的意义 1.1 不存在void变量 1.2 C标准 1.3 void指针的意义 1.4 通过void* 实现memset函数 2 总结 1 void的意义 void修饰函数的参数 ...

  8. 【C语言进阶深度学习记录】五 C语言中变量的属性

    上一篇文章学习了C语言中的类型转换,点击链接查看:[C语言进阶深度学习记录]四 C语言中的类型转换. 文章目录 1 C语言的变量属性 1.1 auto关键字 1.2 register关键字 1.3 s ...

  9. 【C语言进阶深度学习记录】三十 二维数组与二维指针

    文章目录 1 二维指针(指向指针的指针) 2 二维数组 3 二维数组的类型 3.2 如何动态申请二维数组 4 总结 1 二维指针(指向指针的指针) 指针的本质是变量 指针的指针是保存指针变量的地址.如 ...

最新文章

  1. MQTT消息长度限制
  2. Dubbo 高危反序列化漏洞,存在远程代码执行风险,建议及时升级到2.7.7或更高版本!...
  3. 光复用技术中三种重要技术_传感器在机器人技术研究发展历程中扮演着重要角色...
  4. python 存入数据库bigint_【Python】从0开始写爬虫——把扒到的豆瓣数据存储到数据库...
  5. intelli idea新建无scala class选项解决方案
  6. Python 中的 os 模块常见方法?
  7. mysql grep 提取错误日志_详解grep获取MySQL错误日志信息的方法
  8. 系统滚动条实现的NUD控件Unusable版
  9. 计算机科技英语论文,计算机专业英语(第2版)——科技交流与科技论文写作
  10. 通俗理解TCP握手次数是三次?
  11. 《嵌入式系统Linux内核开发实战指南(ARM平台)》书评
  12. windows2008r2安装笔记
  13. 关于《ADS-B点迹数据质量控制散及基础预警算法和实现流程》
  14. Idea部署dubbo-admin
  15. Android代码实现新年贺卡动画
  16. VB.NET 使用 OleDb 操作 Access 数据库(来自 MSDN)
  17. 微信小程序文字跑马灯效果
  18. 如何让百度搜索到自己的博客?
  19. 电子劳动合同,为企业用工护航
  20. 多小区智慧物业管理系统源码

热门文章

  1. spring学习(45):util名称空间注入
  2. 第三十七期:为什么2019年人工智能算法岗求职竞争如此激烈?
  3. 实例47:python
  4. Linux安装samba的过程,Samba安装全过程
  5. PHP检查微信域名屏蔽接口,微信域名检测API接口,实时查询域名是否被微信拦截...
  6. powerbuilder提示不是下拉窗口_为什么过去状态管理不是问题?
  7. Objective-C学习笔记-使用NSString与NSData读写文件
  8. scp命令:服务器间远程复制代码
  9. 配置HAProxy支持https协议
  10. 基于wordpress搭建网站和基于nodejs自己搭建