数据结构与算法 通用二维数组

本文探讨了如何使用一维数组实现存储不同数据类型的通用二维数组。通过详细的手工过程和代码示例,展示了如何计算特定下标元素的位置,以及初始化、销毁、设置和获取元素的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通用二维数组的介绍及分析

首先数组的共性是:
1、连续的存储空间
2、数组元素类型相同(数组元素长度相同)
3、可随即定位(可下标查找)
今天我们设计一个通用的二维数组(用一维数组实现),这个二维数组可以存储不同数据类型的数据,不再受到传统数组数据类型定死的限制!要看代码直接向下滑哦!


INTEGER a(3…10)
上面这条语句是Pascal(一种编程语言)。
由上述语句我们可看到定义数组的真面目,也就是编译系统处理数组的通用原则。只需知道元素类型,开始下标和结束下标就行,因为这些足以计算出数组总空间,从而去申请一段连续的空间。
接下来我想要仿照上面的语句申请一个一维数组并且让它能够实现二维数组的功能!如果掌握了这个方法,不仅仅能够实现二维通用数组,N维都行!当然,前提是你手工过程要好~


手工过程

看下图:

假设有数组定义如下:TYPE ar ( s1…e1 , s2…e2 );且存在 i1 和 i2 在有效下标范围内。求 Loc (ar ( i1, i2 ) ) = Loc (ar) + ? * len 。
这个" ?"显然是在 ar ( i1 , i2 ) 前面的元素个数。想象一个二维数组行数从 s1 到 e1 ,列数从 s2 到 e2 ,此时计算 ar ( i1 , i2 ) 前面的元素个数,我们选用行主序,能得到 " ? " 等于:( i1 - s1 ) * ( e2 - s2 + 1) + ( i2 - s2 )

下图是三维数组公式:

以此类推可以得出及N维数组的(计算给定有效下标的前面元素个数的)公式!

今天我们主要讨论的是二维数组的编写~
( i1 - s1 ) * ( e2 - s2 + 1) + ( i2 - s2 )
注意!上述公式的目的是为了让我们查找数组中指定下标的数据,以及替换指定下标的数据。不是无用的!


开始着手代码编写:
首先需要定义一个二维数组的控制头 ,控制头中包含 ( void **data)(行值) (列值)。void **data 这里定义了一个指针,指针的指类是 void * ,也就是说data指针所指向的空间是一个一维数组,里面存储的是一些四字节指针!而这些指针又指向不同数据类型的数据。我们在这里实现了存储不同数据类型(不同长度)的数据!

了解到这里就上代码八!

matrix.h

#ifndef _MEC_MATRIX_H_
#define _MEC_MATRIX_H_

#include "mec.h"

typedef struct NORMAL_MATRIX {
	void **data;
	int rowCount;
	int colCount;
}NORMAL_MATRIX;

boolean initMatrix(NORMAL_MATRIX **matrix, int rowCount, int colCount);
void destoryMatrix(NORMAL_MATRIX **matrix);
boolean setElementAt(const NORMAL_MATRIX *matrix, 
		const int row, const int col, void *data);
void *getElementAt(const NORMAL_MATRIX *matrix, const int row, const int col);

#endif

matrix.c

#include <stdio.h>
#include <malloc.h>

#include "mec.h"
#include "matrix.h"

boolean initMatrix(NORMAL_MATRIX **matrix, int rowCount, int colCount) {
	if (NULL == matrix || NULL != *matrix || rowCount <= 0 || colCount <= 0) {
		return FALSE;
	}

	*matrix = (NORMAL_MATRIX *) calloc(sizeof(NORMAL_MATRIX), 1);
	(*matrix)->data = (void **) calloc(sizeof(void *), rowCount * colCount);
	(*matrix)->rowCount = rowCount;
	(*matrix)->colCount = colCount;

	return TRUE;
}

void destoryMatrix(NORMAL_MATRIX **matrix) {
	if (NULL == matrix || NULL == *matrix ) {
		return;
	}
	free((*matrix)->data);
	free(*matrix);
	*matrix = NULL;
}

boolean setElementAt(const NORMAL_MATRIX *matrix, 
		const int row, const int col, void *data) {
	if (NULL == matrix 
			|| row < 0 || row >= matrix->rowCount
			|| col < 0 || col >= matrix->colCount
			|| NULL == data) {
		return FALSE;
	}

	matrix->data[row * matrix->colCount + col] = data;

	return TRUE;
}

void *getElementAt(const NORMAL_MATRIX *matrix, const int row, const int col) {
	if (NULL == matrix 
			|| row < 0 || row >= matrix->rowCount
			|| col < 0 || col >= matrix->colCount) {
		return NULL;
	}

	return matrix->data[row * matrix->colCount + col];
}

mec.h中定义了boolean 类型,具体请看上一篇博文最底下~

typedef 行为有点像 #define 宏,用其实际类型替代同义字。不同点是 typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值