数组的顺序表示与实现

#include<stdio.h>
#include<stdarg.h>
#include<stdlib.h>//使用变长参数表需要引入此头文件
#define MAX_DIM 8
typedef struct 
{
	int * base;//数组元素基址
	int * bounds;//数组维数基址,bounds[0]=3,bounds[1]=4,bounds[2]=2,表示3页4行2列的数组
	int * constants;//数组映像函数常量基址
	/*constants的含义最开始一直看不懂,其实就是定位用的。
	对于3页4行2列的数组,跨越一页8个元素,一行2个元素,一列1个元素
	这样给定一个下标A[2][3][1],2*8+2*3+1=23,再根据基地址base就可找到A[2][3][1]的地址
	可以看出最后一维肯定是1即constants[dim-1] = 1
	*/
	int dim;//维数
}Array,*PArray;
bool init(PArray array,int dim,...);//初始化,bounds的赋值采用变长参数表
bool locate(PArray array,va_list list,int * off);//根据下标定位,得到off
bool getValue(int * e,PArray array,...);//利用locate获取off,从而得到元素的值
bool assign(int e,PArray array,...);//为数组的元素赋值
int main(void)
{
	Array array;
	int value;
	init(&array,3,3,4,2);//3维数组,3页4行2列
	printf("%d %d %d\n",array.constants[0],array.constants[1],array.constants[2]);
	assign(-8,&array,2,3,1);
	getValue(&value,&array,2,3,1);
	printf("这个元素为%d",value);
	return 0;
}
bool init(PArray array,int dim,...)
{
	int total = 1,i=0;//用于累乘,计算总元素个数
	va_list list;//变长参数表
	if(dim<1 || dim>MAX_DIM)//维数超过范围
		return false;
	array->dim = dim;//初始化维数
	array->bounds = (int *)malloc(sizeof(int)*dim);//为bounds分配空间
	if(NULL == array->bounds)
	{
		printf("分配内存失败\n");
		exit(-1);
	}
	//为bounds赋值
	va_start(list,dim);//从dim后开始读取
	for(i=0;i<dim;++i)
	{
		array->bounds[i] = va_arg(list,int);//从参数表中读取
		total*=array->bounds[i];//计算总个数,用于base的内存分配
	}
	va_end(list);//结束读取参数表
	//为base分配空间
	array->base = (int * )malloc(sizeof(int)*total);
	if(NULL == array->base)
	{
		printf("分配空间失败\n");
		exit(-1);
	}
	//为constants分配空间
	array->constants = (int * )malloc(sizeof(int)*dim);
	if(NULL == array->constants)
	{
		printf("分配空间失败\n");
		exit(-1);
	}
	//赋值
	array->constants[dim-1] = 1;//最后一维 为1
	for(i=dim-2;i>=0;--i)
	{
		array->constants[i] = array->constants[i+1]*array->bounds[i+1];
	}
	return true;
}
bool locate(PArray array,va_list list,int * off)
{
	* off = 0;
	int i,temp;
	for(i=0;i<array->dim;++i)
	{
		temp = va_arg(list,int);
		if(temp<0|| temp>=array->bounds[i])//下标越界
			return false;
		(*off)+=array->constants[i]*temp;//每一维的下标乘每一维的偏移量
	}
	//printf("locate中的off为%d\n",*off);
	return true;
}
bool getValue(int * e,PArray array,...)
{
	va_list list;//参数表
	va_start(list,array);
	int off;
	if(!locate(array,list,&off))//定位失败
		return false;
	*e = *(array->base+off);//取值
	return true;
}
bool assign(int e,PArray array,...)
{
	va_list list;//参数表
	va_start(list,array);
	int off;
	if(!locate(array,list,&off))//定位失败
		return false;
	printf("assign中的off为%d\n",off);
	*(array->base+off)=e;//赋值
	return true;
}

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值