//数组做函数参数退化为指针的技术推演
#include<stdio.h>
#include<stdlib.h>
#include<string.h> //一维数组做函数参数退化为指针的技术推演 void printfA(char * strarr[]);
//计算机中,数组都是线性存储,二维数组元素也是一个个的排列的
//例如: 1,2,3,4,5,6,7,8,9 像这组数据 我们可以认为是一维数组 int a[9]={1,2,3,4,5,6,7,8,9};
//也可以认为是二维数组 int b[3][3]={1,2,3,4,5,6,7,8,9};
//所以计算机并不清楚数组名的步长是多少 就是 a+1移动多少个字节 或者 b+1 移动多少个字节
//这就需要程序员去告诉计算机 数组名的步长是多少
//对于本题 void printfA(char * strarr[3]); 数组做函数参数 该数组是一个一维数组 数组元素类型是 char *
//那么数组strarr的步长应该是 sizeof(char *) 也就是4个字节
//这么来说 我们只需要告诉计算机 你跳4个字节 就OK了
//所以技术推演为printfB
void printfB(char * strarr[]);
//因为计算机根本不关心你有多少个元素 是3个 还是30个 与计算机没关系 是程序员需要关心的(这就是数组越界问题)
//函数参数 char * strarr[] 同样告诉计算机 我是一个一维数组 数组元素是 char * 类型
//那么数组strarr的步长还是 sizeof(char *) 也就是4个字节
//那么我们继续推演 既然计算机只需要确定 该数组每次移动的步长是 4个字节就好
//那么void printfC(char ** strarr);这么写也是可以的 strarr是个指针 strarr里的值指向一个类型是 char *的变量
//步长只与指针的值有关 ,因此strarr的 步长是 sizeof(char *) 也就是4个字节
//所以C语言的开发人员就做了优化 printfC (与我没关系 设计C语言的就是这么优化的)
void printfC(char ** strarr);
//char * strarr[3]做参数退化为char ** strarr) 有2个好处
//好处1:复制一个一维数组char * strarr[3] 比复制一个指针char ** strarr 会耗费更多的内存空间
//char * strarr[3] 需要耗费 sizeof(char *) * 3 =12 个字节的内存空间 ;
//而char ** strarr需要耗费 sizeof(char **) = 4 个字节的内存空间 ;
//节约了内存 和创建 数组时的资源消耗
//好处2:减少了无用解析 ;对于char * strarr[3] 元素个数3 没用,
//这是个一维数组 这个信息没用 ,因为遍历数组的时候从首地址开始遍历, 只要给计算机个首地址就行
//计算机从首地址向后遍历 无需知道他是什么 只需要知道每次的步长是多少就好了 //二维数组做函数参数退化为指针的技术推演
void printfD(int arr[][]);
//对于二维数组,C语言编译器同样需要知道 数组名arr的步长 就是在遍历的时候 每次计算机改移动多少个字节
//那么首先 我们应该确定数组名arr 到底是个什么类型
//数组名 是数组首元素的指针 (我自己的推论) 那么二维数组 可以想象成一维数组 只是这个一维数组的每个元素比较特殊,还是一个一维数组
//那么根据推论 数组名arr的类型是一个一维数组的指针 一维数组是这样定义的 typedef int Myarr[4];
//一维数组指针的类型定义是这样的 typedef int (* PMyarr)[4];
//一维数组指针的变量是这么定义的int (* pmyarr)[4];
//所以数组名arr的类型是 int (* PMyarr)[4]; 因为指针的步长与指针所指向的内存空间相关
//arr指向的是一个typedef int Myarr[4]类型的数组,这个数组有4个元素,每个元素都是int类型
//由此得出arr这个一维数组指针的步长是 sizeof(int)*4 = 16;
//由 一维数组的推演可知 数组元素的个数对C语言编译器并不重要 二位数组的元素可以看作一维数组
//推演出 void printfD(int arr[][4]);
void printfE(int arr[][]);
//又因为 C语言编译器 只需要知道 首地址 和步长 所以 可以用 int (*p)[4] 来代替 int arr[][4]
void printfF(int(*arr)[]); //综合以上分析,导出结论 数组做函数参数退化为指针,指针的类型就是数组名的类型 void main(){
char * strarr[] = { "", "", "" };
int arr[][] = { };
system("pause");
}

