首先先介绍一下可变参数表需要用到的宏:

头文件:#include<cstdarg>

void va_start( va_list arg_ptr, prev_param ); 
type va_arg( va_list arg_ptr, type ); 
void va_end( va_list arg_ptr );

va_list:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明
             va_list类型的一个对象       定义: typedef char *  va_list;
va_start:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和
               va_end使用;
va_arg: 展开成一个表达式的宏,该表达式具有变长参数列表中下一个参数的值和类型。每次调用va_arg都会修改
              用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
va_end:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。
va在这里是variable-argument(可变参数)的意思. 
这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.下面我们写一个简单的可变参数的函数,改函数至少有一个整数参数,第二个参数也是整数,是可选的.函数只是打印这两个参数的值.

/*
C++中好像不区分内部类与嵌套类两个名词。
内部类与嵌套类都是指在类中定义类。
局部类是指在函数中定义类。
(c++不能在函数中定义函数。c++在类中定义的函数也就是成员函数。)
(c++内部类与java内部类最大的区别就是:
c++的内部类对象没有外部类对象的指针,不能访问外部类对象的非静态成员;
java的非静态内部类对象有外部类对象的指针,能访问外部类对象的非静态成员。)
*/
#include<cstdarg>//标准头文件,提供宏va_start, va_arg, 和 va_end
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<cstring>
#define MAX_ARRAY_DIM 8 //假设数组的维数的最大值为8
using namespace std; template <typename ElemType>
class MyArray{
private:
public:
class Array{
public:
ElemType *base;//数组元素的基址
int dim;//数组的维数
int * bounds;//数组维界基址
int * constants; //数组映像函数常量基址
};
static const int ERROR = -;
static const int OK = ; int InitArray(Array &A, int dim, ...);//若维数dim和随后的各维的长度合法,则构造相应的数组A
int DestoryArray(Array &A);//销毁数组A
int Value(Array A, ElemType &e, ...);//A是n为数组,e为元素变量,随后是n个下标值,将下标值对应的元素赋给e
int Assign(Array &A, ElemType e, ...);//将元素e赋给指定的下标值
int Locate(Array A, va_list ap, int &off);//返回指定的下标值对应的偏移地址, 存放在off
}; template <typename ElemType>
int MyArray<ElemType>::InitArray(Array &A, int dim, ...){
if(dim< || dim > MAX_ARRAY_DIM) return MyArray::ERROR;
A.dim = dim;
A.bounds = (int *)malloc(dim * sizeof(int));
if(!A.bounds) return MyArray::ERROR; int elemtotal = ;
va_list ap;
va_start(ap, dim);//获取存放变长参数信息的数组
for(int i=; i<dim; ++i){
A.bounds[i] = va_arg(ap, int);
if(A.bounds[i] < ) return MyArray::ERROR;
elemtotal *= A.bounds[i];
}
va_end(ap);
A.base = (ElemType *)malloc(elemtotal * sizeof(ElemType));
if(!A.base) return MyArray::ERROR;
A.constants = (int *)malloc(dim * sizeof(int));
if(!A.constants) return MyArray::ERROR;
//开始求映像数组
//int L = sizeof(ElemType);//每一个元素的大小
int L = ;//注意这里的元素的单位大小就是 1, 因为 A.base + off 实际上是 A.base+off*sizeof(ElemType);
A.constants[dim-] = L;
for(int i=dim-; i>=; --i)
A.constants[i] = A.bounds[i+] * A.constants[i+];
return MyArray::OK;
} template <typename ElemType>
int MyArray<ElemType>::DestoryArray(Array &A){
if(!A.base) return MyArray::ERROR;
free(A.base);
if(!A.bounds) return MyArray::ERROR;
free(A.bounds);
if(!A.constants) return MyArray::ERROR;
free(A.constants);
}
template <typename ElemType>
int MyArray<ElemType>::Value(Array A, ElemType &e, ...){
va_list ap;
int off;
va_start(ap, e);
if(Locate(A, ap, off)==MyArray::ERROR) return MyArray::ERROR;
e = *(A.base+off);
va_end(ap);
return MyArray::OK;
} template <typename ElemType>
int MyArray<ElemType>::Assign(Array &A, ElemType e, ...){
va_list ap;
int off;
va_start(ap, e);
if(Locate(A, ap, off)==MyArray::ERROR) return MyArray::ERROR;
*(A.base+off) = e;
va_end(ap);
return MyArray::OK;
} template <typename ElemType>
int MyArray<ElemType>::Locate(Array A, va_list ap, int &off){
off = ;
for(int i=; i<A.dim; ++i){
int ind = va_arg(ap, int);
if(ind< || ind >= A.bounds[i]) return MyArray::ERROR;
off += A.constants[i]*ind;
}
return MyArray::OK;
} class Student{
public:
char *name;
int age; Student(){ } Student(char *name, int age){
this->name = name;
this->age = age;
} void outMsg(){
cout<<"姓名: " << name << ", 年龄: " << age;
}
}; int main(){
MyArray<int> testArray;
MyArray<int>::Array A;
testArray.InitArray(A, , , , , );
for(int i=; i<; ++i)
for(int j=; j<; ++j)
for(int k=; k<; ++k)
for(int n=; n<; ++n){
int e = i+j+k+n;
testArray.Assign(A, e, i, j, k, n);
} for(int i=; i<; ++i)
for(int j=; j<; ++j)
for(int k=; k<; ++k)
for(int n=; n<; ++n){
int e;
testArray.Value(A, e, i, j, k, n);
printf("%d\n", e);
} MyArray<Student> testArrayx;
MyArray<Student>::Array Ax;
testArrayx.InitArray(Ax, , , , );//4, 10, 20分别表示六层, 座位行号, 座位列号
Student s("hjzgg", );
testArrayx.Assign(Ax, s, , , );
s.name = "lxkdd";
testArrayx.Value(Ax, s, , , );
s.outMsg();
return ;
}

