数组传参很常见,在 C/C++ 中传递数组时,数组名会退化为指针,所以一般都要给出首地址和长度。这是有缺陷的,当我们在写函数时不知道各维大小时该怎么办呢?

下面用矩阵乘法作为例子,给出三种实现方法:GP, flattening the array, struct

其中我认为 flattening the array 这种方法最好,OpenGL 中的 glMaplf 函数用的正是这种方法,它的函数原型如下:

void glMap1f(GLenum target, GLfloat uMin, GLfloat uMax, GLint stride, GLint order, const GLfloat *controlPointsPtr);

参数介绍如下

一、源程序

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;const int MAX_ROW = 10;
const int MAX_COLUMN = 10;template <class T>
struct Matrix {unsigned int row;unsigned int column;T m[MAX_ROW][MAX_COLUMN];Matrix(unsigned int _row, unsigned int _column):row(_row), column(_column) {memset(m, 0, sizeof(m));}
};// GP
template<unsigned int x, unsigned int y, unsigned int z, class T>
void GPMatrixMultiply(T A[x][y], T B[y][z], T C[x][z])
{for (int i = 0; i < x; ++i)  // 有符号数与无符号数的比较,没有给出警告 Why?{for (int j = 0; j < z; ++j){C[i][j] = 0;for (int k = 0; k < y; ++k){C[i][j] += A[i][k] * B[k][j];}}}
}// flattening the array
template<class T>
void FlattenMatrixMultiply(T *p, T *q, T *r, unsigned int x, unsigned int y, unsigned int z)
{for (unsigned int i = 0; i < x; ++i){for (unsigned int j = 0; j < z; ++j){r[i * z + j] = 0;for (unsigned int k = 0; k < y; ++k){r[i * z + j] += p[i * y + k] * q[k * z + j];}}}
}// struct
template <class T>
Matrix<T> StructMatrixMultiply(Matrix<T> A, Matrix<T> B)
{Matrix<T> C(A.row, B.column);for (unsigned int i = 0; i < A.row; ++i){for (unsigned int j = 0; j < B.column; ++j){C.m[i][j] = 0;for (unsigned int k = 0; k < A.column; ++k)   // 待检测A.column == B.row{C.m[i][j] += A.m[i][k] * B.m[k][j];}}}return C;
}#pragma region 定义的输入输出函数template<class T>
istream & operator>>(istream& is, const Matrix<T> &matrix)
{for (unsigned int i = 0; i < matrix.row; ++i){for (unsigned int j = 0; j < matrix.column; ++j){is >> T(matrix.m[i][j]);}}return is;
}template<class T>
ostream & operator<<(ostream& os, const Matrix<T> &matrix)
{for (unsigned int i = 0; i < matrix.row; ++i){for (unsigned int j = 0; j < matrix.column; ++j){os << matrix.m[i][j] << " ";}os << endl;}return os;
}template<unsigned int row, unsigned int column, class T>
void InputMatrix(T matrix[row][column])
{for (int i = 0; i < row; ++i){for (int j = 0; j < column; ++j){cin >> matrix[i][j];}}
}template<unsigned int row, unsigned int column, class T>
void OutputMatrix(T matrix[row][column])
{for (int i = 0; i < row; ++i){for (int j = 0; j < column; ++j){cout << matrix[i][j] << " ";}cout << endl;}
}#pragma endregion 定义的输入输出函数int main(int argc, char **argv)
{freopen("cin.txt", "r", stdin);const unsigned int rowA = 2;const unsigned int columnA = 3;   // columnA必须与rowB相等const unsigned int rowB = 3;const unsigned int columnB = 3;int A[rowA][columnA];int B[rowB][columnB];int C[rowA][columnB];// GPcout << "GP" << endl;InputMatrix<rowA, columnA>(A);InputMatrix<rowB, columnB>(B);cout << "A=" << endl;OutputMatrix<rowA, columnA>(A);cout << endl;cout << "B=" << endl;OutputMatrix<rowB, columnB>(B);cout << endl;GPMatrixMultiply<rowA, columnA, columnB>(A, B, C); // 必须给常量,编译时确定cout << "A*B=" << endl;OutputMatrix<rowA, columnB>(C);cout << endl;// flattening the arraycout << "flattening the array" << endl;InputMatrix<rowA, columnA>(A);InputMatrix<rowB, columnB>(B);cout << "A=" << endl;OutputMatrix<rowA, columnA>(A);cout << endl;cout << "B=" << endl;OutputMatrix<rowB, columnB>(B);cout << endl;FlattenMatrixMultiply(*A, *B, *C, rowA, columnA, columnB);   // 可运行时给出cout << "A*B=" << endl;OutputMatrix<rowA, columnB>(C);cout << endl;// structcout << "struct" << endl;Matrix<int> mA(rowA, columnA);Matrix<int> mB(rowB, columnB);cin >> mA >> mB;cout << "A=\n" << mA << endl;cout << "B=\n" << mB << endl;cout << "A*B=\n" << StructMatrixMultiply(mA, mB) << endl;   return 0;
}

二、测试数据

1 2 0
2 1 32 3 0
1 -2 -1
3 1 10 0 0
2 1 32 3 0
1 -2 -1
3 1 11 2 0
2 1 32 3 0
1 -2 0
3 1 0

三、运行结果

GP
A=
1 2 0
2 1 3B=
2 3 0
1 -2 -1
3 1 1A*B=
4 -1 -2
14 7 2flattening the array
A=
0 0 0
2 1 3B=
2 3 0
1 -2 -1
3 1 1A*B=
0 0 0
14 7 2struct
A=
1 2 0
2 1 3B=
2 3 0
1 -2 0
3 1 0A*B=
4 -1 0
14 7 0请按任意键继续. . .

数组传参的三种方法:泛型;压扁数组;数组结构相关推荐

  1. javascript传值和页面跳转传值(ASP.NET页面传参的三种方法)

    我在csdn上提的问题是        我现在希望从asp.net网页弹出对话框,弹出一些错误信息.警告.提示信息之类的东西,目前准备用javascript实现,所以我希望在调这个对话框的时候,动态传 ...

  2. Vue:路由传参的三种方式

    文章目录 前言 方式一:params 传参(显示参数) 1.声明式 router-link 2.编程式 this.$router.push 方式二:params 传参(不显示参数) 1.声明式 rou ...

  3. 详解vue路由传参的三种方式

    在我们开发vue项目的时候,路由传参几乎是我们必须要用到的,一般出现场景是,当我们点击某个组件的某个按钮时跳转到另一个组件中,并携带参数,便于第二个组件获取数据.下面我就来说说vue路由传参的三种方式 ...

  4. 【vue】vue路由传参的三种方式

    前言 vue 路由传参的使用场景一般都是应用在父路由跳转到子路由时,携带参数跳转.传参方式可划分为 params 传参和 query 传参,而 params 传参又可分为在 url 中显示参数和不显示 ...

  5. react 子传参父_react子父传参有几种方法?

    react子父传参有几种方法?下面本篇文章给大家介绍一下react父子组件传参(值)的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. react父子组件传参(值)的几种方法 一 ...

  6. C语言中调用数组元素的三种方法:下标法、数组名法、指针法

    /*调用数组元素的三种方法:下标法.数组名法.指针法*/ #include<stdio.h> int main() {int a[] = { 1,2,3,4,5 }, i, * p;pri ...

  7. vue路由传参的三种方式/含页面刷新参数丢失解决方案(详细)

    vue路由传参的三种方式以及页面刷新参数丢失问题 一.路由传参的三种方式 1.传参方式一:params传参 2.传参方式二:路由属性配置传参 3.传参方式三:query传参 二.三种传递方式的区别 一 ...

  8. 子组件向父组件传参的几种方法

    子组件向父组件传参的几种方法 在用vue框架写项目的时候,多多少少会遇到子组件向父组件传参的方法.作为一个新手,确实让人头疼,于是便有了这篇小白写的总结,话不多说,开始! 以下方法全部基于这两个父子组 ...

  9. VUE路由跳转传参的七种方法

    vue中每个页面都需要在路由中声明,就是在router/index.js中写 import Vue from 'vue' import Router from 'vue-router' import ...

最新文章

  1. java try catch_异常处理,JAVA中异常处理的介绍
  2. Tabhost嵌套以及Tab中多个Activity跳转的实现
  3. 关于feign调用时,session丢失的解决方案
  4. 电压kV为什么k要小写,原因你知道吗?
  5. python心理学实验程序_心理学实验程序编程(python)
  6. 2.2基本算法之递归和自调用函数_一文学会递归解题
  7. 万物皆可爬系列查看翻页翻到最后是什么
  8. 【CCF】201412-1门禁系统
  9. 【Java】优雅停机时的一点思考
  10. 保持Service不被Kill掉的方法--双Service守护 Android实现双进程守护 2
  11. 连接远程hbase长时间等待问题
  12. 最新android工程目录下armeabi-v7a,armeabi的具体含义,有什么区别
  13. VS 番茄助手添加头注释 以及使用方式
  14. Java生成开发帮助文档 IDEA
  15. Latex三线表格制作及相关问题
  16. (2021系统架构设计师)个人对于软考的一些总结
  17. 《惢客创业日记》2019.02.22(周五) 先僵化,后优化,再固化
  18. 1分钟学会PS背景虚化
  19. Python0基础(上)——期末不挂科
  20. 在win10子系统ubuntu平台下使用jekyll和github pages搭建自己的静态博客网站

热门文章

  1. python代码使用cython进行加密
  2. Linux的ssh学习与配置(SSH的登录)
  3. 分享三个可以在家做的正规兼职工作,看到就是赚到
  4. 浏览器无法显示网页解决方法
  5. android面试!一线互联网移动架构师设计思想解读开源框架!复习指南
  6. 深度!推动“企业上云”光有补贴不够,还要看这5点
  7. mysql物理删除索引_mysql创建索引,mysql索引优化,mysql索引创建删除
  8. 巧用foxmail同步qq邮箱的通讯录
  9. 这样的钓鱼邮件,你会中招吗?
  10. MoveKit:一款功能强大的Cobalt Strike横向渗透套件