【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;
}

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

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

18.读取指定目录下的txt文档时,调用另外一个python文件

1.题目 遍历4K_phone和4K_VR目录下的所有txt文件&#xff0c;并将它们的内容合并到一个名为4k_decoding.txt的文件中。 但是&#xff0c;假设你有一个名为another_script.py的Python文件&#xff0c;你想在合并txt文件之前执行它生成要处理的txt文档。 最后统计完原始的txt文件…

算法与数据结构要点速学——通用 DS/A 流程图

通用 DS/A 流程图 这是一个流程图&#xff0c;可以帮助您确定应该使用哪种数据结构或算法。请注意&#xff0c;此流程图非常笼统&#xff0c;因为不可能涵盖每个场景。 请注意&#xff0c;此流程图仅涵盖 LICC 中教授的方法&#xff0c;因此排除了像 Dijkstra 等更高级的算法。…

eclipse配置SVN和Maven插件

3、 安装SVN插件 使用如下方法安装 Help–Install New Software 注意&#xff1a;目前只能安装1.8.x这个版本的SVN&#xff0c;如果使用高版本的SVN&#xff0c;在安装SVN和maven整合插件的时候就会报错&#xff0c;这应该是插件的bug。 点击Add name: subclipse location…

区块链知识总结——比特币中的密码学原理

比特币中的密码学原理&#xff1a; 比特币的本质&#xff1a;crypto-currency. 比特币用到密码学中的两个功能&#xff1a; 1.哈希函数&#xff08;cryptographic hash function&#xff09; 三个重要性质&#xff1a; &#xff08;1&#xff09;抗碰撞性collison resista…

3 xgboost

目录 1 定义 1.1 模型定义 1.2 损失函数 1.3 化简损失函数 xgboost比赛以及工程利器。目前存在大量有关算法文档。 XGBoost&#xff08;eXtreme Gradient Boosting&#xff09;是一种基于决策树集成的机器学习算法&#xff0c;被广泛应用于分类、回归和排名等任务。XGBoost…

vue快速入门(三十)vue的工程化开发安装配置

步骤很详细&#xff0c;直接上教程 上一篇 新增内容 安装nodejs安装脚手架工具安装vue项目运行项目服务退出项目服务 安装nodejs 没安装的友友可以参考这位大神的博文Node.js下载安装及环境配置教程【超详细】 安装脚手架工具 打开管理员cmd 输入此命令行npm i -g vue/cli …

access多表关联提示:语法错误(操作符丢失)在查询表达式中

在access数据库中执行多表关联时提示了一个错误 select * from Patient a inner join BioMain b on a.BioIDb.BioID inner join BioResult c on b.BioIDc.BioID where len(a.PatientID)>12 and b.AddTime>#2024-04-17 05:53:23# and b.AddTime<#2024-04-17 17:53:23#…

ASP.NET基于Web Mail收发系统设计与开发

摘 要 互联网络技术的不断发展&#xff0c;电子邮件服务已经成为人们基本的信息交互手段&#xff0c;也是网络服务中最早和最基本的服务之一。传统邮件系统大多是基于C/S结构&#xff0c;如Lotus notes、Microsoft Exchange Server等&#xff0c;这些邮件系统占用相对较多的服…

【WEEK8】 【DAY3】【DAY4】总览Spring Boot【中文版】

目录 2024.4.17 Wednesday1.总览1.1.先看个速成课&#xff0c;了解大概1.2.SpringBoot入门1.2.1.什么是Spring1.2.2.Spring是如何简化Java开发的1.2.3.什么是SpringBoot 1.3.第一个Spring Boot项目1.3.1.准备工作1.3.2.创建基础项目说明1.3.2.1.使用官方选配下载 2024.4.18 Thu…

libftdi1学习笔记 5 - SPI Nor Flash

目录 1. 初始化 2. CS控制例子 3. 读ID 3.1 制造商 3.2 容量大小 3.3 设置IO类型 3.3.1 setQSPIWinbond 3.3.2 setQSPIMxic 3.3.3 setQSPIMicrochip 3.3.4 setQSPIMicron 4. 写保护 5. 等待空闲 6. 擦除扇区 7. 页编程 8. 页读 9. 写 10. 读 11. 验证 基于M…