n维数组实现(可变参数表的使用)的更多相关文章

  1. C语言二维数组超细讲解

    用一维数组处理二维表格,实际是可行的,但是会很复杂,特别是遇到二维表格的输入.处理和输出. 在你绞尽脑汁的时候,二维数组(一维数组的大哥)像电视剧里救美的英雄一样显现在你的面前,初识数组的朋友们还等什 ...

  2. PHP之提取多维数组指定列的方法

    前言:有时候在开发中会遇到这样的问题,我们需要把有规律的多维数组按照纵向(列)取出,有下面的方法可用: 我们将拿下面的数组来处理: $arr = array( '0' => array('id' ...

  3. 地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了

    地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了 四叉树对于区域查询,效率比较高. 原理图

  4. 矩阵或多维数组两种常用实现方法 - python

    在python中,实现多维数组或矩阵,有两种常用方法: 内置列表方法和numpy 科学计算包方法. 下面以创建10*10矩阵或多维数组为例,并初始化为0,程序如下: # Method 1: list ...

  5. PHP 二维数组根据某个字段排序

    二维数组根据某个字段排序有两种办法,一种是通过sort自己写代码,一种是直接用array_multisort排序函数 一. 手写arraysort PHP的一维数组排序函数: sort  对数组的值按 ...

  6. 剑指Offer-【面试题03:二维数组中的查找】

    package com.cxz.question3; /* * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. * 请完成一个函数,输入这样的一个二维数组和 ...

  7. PHP开发笔记:二维数组根据某一项来进行排序

    比如说我们现在有一个二维数组: $arr = array( ‘d' => array(‘id' => 5, ‘name' => 1, ‘age' => 7), ‘b' => ...

  8. 剑指Offer面试题:2.二维数组中的查找

    一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...

  9. PHP多维数组根据其中一个字段的值排序

    平时简单的一维数组或者简单的数组排序这里就不多作介绍,这里主要是针对平时做项目中的可能遇到的情况,根据多维数组中的其中一个排序.用到的php函数是:array_multisort. 思路:获取其中你需 ...

随机推荐

  1. JavaScript对象状态

    有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物. 简单说,它有三个特征: * 状态总数(state)是有限的. * 任一时刻,只处在一种状态之中. ...

  2. compass typography 排版 常用排版方法[Sass和compass学习笔记]

    Bullets 用来定义ul li 相关的样式 no-bullet  关闭 li的默认样式 那个小圆点 no-bullets 作用域ul 调用no-bullet 函数 不过用了reset 后 默认没有 ...

  3. 使用display:table来解决一些问题

    一直有,多栏的需求,当然用table布局,很快就做完了.不怎么喜欢用table,刚开始使用display:table,但是有一条老是不能达到我的效果,那就是有一行不固定宽度的时候,就不知道怎么处理,今 ...

  4. Map的keySet和entrySet

    /*Map集合的两种 取出方式 * 1.keySet() * 2.entrySet() * */ //定义一个学生类 重写了equals.hashcode三个方法,实现了comparable接口并覆盖 ...

  5. 代码-->发呆

    代码,敲着敲着,就发呆了. 其实安安静静敲代码,是一种享受.开着不快不慢的音乐,徜徉在代码的世界里,忘记了时间的存在. 原本备忘录中提醒我13点看书,一小时又一小时的延后,已经不记得自己按了多少次一小 ...

  6. Python操作Mysql数据库时SQL语句的格式问题

    一.概述 近日使用Python对Mysql数据库进行操作,遇到SQL语句死活出问题的情况.由于最初没有将异常打印出来,一直不知道原因.随后,将异常打印出来之后,通过异常信息,对代码进行修改.最终,成功 ...

  7. DBUtils 笔记

    一.DBUtils介绍  apache 什么是dbutils,它的作用 DBUtils是java编程中的数据库操作实用工具,小巧简单实用. DBUtils封装了对JDBC的操作,简化了JDBC操作.可 ...

  8. tab+tab

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 解决Unity5+Vuforia+Network本地联机发布到Android上白屏的问题

    Unity5+Vuforia+Network本地联机,在Android下点击联机,然后识别模型就出现白屏,点击屏幕上相应位置的按钮(已白屏,但点击该看不见的按钮)还是能起作用,如跳转到其他场景正常. ...

  10. Swift库运行崩溃

    报错如下: 解决方法: 退出 Xcode 找到 DerivedData 文件夹 删除 (路径: ~/Library/Developer/Xcode/DerivedData) 删除 com.apple. ...