常量和所需的头文件
#include<stdio.h>
#include<stdarg.h>
#include<stdlib.h>
#define MAX_ARRAY_DIM 8 //设置数组维数最大为8
#define ElemType int
#define ERROR -1
#define SUCCESS 1
#define OVERFLOW -2
#define UNDERFLOW -3
结构体
typedef struct {
ElemType* base;//数组元素基址,由InitArray分配
int dim;//数组维数
int* bounds;//数组维界基址,由InitArray分配
int* constants;//数组映像函数常量基址,由InitArray分配
}Array;
构造数组A
Array InitArray(Array A, int dim, ...) {
//若维数dim和各维长度合法,则构造相应的数组A
if (dim<1 || dim>MAX_ARRAY_DIM)
{
exit(ERROR);
}
A.dim = dim;
A.bounds = (int*)malloc(dim * sizeof(int));
if (!A.bounds)
{
exit(OVERFLOW);
}
//若各维长度合法,则存入A.bounds,并求出A的元素总数elemtotal
int elemtotal = 1;
va_list ap;
va_start(ap, dim);
for (int i = 0; i < dim; i++)
{
A.bounds[i] = va_arg(ap, int);
if (A.bounds[i] < 0)
{
exit(UNDERFLOW);
}
elemtotal *= A.bounds[i];
}
va_end(ap);
A.base = (ElemType*)malloc(elemtotal * sizeof(ElemType));
if (!A.base)
{
exit(OVERFLOW);
}
//求映像函数的常数ci,并存入A.constants[i-1],i=1,...,dim
A.constants = (int*)malloc(elemtotal * sizeof(ElemType));
if (!A.base)
{
exit(OVERFLOW);
}
A.constants[dim - 1] = 1;//L=1,指针的增减以元素的大小为单位
for (int i = dim - 2; i >= 0; i--)
{
A.constants[i] = A.bounds[i + 1] * A.constants[i + 1];
}
return A;
}
销毁释放数组
Array DestoryArray(Array A) {
if (!A.base)
{
exit(ERROR);
}
free(A.base);
A.base = NULL;
if (!A.bounds)
{
exit(ERROR);
}
free(A.bounds);
A.bounds = NULL;
if (!A.constants)
{
exit(ERROR);
}
free(A.bounds);
A.bounds = NULL;
return A;
}
求出元素在数组中的相对地址
int Locate(Array A, va_list ap, int off) {
//若ap指示的各下标值合法,则求出该元素在A中相对地址off
for (int i = 0; i < A.dim; i++)
{
int ind = va_arg(ap, int);
if (ind < 0 || ind >= A.bounds[i]) {
exit(OVERFLOW);
}
off += A.constants[i] + ind;
}
return off;
}

获取A相应位置值函数

int Value(Array A, ElemType e, ...) {
//A是N维数组,e为元素变量,随后是n个下标值
//若下标不超界,则e赋值为所指定的A的元素值
va_list ap;
int off = 0;
va_start(ap, e);
if ((Locate(A, ap, off)) <= 0)
{
exit(ERROR);
}
e = *(A.base + off);
return e;
}
为A指定位置赋值函数
Array Assign(Array A, ElemType e, ...) {
//A是n维数组,e是元素变量,随后是n个下标值
//若下标不超界,则将e值赋给所指定的A的元素
va_list ap;
int off = 0;
va_start(ap, e);
if (Locate(A, ap, off) <= 0)
{
exit(ERROR);
}
*(A.base + off) = e;
return A;
}
main函数调用
int main(void) {
int off = 0;
Array A = { NULL,0,NULL,NULL };
ElemType arrayB[4][3] = { {1,2,3},{4,5,6},{7,8,9},{10,11,12} };
int dim = 2, bounds = 4, constants = 3, e = 0;
A = InitArray(A, dim, bounds, constants);
for (int i = 0; i < bounds; i++)
{
for (int j = 0; j < constants; j++) {
Assign(A, arrayB[i][j], i, j);
printf("value=%d\n", Value(A, e, i, j));
}
}
printf("A.dim=%d\n", A.dim); A = DestoryArray(A);
printf("A.base=%p\n", A.base);
}

