C语言二维数组作为函数参数

2023-11-03

设有整型二维数组a[3][4]如下:
0   1   2   3
4   5   6   7
8   9  10  11 
它的定义为:
    int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}
设数组a的首地址为1000,各下标变量的首地址及其值如图所示。


前面介绍过,C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0]、a[1]、a[2]。每一个一维数组又含有四个元素。



例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。

更多的见: http://c.biancheng.net/cpp/html/79.html


数组及数组元素的地址表示如下:从二维数组的角度来看,a是二维数组名,a代表整个二维数组的首地址,也是二维数组0行的首地址,等于1000。a+1代表第一行的首地址,等于1008。如图:

 

 

int array[3][3];

array的类型既不是int **

更不是(int *a)[4]

而是int [3][3]

只是作为右值时才转换成

int (*a)[4] a是指向一个有4个元素的数组的指针,事实上这个a此时指向a[0],指向数组,就是说a里保存着数组的地址,就是1000

指针数组与数组指针

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

数组指针:a pointer to an array,即指向数组的指针

还要注意的是他们用法的区别,下面举例说明。

int* a[4]     指针数组     

                 表示:数组a中的元素都为int型指针    

                 元素表示:*a[i]   *(a[i])是一样的,因为[]优先级高于*

int (*a)[4]   数组指针     

                 表示:指向数组a的指针

                 元素表示:(*a)[i]  

#include <iostream>

using namespace std;

 

int main()

{

int c[4]={1,2,3,4};

int *a[4]; //指针数组

int (*b)[4]; //数组指针

b=&c;

//将数组c中元素赋给数组a

for(int i=0;i<4;i++)

{

a[i]=&c[i];

}

//输出看下结果

cout<<*a[1]<<endl; //输出2就对

cout<<(*b)[2]<<endl; //输出3就对

return 0;

}

(int *array)[N] 和int **的区别

Int ** p,就是一个指针,这个指针指向了int* 也就是一个整型数组,p是指向了整数数组的指针,p中是整数数组的地址,(int *array)[N] 和int **的区别就在于每行的元素个数固不固定

传递二维数组参数

int func(int **array, int m, int n) {

...

printf("\t%d", *(*array +i*n +j));

...

}

 

int main() {

  int array[3][3] = {

{1,2,3},

{4,5,6},

{7,8,9}

};

...

func(array,3,3);

 ...

}

这样传递二维数组是错的,因为类型不匹配,是因为数组实际类型是int [3][3],在作为右值时可以被转化为int (*)[3],它们都和int **不同,自然不可用。

 

法一 直接使用数组类型:因为数组实际类型是int [3][3]

可以用二维数组名作为实参或者形参,在被调用函数中对形参数组定义时可以指定所有维数的大小,也可以省略第一维的大小说明,如:

 

void Func(int array[3][10]);

 

void Func(int array[][10]);

 

二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的:

 

void Func(int array[][]);

 

因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,如果在形参中不说明列数,则系统无法决定应为多少行多 少列,不能只指定一维而不指定第二维

 

法二.一维数组指针作为形参

void func2(int (*pArray)[10])

{

 

}

 

void func2_1(int (*pArray)[]) //编译通过,无法调用

{

 

}

 

int main()

{

int array[10][10];

func2(array);

}

把array[0] 数组的指针传给了func2 因为array是指向10个元素的数组的指针,(*array)就是array[0],(*array)[0] 就是array[0][0]

 

法三.二维数组引用作为形参

void func3(int (&pArray)[10][10])

{

 

}

 

int main()

{

int array[10][10];

func3(array);

}

以下是一维数组引用的例子

 

#include <iostream>

using namespace std;

void output(int (&a)[5])

{

for(int i = 0; i < 5; i++)

cout<<a[i]<<endl;

}

int main()

{

int a[5]={0};

output(a);

getchar();

return 0;

}

 

法四。二维数组指针作为形参

void func4(int (*pArray)[10][10])

{

 

}

 

int main()

{

int array[10][10];

func4(&array);

 

}

转载于:https://www.cnblogs.com/unflynaomi/p/6516766.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言二维数组作为函数参数 的相关文章

  • 数组和链表的区别

    数组是将元素在内存中连续存放 由于每个元素占用内存相同 可以通过下标迅速访问数组中任何元素 但是如果要在数组中增加一个元素 需要移动大量元素 在内存中空出一个元素的空间 然后将要增加的元素放在其中 同样的道理 如果想删除一个元素 同样需要移

