n维数组实现(可变参数表的使用)

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

头文件:#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 = -1;
         static const int OK = 1;

        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<1 || 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 = 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) 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;//注意这里的元素的单位大小就是 1, 因为 A.base + off 实际上是 A.base+off*sizeof(ElemType);
    A.constants[dim-1] = L;
    for(int i=dim-2; i>=0; --i)
        A.constants[i] = A.bounds[i+1] * A.constants[i+1];
    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 = 0;
    for(int i=0; i<A.dim; ++i){
        int ind = va_arg(ap, int);
        if(ind<0 || 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, 4, 1, 2, 3, 4);
    for(int i=0; i<1; ++i)
        for(int j=0; j<2; ++j)
            for(int k=0; k<3; ++k)
                for(int n=0; n<4; ++n){
                    int e = i+j+k+n;
                    testArray.Assign(A, e, i, j, k, n);
                }

    for(int i=0; i<1; ++i)
        for(int j=0; j<2; ++j)
            for(int k=0; k<3; ++k)
                for(int n=0; n<4; ++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, 3, 4, 10, 20);//4, 10, 20分别表示六层, 座位行号, 座位列号
    Student s("hjzgg", 23);
    testArrayx.Assign(Ax, s, 1, 2, 3);
    s.name = "lxkdd";
    testArrayx.Value(Ax, s, 1, 2, 3);
    s.outMsg();
    return 0;
}
时间: 2024-10-04 13:44:16

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

指向多维数组的指针变量

问题描述 指向多维数组的指针变量 #include int main() { int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int *p; for(p=a[0];p<a[0]+12;p++) { if((p-a[0])%4==0) printf(" "); printf("%4d",*p); } } 把for(p=a[0];p<a[0]+12;p++)改成for(p=a[0];p<a+3;p++)为什么是正确的

数组中求乘积-JAVA中二维数组的函数运算

问题描述 JAVA中二维数组的函数运算 for(i=0;i<MAX;i++){ for(j=0;j<MAX;j++){ d[i][j]=0; for(k=0;k<MAX;k++) d[i][j]+=a[i][k]*b[k][j]; } } 就是在这个程序中为什么最后的乘积是 for(k=0;k<MAX;k++) d[i][j]+=a[i][k]*b[k][j];

[剑指Offer]5.二维数组中的查找

题目 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路 [算法系列之三十三]杨氏矩阵 代码 /*--------------------------------------- * 日期:2015-07-19 * 作者:SJF0115 * 题目: 5.二维数组中的查找 * 网址:http://www.nowcoder.com/books/coding-interviews/a

c语言中怎么把一个大小不确定的二维数组当作参数传入函数中

问题描述 c语言中怎么把一个大小不确定的二维数组当作参数传入函数中 c语言中怎么把一个大小不确定的二维数组当作参数传入函数中,取大神,取大神,取大神 解决方案 用VC++新建一个程序,默认生成的main函数定义如下 int mian(int argc, char* args[]) 这就是一个例子. 解决方案二: 一个表示长度的参数,一个指向二维数组的指针 解决方案三: fun(args[][],int rows,int cols) 解决方案四: void Func(int array[][10]

VS2013下动态数组二维数组读二进制文件的问题

问题描述 VS2013下动态数组二维数组读二进制文件的问题 int samples_to_read = 7200; uint8_t **caculate_a; int count2,count3; caculate_a = (uint8_t **)malloc(sizeof(uint8_t *)* 3); for (count1 = 0; count1<3; count1++){ //动态数组分配空间 caculate_a[count1] = (uint8_t *)malloc(sizeof(u

for-二维数组输入时自动换行问题?

问题描述 二维数组输入时自动换行问题? #include"stdio.h" main() { int a[3][3],i,j; for(i=0;i<3;i++) { for(j=0;j<3;j++) scanf("%d",&a[i][j]); if(j==2) printf("n"); } ... } 1 2 3 我认为每当我输入3个数的时候,它就会自动的换行,像这样 4 5 6 但当我输入三个数以后,它却不能自动换行,这是怎

Python中的二维数组的操作方法

这篇文章主要介绍了一些Python中的二维数组的操作方法,是Python学习当中的基础知识,需要的朋友可以参考下 需要在程序中使用二维数组,网上找到一种这样的用法: ? 1 2 3 4 5 6 #创建一个宽度为3,高度为4的数组 #[[0,0,0], # [0,0,0], # [0,0,0], # [0,0,0]] myList = [[0] * 3] * 4 但是当操作myList[0][1] = 1时,发现整个第二列都被赋值,变成 ? 1 2 3 4 5 6 7 [[0,1,0],   [0

二维数组作形参该如何实现

问题描述 二维数组作形参该如何实现 假设有个函数A,在这个函数里定义了一个二维数组.再定义一个函数B,并在函数A里调用 函数B,通过B对这个二维数组进行处理(二维数组作形参),然后将结果返回到函数A.要求这个二维数组的长度 由函数A里的变量参数决定.请问诸位高手该如何实现? 解决方案 二维数组作为形参二维数组形参二维数组形参问题 解决方案二: 定义函数B时增加两个维数的参数.

c++-C++ char 类型二维数组出现错误

问题描述 C++ char 类型二维数组出现错误 图片是错误--不知道怎么回事求大神解答-- 解决方案 贴代码,不要贴图.建议贴在codepad.org上,这里给出链接. 解决方案二: #include #include using namespace std; char ** create_table(int rows, int cols){ char **a; a = new char *[rows+rows]; for(int i;i<rows+rows;i++){ a[i]=new ch