C语言多维数组的实现与操作的更多相关文章

  1. c语言二维数组传递

    c语言二维数组传递,目前我总结三种方法,以及纠正一个不能使用的方法 /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维 ...

  2. [语法]C语言中二维数组做输入参数

    C语言中二维数组做输入参数时, 可以同时指定各维长度, 可以只指定第二维的长度, 不可以只指定第一维的长度, 不可以各维长度都不指定. 一句话总结:要指定至少指定第二维,都不指定是不行的. 具体栗子如 ...

  3. C语言中二维数组如何申请动态分配内存

    C语言中二维数组如何申请动态分配内存: 使用malloc函数,先分配第一维的大小,然后再循环分配每一维的大小 #include <stdio.h> #include <malloc. ...

  4. 对二维数组使用指针进行操作的探索(C语言)

    /* Name: 对二维数组使用指针进行操作的探索 Copyright: Author: lingr7 Date: 01/12/18 11:55 Description: */ #include< ...

  5. 关于c语言二维数组与指针的个人理解及处理办法。

    相信大家在学习C语言时,对一维数组和指针的理解应该是自信的,但是,我在学习过程中,看到网上一些博文,发现即便是参加工作的一些专业编程人员,突然碰到二维数组和指针的问题时,也可能会遇到难以处理的诡异问题 ...

  6. C语言多维数组的地址

    设有整型二维数组a[3][4]如下: 0   1   2   3 4   5   6   7 8   9  10  11  它的定义为:     int a[3][4]={{0,1,2,3},{4,5 ...

  7. C语言 二维数组复制、清零及打印显示

    #include <stdlib.h> #include <stdio.h> #include <string.h> //二维整型数组打印显示 ],int row, ...

  8. C语言二维数组作业

    一.PTA实验作业 题目1:7-3 出生年 1. 本题PTA提交列表 2. 设计思路 1.声明一个函数different()用来计算一个年份的不同数字个数 2.定义y(y是来计算符合要求的年份的量), ...

  9. C语言多维数组的指针传递

    在C语言中为了节省空间,提高运行速度经常使用指针来完成数组的传递. 对于一维数组而言可以直接传递首地址 而对于二维数组必须在传递时声明是二维数组的指针,并且调用时也要经过一些运算 首先是定义形参: 函 ...

  10. Go 语言多维数组

    Go 语言支持多维数组,以下为常用的多维数组声明方式: var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type 以下实例声明了三维的整型数组: ...

随机推荐

  1. re、base64的结合使用爬取豆瓣top250

    一.缘由 对于豆瓣的这个网站,记得使用了不少于三种的爬取和解析方式来进行的.今天的这种解析方式是我使用起来较为顺手,后来就更喜欢使用xpath解析,但是这两种也需要掌握. 二.代码展示 '''爬取豆瓣 ...

  2. Window系统的mysql数据库定时备份

    原文:Window系统的mysql数据库定时备份 - Stars-One的杂货小窝 最近老大提到了数据库备份的功能,由于服务器是window系统的,所以研究了下备份的方案,特此记录 主要是实现每天定时 ...

  3. uniapp 微信小程序-点击图片放大图片

    <view class="pij-cont-imgbox" v-if='item.images.length>0'> <view class="p ...

  4. DPDK编译与演示

    环境 安装dpdk 安装依赖 环境配置 编译 遇到过的问题 dpdk使用 设置hugepage helloworld演示 遇到问题 timer演示 环境 虚拟机系统:ubuntu:1404 安装dpd ...

  5. c++中编码protobuf repeated string

    参考:http://www.cppblog.com/API/archive/2014/12/09/209070.aspx proto文件 addressbook.proto syntax = &quo ...

  6. php的可变变量覆盖漏洞

    题目如下: <?php highlight_file('source.txt'); echo "<br><br>"; $flag = 'xxxxxxx ...

  7. 第二章 --------------------XAML基础

    1.XAML是什么? XAML是扩展标记语言,是为了方便设计人员设计UI界面.具体关于XAML语法的讲解参考其他相关书籍.  XAML每一个标签以<>开头,以</>结尾,作为标 ...

  8. C#开发的线程池和管理器 - 开源研究系列文章

    上次编写了一个小软件,用于练手及自己的一个小工具集合.今天把其中的线程池和管理器的代码抽取出来,写成一个博文,让需要的朋友能够进行学习和应用. 这个线程管理器包括了3个类库和一个应用程序,见下图: 第 ...

  9. Ubuntu 中科大源的使用

    官方网址: https://mirrors.ustc.edu.cn/help/ubuntu.html

  10. 手撕AVL树(C++)

    阅读本文前,请确保您已经了解了二叉搜索树的相关内容(如定义.增删查改的方法以及效率等).否则,建议您先学习二叉搜索树.本文假定您对二叉搜索树有了足够的了解. 效率? 众所周知,在平衡条件下,对二叉搜索 ...