【C++】二维数组传参方式

最近刚开始刷剑指offer,刚做到第三题的时候,发现C++二维数组的传参方式和C语言略有些不同,所以在这篇博客中,会列出C/C++常见的二维数组传参方式。(本方式和代码都是基于vs环境所编写)

 一.C语言二维数组传参方式

C语言二维数组传参一般有三个方式。 

1.指针形式接收

#include<stdio.h>void Print1(int* parr, int rows, int cols)//指针,行数,列数
{for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){printf("%2d ", *(parr + i * cols + j));}printf("\n");}printf("\n");
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };Print1(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]) / sizeof(arr[0][0]));return 0;
}

2. 数组形式接收

#include<stdio.h>void Print2(int parr[][5], int rows, int cols)
{for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){printf("%2d ", parr[i][j]);}printf("\n");}printf("\n");
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };Print2(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]) / sizeof(arr[0][0]));return 0;
}

3.数组指针形式接收

void Print3(int(*arr)[5], int rows, int cols)
{for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){printf("%2d ", (*(arr + i))[j]);}printf("\n");}printf("\n");
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };Print3(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]) / sizeof(arr[0][0]));return 0;
}

一般来说,第一种更为常见,更加通用,因为第二、三种方法需要在函数中写明二维数组的列数,而一般情况下是不知道的。

二.C++二维数组传参方式

当我写完C语言二维输出传参方式后,接着用C语言写,发现C语言的第一种写法不适用于C++,会直接报错。

 原因:

在C语言里面,不管是一维数组还是二维数组,通过用数组名的传参方式,传过去后,数组名都会退化成一个指针指向第一个元素的指针。

而在C++的二维数组里面,通过用数组名传参,传过去后数组名会退化成一个一维数组指针,即这个指针是指向一个一维数组的。

如下图所示:

所以C++的函数参数不能像C语言一样去写。 

1. 数组指针形式接收

#include<iostream>
using namespace std;void Print1(int (*parr)[5], int rows, int cols)
{for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){cout << (*(parr + i))[j] << " ";}cout << endl;}cout << endl;
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };Print1(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]) / sizeof(arr[0][0]));return 0;
}

2.指针形式接收

第一种方式参数要指明多少列,如果我们不想这样写可以吗,答案是可以的,我们还是可以像C语言的第一种写法一样去写,但是调用函数时的参数需要做出一些改变。 

传arr改为传arr[0][0]的地址

#include<iostream>
using namespace std;void Print2(int* parr, int rows, int cols)
{for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){cout << *(parr + i * cols + j) << " ";}cout << endl;}cout << endl;
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };//函数第一个参数改为传arr[0][0]的地址Print2(&arr[0][0], sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]) / sizeof(arr[0][0]));return 0;
}

3. 引用方式传参

void Print3(int(&parr)[4][5],int rows,int cols)
{for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){cout << parr[i][j] << " ";}cout << endl;}cout << endl;
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };Print3(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]) / sizeof(arr[0][0]));return 0;
}

这种引用方式传参要指定行和列,所以也不好用,但是好在C++支持模板,所以可以使用模板来优化。

4.引用+模板

template<size_t row, size_t col>
void Print4(int(&parr)[row][col])
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){cout << parr[i][j] << " ";}cout << endl;}cout << endl;
}int main()
{int arr[][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };Print4(arr);return 0;
}

通过使用引用+模板的方式传参,通过使用模板,编译器会自动推导数组的行数和列数。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Reflect.get() 详细介绍,并给出例子说明

Reflect.get() 是 JavaScript 的一个内置方法&#xff0c;它用于获取对象上某个属性的值。这个方法属于 Reflect 对象&#xff0c;它提供了一种方式来执行对象的属性访问操作&#xff0c;与直接使用点&#xff08;.&#xff09;或方括号&#xff08;[]&#xff09;访问属性的方…

CCF区块链论文录用资讯--ICSE 2024

ICSE是CCF A类会议 &#xff08;软件工程/系统软件/程序设计语言&#xff09; 其2024录用了13篇区块链论文 Smart Contract and DeFi Security Tools: Do They Meet the Needs of Practitioners? 智能合约和 DeFi 安全工具&#xff1a;它们满足从业者的需求吗&#xff1f; St…

SegAnyGAussians(SAGA)项目配置和运行

GitHub项目地址&#xff1a;Jumpat/SegAnyGAussians: The official implementation of SAGA (Segment Any 3D GAussians) (github.com) 一、项目准备 1、下载原项目的zip包解压 2、下载third_party目录下的两个模块&#xff0c;放到对应目录下 3、下载预训练模型和数据集 数据…

非计算机专业,如何从事研发岗位的建议!

首先&#xff0c;非计算机专业的毕业生通过读研和专门的培训是完全可以进入IT行业的&#xff0c;目前IT行业内也有大量非计算机专业毕业的技术开发&#xff08;研发&#xff09;人员&#xff0c;其中有不少人也非常优秀&#xff0c;发展空间同样比较大。 虽然IT行业内整体的人才…

Linux hwclock命令教程:管理和操作硬件时钟(附实例详解和注意事项)

Linux modinfo命令介绍 modinfo&#xff08;模块信息&#xff09;命令在Linux系统中用于显示Linux内核模块的信息。此命令从命令行给出的Linux内核模块中提取信息。如果模块名称不是文件名&#xff0c;则默认搜索/lib/modules/kernel-version目录。modinfo可以理解来自任何Lin…

IPFS分布式存储系统

