常量和所需的头文件
#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. JavaScript:对象:如何创建对象?

    JS是面向对象的语言,除开基础数据类型,其他所有的数据类型都是对象,包括函数. 如何去理解对象,什么是对象呢? 举个例子,比如我们将日常生活中见到的猫这种动物,抽象成一个类Cat,这里不去谈类是什么概 ...

  2. docker搭建Elasticsearch、Kibana、Logstash 同步mysql数据到ES

    一.前言 在数据量大的企业级实践中,Elasticsearch显得非常常见,特别是数据表超过千万级后,无论怎么优化,还是有点力不从心!使用中,最首先的问题就是怎么把千万级数据同步到Elasticsea ...

  3. Linux中的infuxdb安装及数据迁移

    一.安装influxdb 1.更新yum源 cat <<EOF | sudo tee /etc/yum.repos.d/influxdb.repo   [influxdb]   baseu ...

  4. spark RPC超时造成任务异常 Attempted to get executor loss reason for executor id 17 at RPC address 192.168.48.172:59070, but got no response. Marking as slave lost.

    日志信息如下 Attempted to get executor loss reason for executor id 17 at RPC address 192.168.48.172:59070, ...

  5. dfs 返回值用bool相对void会快一点

    力扣 剑指 Offer 12. 矩阵中的路径 超时代码 dfs返回值是void,用类内的全局变量flag表示找到或没找到. class Solution { public: bool flag; in ...

  6. 【ASP.NET Core】用配置文件来设置授权角色

    在开始之前,老周先祝各个次元的伙伴们新春快乐.生活愉快.万事如意. 在上一篇水文中,老周介绍了角色授权的一些内容.本篇咱们来聊一个比较实际的问题--把用于授权的角色名称放到外部配置,不要硬编码,以方便 ...

  7. DVWA靶场实战(十)——XSS(DOM)

    DVWA靶场实战(十) 五.XSS(DOM): 1.漏洞原理: XSS全称为Cross Site Scripting,由于和层叠样式表(Cascading Style Sheets,CSS)重名,所以 ...

  8. 如何解决github下载很慢的问题?(已经解决)

    目的是为了解决GitHub致命的下载速度慢的问题 方法 通过码云来导入github,通过码云下载 1.在github上面找到自己想要的项目 这一步略过 2.复制github项目上面的网页链接 3.打开 ...

  9. Typora软件下载与markdown语法的使用

    Typora软件下载与markdown语法的使用 一.Typora下载 1.Typora的简介 Typora是一款轻量级文本编辑器,文本阅读器,是目前最火爆的文本编辑器. Typora中格式,字体,主 ...

  10. python语法进阶这一篇就够了

    前言 前面我们已经学习了Python的基础语法,了解了Python的分支结构,也就是选择结构.循环结构以及函数这些具体的框架,还学习了列表.元组.字典.字符串这些Python中特有的数据结构,还用这些 ...