管理能力学习笔记五:识别团队角色,因才施用

识别团队角色&#xff0c;因才施用&#xff0c;需要做到以下三点 扬长避短 管理者要学会问自己员工能把什么做好&#xff0c;而不是想方设法改造他们的短处 。 – 彼得德鲁克 人岗匹配 将合适的人放在合适的位置 人才多样化 团队需要各式各样的人才&#xff0c;才能高效配合…

【Linux】引导过程与服务控制

目录 一、Linux操作系统引导过程 1.linux开机引导过程 2.系统初始化进程 1.init进程 2.进程启动方式 二、运行级别和Systemd单元类型 1.运行级别 2.Systemd 三、启动类故障恢复 1.修复MBR扇区故障 2.修复GRUB引导故障 3.root密码忘记的修改方式 四、系统服务控制 …

初识ansible服务及ansible主机清单配置

目录 1、什么是自动化批量管理 2、自动化工具ansible架构 3、ansible服务专用术语对照表 4、设置主机清单&#xff08;inventory&#xff09; 4.1实验环境准备 4.2配置主机清单 4.2.1分组基本格式 4.2.2指定用户名&#xff0c;密码。端口 4.2.3子组 4.3查看 4.3.1看…

基于SpringBoot+Vue的服装销售商城系统(源码+文档+包运行)

一.系统概述 顺应互联网发展的时代热潮&#xff0c;着力于服装电商&#xff0c;满足消费者的日常需求的同时解决传统服装销售的难题。商家如果还用之前的只有线下卖衣服&#xff0c;已经很落伍了&#xff0c;这样会导致了效率低下。而且&#xff0c;时间一长的话&#xff0c;积…

AIGC算法2:LLM的复读机问题

1. 什么是LLM的复读机问题 字符级别重复&#xff0c;指大模型针对一个字或一个词重复不断的生成例如在电商翻译场景上&#xff0c;会出现“steckdose steckdose steckdose steckdose steckdose steckdose steckdose steckdose…”&#xff1b;语句级别重复&#xff0c;大模型针…

不容错过的 IntelliJ IDEA 插件 Top 10

虽然 IntelliJ IDEA 功能齐全&#xff0c;您仍然可以增添一些个性化的设置。 JetBrains Marketplace 上有着大量实用插件&#xff0c;可以满足您个人或企业的特定需求。 内容库非常庞大&#xff0c;可能会让人眼花缭乱。 在这篇博文中&#xff0c;我们将分享最近和一直以来最受…

(十四)C++自制植物大战僵尸游戏windows平台视频播放实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs VLC库 在Cocos2d-x游戏开发框架中&#xff0c;没有实现windows平台视频播放的功能&#xff0c;需要自定义实现。在本项目中使用vlc库实现windows平台的视频播放功能。 vlc官网&#xff1a;网址 下载完成后&#x…

如何配置Postgres的自动扩展功能以应对数据增长

文章目录 解决方案1. 表空间管理2. 分区表3. 自动扩展配置4. 监控和告警5. 使用外部工具和服务 示例代码示例1&#xff1a;创建表空间示例2&#xff1a;创建分区表示例3&#xff1a;调整配置参数示例4&#xff1a;使用监控和告警工具 总结 在PostgreSQL中&#xff0c;随着数据的…

Spring Boot:Web应用开发之登录与退出的实现

Spring Boot 前言实现登录功能配置拦截器 实现退出功能 前言 登录与退出功能作为 Web 应用中的基础且重要的组成部分&#xff0c;直接关系到用户的安全和隐私保护。通过实现登录与退出功能&#xff0c;可以对用户的身份进行验证和授权&#xff0c;确保只有合法的用户才能访问特…

吃鸡游戏msvcp140.dll丢失的解决方法

msvcp140.dll 是一个与 Microsoft Visual C Redistributable 相关的动态链接库&#xff08;DLL&#xff09;文件&#xff0c;是 Windows 操作系统中众多应用程序正常运行所必需的关键组件之一。以下是对 msvcp140.dll 文件的总体介绍和msvcp140.dll丢失的多个解决方案分享。 *…