随机推荐

  • 关于request.getinputStream读取一次的问题研究

    public int substract byte src int off int len throws IOException if end start 0 if in null return 1 重点 进行流读取标识 读到末尾 会返回
  • 只有技术人才能看懂的幽默

    面试官 请写出一段体现你水平的代码 我 sudo rm rf 面试官 这体现了你哪方面能力 我 我大学田径队的 1 程序有问题时不要担心 如果所有东西都没问题 你就失业了 2 计算机系的男同学追班里一女同学 结果此女总是躲躲闪闪 男的看没戏
  • swagger3.0访问后台地址

    swagger3 0访问后台地址 最近在学SpringBoot 其中swagger部分 发现后台地址不能访问了 当时导入的坐标为 这个是Gradle坐标 和Maven差不多 compile group io springfox name s
  • 计算机视觉基础7

    语义分割 从像素 pixel level 水平上 理解识别图片的内容 根据语义信息分割 输入 图片 输出 同尺寸的分割标记 每个像素会被识别为一个类别 FCN全卷积网络 所有层都是卷积层 相对位置保持不变 解决降采样后的低分辨率问题 全卷积
  • input类型

    下面通过设置input元素的type属性来演示不同类型的文本框的用法 效果图 当输入不正确的邮箱号 点击提交时 如下图 当输入不正确的网址 点击提交时 如下图 当输入不正确的手机号 点击提交时 如下图 代码如下
  • 不同的人每天工作有什么不同

    Author Skatexg Time 2020 07 17 不同的人每天工作有什么不同 有的人在为完成任务付出劳动 有的人在为有意义的成果付出劳动 为完成任务而付出的劳动是无意义的 只有产生成果的劳动才是有意义的 公司花钱买的是劳动成果
  • UPF learing2:set_level_shifter

    set level shifter 设置level shifter strategy在实现的过程中 level shifter name domain domain name elements list exclude elements l
  • python:10个小孩围成一圈分糖果

    10个小孩围成一圈分糖果 老师顺次分给每个人的糖果数为12 2 8 22 16 4 10 6 14 20 然后按以下规则调整 所有小孩同时把自己的糖果分一半给右边的小孩 糖果数如果变为奇数的人 再向老师补要一块 那多少次调整后 大家的糖果数
  • JavaScript——插入排序、堆排序

    一 插入排序 插入排序是一种简单直观的排序算法 它比冒泡排序 选择排序都更有效率 基本思路 插入排序的工作原理是通过构建有序序列 对于未排序元素 在已排序序列中从后向前扫描 找到对应的位置并插入 插入排序将数组分成 已排序 和 未排序 两部
  • 华为OD机试--路灯覆盖问题

    一条笔直的公路上安装了N个路灯 从位置0开始安装 路灯之间的距离是100m 每个路灯都有自己的照明半径 请计算第一个路灯和最后一个路灯之间 未照明区间的长度和 输入描述 第一行为一个数N 表示灯的个数 1 100000 第二行为N个空格分隔
  • 请问如何用nodejs通过post发送multipart/form-data类型的http请求?

    请问如何用nodejs通过post发送multipart form data类型的http请求 发布于 4 年前 作者 xuhaijinsky2008 24777 次浏览 请问如果用nodejs通过post发送multipart form
  • Selenium成长之路-11简单对象定位之XPATH方法

    XPath是一种在HTML文档中定位元素的语言 因为 HTML 可以看做 XML 的一种实现 所以 selenium 用 户可是使用这种强大语言在 web 应用中定位元素 XPath基于XML的树状结构 提供在数据结构树中找寻节点的能力 X
  • static的用法

    1 static修饰普通变量 static修饰全局变量 1 作用域 改变链接属性 只在本文件有效 即使extern外部声明也不行 其他文件可定义相同名字的变量 2 初始化 只能被初始化一次 如果是整型不初始化就会自动赋值为0 字符型初始化为
  • 【Spring】aop的底层原理

    欢迎来到 边境矢梦 的csdn博文 本文主要梳理 Spring 中的切面编程aop的底层原理和重点注意的地方 我是边境矢梦 一个正在为秋招和算法竞赛做准备的学生 喜欢的朋友可以关注一下 下次更新不迷路 Ps 月亮越亮说明知识点越重要 重要性
  • 群晖nas怎么上传整个文件夹_处理群晖NAS中的烦人@eaDir文件夹

    今天发现NAS文件夹里面有很多 eaDir文件夹 和Mac OS X里的 DS Store类似 很烦人 找了解决方法 0 0 ssh登录群晖 控制面板里面打开SSH 0 1 Windows或者Mac 用 ssh 用户名 NAS IP地址登录
  • 1.进程与线程

    Java多线程文章目录 目录 1 进程与线程 Java程序启动至少会有两个线程启动 2 创建Java线程三种方式 run 与start 区别 第一种 继承Thread类 第二种 实现Runnable接口 两种方式区别 练习项目 第三种 实现
  • 通俗理解条件概率、条件期望、条件方差

    写在前面 求 条件XX 时 对 条件 的理解可以是 把 XX条件 作为新的基本事件空间 总体看待 而忽略除这个条件以外的 类似于用摄像机照相时 一开始是整个画面 当得到 XX条件 的约束后 镜头聚焦 画面缩小至代表那个条件的小空间上 一 条
  • Python-爬虫(期末报告)

    爬取的是房价网的数据 然后进行展示 初学爬虫 和同组的小伙伴 其实一个组就俩人 一起写的 我写的爬取 只用了正则表达式拿到网页源码里我想要的数据 还有个AJAX请求直接抓取相应对象然后拿到其中有用的数据即可 注释没写完 另一个小伙伴拿我爬取
  • Fully Convolutional Adaptation Networks for Semantic Segmentation

    参考 论文解析之 Fully Convolutional Adaptation Networks for Semantic Segmentation 云 社区 腾讯云 论文网址 Fully Convolutional Adaptation
  • C语言二维数组作为函数参数

    设有整型二维数组a 3 4 如下 0 1 2 34 5 6 78 9 10 11 它的定义为 int a 3 4 0 1 2 3 4 5 6 7 8 9 10 11 设数组a的首地址为1000 各下标变量的首地址及其值如图所示 前面介绍过