数组传参的三种方法:泛型;压扁数组;数组结构
数组传参很常见,在 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请按任意键继续. . .
数组传参的三种方法:泛型;压扁数组;数组结构相关推荐
- javascript传值和页面跳转传值(ASP.NET页面传参的三种方法)
我在csdn上提的问题是 我现在希望从asp.net网页弹出对话框,弹出一些错误信息.警告.提示信息之类的东西,目前准备用javascript实现,所以我希望在调这个对话框的时候,动态传 ...
- Vue:路由传参的三种方式
文章目录 前言 方式一:params 传参(显示参数) 1.声明式 router-link 2.编程式 this.$router.push 方式二:params 传参(不显示参数) 1.声明式 rou ...
- 详解vue路由传参的三种方式
在我们开发vue项目的时候,路由传参几乎是我们必须要用到的,一般出现场景是,当我们点击某个组件的某个按钮时跳转到另一个组件中,并携带参数,便于第二个组件获取数据.下面我就来说说vue路由传参的三种方式 ...
- 【vue】vue路由传参的三种方式
前言 vue 路由传参的使用场景一般都是应用在父路由跳转到子路由时,携带参数跳转.传参方式可划分为 params 传参和 query 传参,而 params 传参又可分为在 url 中显示参数和不显示 ...
- react 子传参父_react子父传参有几种方法?
react子父传参有几种方法?下面本篇文章给大家介绍一下react父子组件传参(值)的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. react父子组件传参(值)的几种方法 一 ...
- C语言中调用数组元素的三种方法:下标法、数组名法、指针法
/*调用数组元素的三种方法:下标法.数组名法.指针法*/ #include<stdio.h> int main() {int a[] = { 1,2,3,4,5 }, i, * p;pri ...
- vue路由传参的三种方式/含页面刷新参数丢失解决方案(详细)
vue路由传参的三种方式以及页面刷新参数丢失问题 一.路由传参的三种方式 1.传参方式一:params传参 2.传参方式二:路由属性配置传参 3.传参方式三:query传参 二.三种传递方式的区别 一 ...
- 子组件向父组件传参的几种方法
子组件向父组件传参的几种方法 在用vue框架写项目的时候,多多少少会遇到子组件向父组件传参的方法.作为一个新手,确实让人头疼,于是便有了这篇小白写的总结,话不多说,开始! 以下方法全部基于这两个父子组 ...
- VUE路由跳转传参的七种方法
vue中每个页面都需要在路由中声明,就是在router/index.js中写 import Vue from 'vue' import Router from 'vue-router' import ...
最新文章
- java try catch_异常处理,JAVA中异常处理的介绍
- Tabhost嵌套以及Tab中多个Activity跳转的实现
- 关于feign调用时,session丢失的解决方案
- 电压kV为什么k要小写,原因你知道吗?
- python心理学实验程序_心理学实验程序编程(python)
- 2.2基本算法之递归和自调用函数_一文学会递归解题
- 万物皆可爬系列查看翻页翻到最后是什么
- 【CCF】201412-1门禁系统
- 【Java】优雅停机时的一点思考
- 保持Service不被Kill掉的方法--双Service守护 Android实现双进程守护 2
- 连接远程hbase长时间等待问题
- 最新android工程目录下armeabi-v7a,armeabi的具体含义,有什么区别
- VS 番茄助手添加头注释 以及使用方式
- Java生成开发帮助文档 IDEA
- Latex三线表格制作及相关问题
- (2021系统架构设计师)个人对于软考的一些总结
- 《惢客创业日记》2019.02.22(周五) 先僵化,后优化,再固化
- 1分钟学会PS背景虚化
- Python0基础(上)——期末不挂科
- 在win10子系统ubuntu平台下使用jekyll和github pages搭建自己的静态博客网站