常量和所需的头文件
#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. Python全栈工程师之从网页搭建入门到Flask全栈项目实战(5) - Flask中的ORM使用

    1.理解ORM ORM是MTV模型里面的Model模型 ORM(Object Relational Mapping),对象关系映射 举例:学生选课 学生和课程这两个实体,一个学生可以选择多门课程,一个 ...

  2. 开源库libcli的安装与使用

    源码:https://github.com/dparrish/libcli 环境 Ubuntu 20.04.2 LTS 编译libcli 参考:README.md 按照libcli中的 README ...

  3. C# 正则表达式常用的符号和模式解析

    〇.正则表达式的基本语法符号 若只简单匹配固定字符串,则无需任何修饰符,例如:需要匹配字符串 77,则可直接写:new Regex("77"). 下边例举一下常用的符号:(知道下面 ...

  4. 读python代码-学到的python函数-1

    1.with open(data_path,'r') as f: with open()是python用来打开本地文件的,他会在使用完毕后,自动关闭文件,无需手动书写close(). 三种打开模式: ...

  5. Redis 中ZSET数据类型命令使用及对应场景总结

    转载请注明出处: 目录 1.zadd添加元素 2.zrem 从有序集合key中删除元素 3.zscore 返回有序集合key中元素member的分值 4.zincrby 为有序集合key中元素增加分值 ...

  6. [OpenCV实战]22 使用EigenFaces进行人脸重建

    目录 1 背景 1.1 什么是EigenFaces? 1.2 坐标的变化 2 面部重建 2.1 计算新面部图像的PCA权重 2.2 使用EigenFaces进行面部重建 3 参考 在这篇文章中,我们将 ...

  7. [编程基础] Python格式化字符串常量f-string总结

    Python格式化字符串常量f-string总结 本文主要总结在Python中如何使用格式化字符串常量f-string(Formatted string literals).在 Python 程序中, ...

  8. 09.什么是synchronized的重量级锁?

    大家好,我是王有志.关注王有志,一起聊技术,聊游戏,聊在外漂泊的生活. 今天我们继续学习synchronized的升级过程,目前只剩下最后一步了:轻量级锁->重量级锁. 通过今天的内容,希望能帮 ...

  9. 真正“搞”懂HTTP协议07之队头阻塞真的很烦人

    这一篇文章,我们核心要聊的事情就是HTTP的对头阻塞问题,因为HTTP的核心改进其实就是在解决HTTP的队头阻塞.所以,我们会讲的理论多一些,而实践其实很少,要学习的头字段也只有一个,我会在最开始就讲 ...

  10. CTF-MISC比赛技巧总结(一)

    CTF-MISC比赛技巧总结之隐写术 一.第一阶段(观):1.flag藏在文本文件里面,直接ctrl+F就可以查找到:2.flag被字符隔开,在头或尾上,这个时候就只用消除间隔字符就可以了:3.fla ...