一、 引言 IPFS是InterPlanetary File System的缩写。它是一个分布式的网络传输协议&#xff0c;它可以把文件分成很多小块放到服务器的不同地方&#xff0c;然后用一种特别的方式来寻找和传输这些小块。这样&#xff0c;我们就可以更快、更安全、更抗容错了的存储文件了。 可能…

从小到大输出四个整数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int a, b, c, d;int t 0;//提示用户&#xff1b;printf("请输入四个整数a b c d&…

python怎么判断整数

isinstance()函数 可以用来判断变量的类型&#xff0c;它返回的是一个布尔值&#xff0c;False or True。 >>>isinstance("123",str) >>>Flase >>>isinstance(123,int) >>>True >>>isinstance({123},list) >>&g…

【大数据】分布式文件系统HDFS

目录 1.什么是分布式文件系统 2.HDFS的特点 3.HDFS的核心概念 4.HDFS的体系结构 5.HDFS的配置建议 6.HDFS的局限性 7.HDFS的存储机制 7.1.数据冗余机制 7.2.错误与恢复 8.HDFS数据读写过程 1.什么是分布式文件系统 分布式文件系统是整个大数据技术的基础&#xff0c…

京东AI数字人“采销东哥”首秀观看量破2000万;天工 SkyMusic 音乐大模型开放公测

&#x1f989; AI新闻 &#x1f680; 京东AI数字人“采销东哥”首秀观看量破2000万 摘要&#xff1a;京东AI数字人“采销东哥”由京东云言犀打造&#xff0c;在其直播首秀中亮相并迅速吸引超2000万观看量。尽管“采销东哥”的外形和口音与创始人刘强东相似&#xff0c;但其直…

C语言的OJ判题机设计与实现

1. 接收判题入参 判题需要作答代码、测试输入和期望输出、编译器名称、时空限制。对于支持special judge的还需要传入是否为sj和sj代码。推荐使用消息队列&#xff0c;应对高并发的比赛情况会比较好。 但是消息队列是异步的&#xff0c;我为了快点实现能提交后在当前页面获得判…

Linux: security: sudo 的一个隐藏问题

说这个隐藏是根据一般的知识&#xff0c;肯定是想不到它会读取本机的ip地址和mask。 这个命令在执行的时候会读取本地地址列表。是下面这个commit引进来的一个plugin https://github.com/sudo-project/sudo/commit/1009d7a3e6ed2b7811473c91d90082cfe4dd2db9 /* Load local IP…

量子密钥分发系统的设计与实现(二):光路子系统初步讨论

通过上一篇文章&#xff0c;我们对量子密钥分发系统的基本架构、硬件结构以及密钥分发流程进行了初步的总体介绍&#xff0c;从本文开始&#xff0c;我们就基于系统顶层的架构设计&#xff0c;开始从模块到器件&#xff0c;从硬件到软件开始详细讨论QKD系统的设计与实现。本文主…

双向链表详解

目录 带头双向循环链表带头双向循环链表的实现带头双向循环链表的功能实现创造新节点LTNode* CreateLTNode(LTDataType x)代码 初始化链表LTNode*LTInit(LTNode* phead)代码 打印链表void LTPrint(LTNode* phead)代码 链表尾插void LTPushBack(LTNode* phead, LTDataType x)代码…

C#语法知识之运算符

3、运算符 1、算数运算符 1、赋值符号 //把右侧的值赋给左侧的变量2、算数运算符 _ * / float f 1 / 2f; %3、算数运算符的优先级 //乘除余优先级高于加减 括号可以改变优先级&#xff0c;优先计算括号内的内容4、算数运算符的复合运算 复合运算符是用于自己 自己进行运算…

2024-04-17 学习笔记(李宏毅AI基础课,图像预处理)

1.Hung-yi Lee 摘要&#xff1a;这篇文章介绍了李宏毅教授的课程内容和作业安排&#xff0c;涵盖了深度学习的理论、优化、泛化、特殊网络结构、特殊训练技术、生成对抗网络(GAN)以及深度强化学习等主题。 Raiden说&#xff1a;基础知识&#xff0c;常学常新 2.软包装锂离子电…

源码解读——SplitFed: When Federated Learning Meets Split Learning

源码地址 1. 源码概述 源码里一共包含了5个py文件 单机模型&#xff08;Normal_ResNet_HAM10000.py&#xff09;联邦模型&#xff08;FL_ResNet_HAM10000.py&#xff09;本地模拟的SFLV1&#xff08;SFLV1_ResNet_HAM10000.py&#xff09;网络socket下的SFLV2&#xff08;SF…

51单片机入门_江协科技_33~34_OB记录的自学笔记_LED呼吸灯与PWM直流马达调速

33. 直流电机驱动(PWM) 33.1. 直流电机介绍 •直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 •直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&…

笔记本触摸板的使用

使用电脑很多面年了&#xff0c;但很少使用触摸板&#xff0c;最近公司配置了台新笔记本触摸板很丝滑&#xff0c;像着改变一下多年使用电脑的习惯&#xff0c;做个笔记&#xff0c;使用它&#xff0c;适应它&#xff01; 单手指&#xff1a; 单击→左键 两次单击→打开文件夹&…

MySQL 死锁案例解析一则

原文链接&#xff1a;https://www.modb.pro/db/448666 一、问题背景某业务模块反馈数据库最近出现过几次死锁告警的情况&#xff0c;本文总结了这次死锁排查的全过程&#xff0c;并分析了导致死锁的原因及解决方案。希望给大家提供一个死锁的排查及解决思路。基础环境&#xff…