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

数组传参很常见,在 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];

	// GP
	cout << "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 array
	cout << "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;

	// struct
	cout << "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 3

2 3 0
1 -2 -1
3 1 1

0 0 0
2 1 3

2 3 0
1 -2 -1
3 1 1

1 2 0
2 1 3

2 3 0
1 -2 0
3 1 0

三、运行结果

GP
A=
1 2 0
2 1 3

B=
2 3 0
1 -2 -1
3 1 1

A*B=
4 -1 -2
14 7 2

flattening the array
A=
0 0 0
2 1 3

B=
2 3 0
1 -2 -1
3 1 1

A*B=
0 0 0
14 7 2

struct
A=
1 2 0
2 1 3

B=
2 3 0
1 -2 0
3 1 0

A*B=
4 -1 0
14 7 0

请按任意键继续. . .




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值