C语言 数组做函数参数退化为指针的技术推演的更多相关文章

  1. C语言 数组做函数参数不传数组个数的遍历方法

    //数组做函数参数不传数组个数的遍历方法 #include<stdio.h> #include<stdlib.h> #include<string.h> void ...

  2. 3205: 数组做函数参数--数组元素求和1--C语言

    3205: 数组做函数参数--数组元素求和1--C语言 时间限制: 1 Sec  内存限制: 128 MB提交: 178  解决: 139[提交][状态][讨论版][命题人:smallgyy] 题目描 ...

  3. 3204: 数组做函数参数--排序函数2--C语言

    3204: 数组做函数参数--排序函数2--C语言 时间限制: 1 Sec  内存限制: 128 MB提交: 211  解决: 143[提交][状态][讨论版][命题人:smallgyy] 题目描述 ...

  4. 3203 数组做函数参数----排序函数--C语言版

    3203: 数组做函数参数----排序函数--C语言版 时间限制: 1 Sec  内存限制: 128 MB提交: 253  解决: 151[提交][状态][讨论版][命题人:smallgyy] 题目描 ...

  5. C语言中数组做函数参数的问题

    数组做函数参数,会退化成为一个指针变量.因此在进行数组参数传递的同时,需要传递一个数组长度的参数变量. 数组长度可以通过sizeof(arr)/siezof(arr[0])来得到.关于这个sizeof ...

  6. go语言基础之数组做函数参数是值拷贝

    1.数组做函数参数是值拷贝 示例: package main //必须有个main包 import "fmt" //数组做函数参数,它是值传递 //实参数组的每个元素给形参数组拷贝 ...

  7. 【面试题003】c数组做为参数退化的问题,二维数组中的查找

    [面试题003]c数组做为参数退化的问题,二维数组中的查找  一,c数组做为参数退化的问题 1.c/c++没有记录数组的大小,因此用指针访问数组中的元素的时候,我们要确保没有超过数组的边界, 通过下面 ...

  8. ​C语言数组作为函数参数

    数组可以作为函数的参数使用,进行数据传送. 数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用:另一种是把数组名作为函数的形参和实参使用. 数组元素作函数实参 数组元素就是下标变量, ...

  9. [GO]数组做函数参数

    package main import "fmt" //数组为函数参数,实际上是值传递//实参数据里的每个元素,给形参数组拷贝一份//这里形参的数组其实就是实参的复制品 func ...

随机推荐

  1. Mac平台下启动MySQL到完全终止MySQL----终端八步走

    1.选中Finder的情况下,快捷键进入搜索目录:/usr/local 然后进入mysql目录下: 2.右键 "从这里启动" 打开终端: 3.输入执行:./scripts/mysq ...

  2. android 之 spinner的简单使用

    先看spinner的效果图: 代码: MainActivity package com.mecury.spinnertest; import java.util.ArrayList; import a ...

  3. Android 之 2048 的游戏逻辑分析

    继续学习了极客学院的实战路径课程,讲到了2048游戏的编写过程,我在这里作个总结分享给大家(结果会附源代码和我改写后的代码): 这里主要包括两个方面:1.2048界面的绘制   2.2048算法逻辑的 ...

  4. 邮件群发工具(C#版)

    引言 经常会参与组织一些社区活动,涉及到和不同的人进行交流,微信当然是必须的,同样邮件也是一种不可或缺的方式. 一般群发的邮件不是很友好,如果是一对一的,收到邮件的人是不是会比较重视,而且还有他的名字 ...

  5. Centos7安装配置gitlab

    Centos7安装配置gitlab 这篇文字我会介绍在Centos7上安装gitlab,配置gitlab的smtp,并且创建项目demo. sudo yum install openssh-serve ...

  6. Python 虚拟环境:Virtualenv

    安装sudo yum install python-virtualenv 使用方法 virtualenv [虚拟环境名称] 如,创建**ENV**的虚拟环境 virtualenv ENV 默认情况下, ...

  7. Android调用Web服务

    现在大部分应用程序都把业务逻辑处理,数据调用等功能封装成了服务的形式,应用程序只需要调用这些web服务就好了,在这里就不赘述web服务的优点了.本文总结如何在android中调用Web服务,通过传递基 ...

  8. jQuery无刷新上传之uploadify简单试用

    先简单的侃两句:貌似已经有两个月的时间没有写过文章了,不过仍会像以前那样每天至少有一至两个小时是泡在园子里看各位大神的文章.前些天在研究“ajax无刷新上传”方面的一些插件,用SWFUpload实现了 ...

  9. 设计模式C#实现(一)——模板方法模式

    模板方法模式——在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重写定义算法中的某些步骤. 假如我们有两种咖啡因饮料:茶和咖啡.茶的制作过程为: ...

  10. 网站日志实时分析工具GoAccess使用

    网站日志实时分析工具GoAccess使用 系统环境CentOS release 5.5 (Final) GoAccess是一款开源的网站日志实时分析工具. GoAccess 的工作方式就是读取和解析 ...