ADT-Array

核心知识点:

多参数函数的使用

使用标准库<cstdarg>中重要的宏定义实现函数的参数可变

Status fun(Type ele, Type e, . . .)

{

va_list(ap);//首先声明va_list类型的变量

va_start(ap,e);//然后调用va_start传入两个参数,第一个是事先定义的va_list变量,第二个是函数参数里的一个形参变量、注意:第二个参数不能是引用类型

va_arg(ap, Type);//两个参数,返回Type类型的形参列表里e的下一个参数

va_end(ap); //结束时由va_list调用,形参不一定读完

}

存在不足:两个不确定的类型转换会出现不确定的情况等

参考:https://baike.baidu.com/item/stdarg/10282385?fr=aladdin

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdarg>
  4 
  5 using namespace std;
  6 
  7 #define MAX_ARRAY_DIM 8//数组的最大维数为8
  8 
  9 template<class T>
 10 struct array_struct{
 11     T *base;
 12     int dim;//维数
 13     int *bounds;//数组维界基址
 14     int *constants;//用于计算偏移量
 15 };
 16 
 17 template<class T>
 18 class Array
 19 {
 20 public:
 21     Array(){}
 22     Array(int dim, ...);//初始化,为base、bounds、constants数组申请空间
 23     ~Array() {  }
 24     void DestoryArray();
 25     void Locate(va_list ap, int &off);//辅佐函数,计算(i,j,k,,,)单元的偏移量off
 26     void ValueOf(T &e,int temp, ...);//得到(i,j,k,,,)的值
 27     void Assign(T e, ...);//赋值e到(i,j,k,,,)单元
 28     void Show();//二维打印
 29 private:
 30     array_struct<T> A;
 31 };
 32 
 33 int main() {
 34     try {
 35         Array<int> Ab(3, 2, 2, 3);//2*2*3数组
 36         Ab.Assign(3, 0, 0, 0);
 37         Ab.Assign(7, 0, 0, 1);
 38         Ab.Assign(8, 0, 0, 2);
 39         Ab.Assign(1, 0, 1, 0);
 40         Ab.Assign(10, 0, 1, 1);
 41         Ab.Assign(-1, 0, 1, 2);
 42 
 43         Ab.Assign(3, 1, 0, 0);
 44         Ab.Assign(7, 1, 0, 1);
 45         Ab.Assign(8, 1, 0, 2);
 46         Ab.Assign(1, 1, 1, 0);
 47         Ab.Assign(10, 1, 1, 1);
 48         Ab.Assign(-1, 1, 1, 2);
 49         Ab.Show();
 50 
 51         //验证valueof
 52         int e = 0;
 53         Ab.ValueOf(e, 99, 0, 1, 2);//temp不起作用,va_start()参数不能包含引用类型
 54         cout << "ValueOf(0,1,2)=" << e << endl;
 55 
 56         //验证assign
 57         Ab.Assign(0, 0, 0, 0);
 58         Ab.Show();
 59 
 60         Ab.DestoryArray();
 61     }
 62     catch (const char *s)
 63     {
 64         cout << s;
 65     }
 66     system("pause");
 67 }
 68 template<class T>
 69 void Array<T>::Show() 
 70 {
 71     int elemtotal = 1;
 72     for (int i = 0, j = A.dim; i < j; i++)
 73         elemtotal *= A.bounds[i];
 74     cout << "数组的元素(按二维写出):" << endl << endl;
 75     for (int i = 0; i < elemtotal; i++)
 76     {
 77         cout << *(A.base + i) << '	';
 78         if (!((i + 1) % A.constants[0]))
 79             cout << endl << endl;
 80     }
 81 }
 82 
 83 template<class T>
 84 void Array<T>::Assign(T e, ...) {
 85     va_list(ap);
 86     va_start(ap, e);
 87     int off = -1;
 88     Locate(ap, off);
 89     *(A.base + off) = e;
 90     return;
 91 }
 92 template<class T>
 93 void Array<T>::ValueOf(T &e, int temp, ...) {
 94     va_list(ap);
 95     va_start(ap, temp);
 96     int off = 2;
 97     Locate(ap, off);
 98     e = *(A.base + off);
 99     return;
100 }
101 template<class T>
102 void Array<T>::Locate(va_list ap, int &off) {
103     off = 0;
104     for (int i = 0; i < A.dim; i++)
105     {
106         int ind = va_arg(ap, T);
107         if (ind < 0 || ind >= A.bounds[i])
108         {
109             throw"Locate():维数错误";
110             return;
111         }
112         off += A.constants[i] * ind;
113     }
114 }
115 template<class T>
116 Array<T>::Array(int dim, ...)
117 {
118     if (dim<1 || dim>MAX_ARRAY_DIM)
119     {
120         throw"Array():维数非法";
121         return;
122     }
123     //bounds数组用于记录dim个维度个长度
124     A.dim = dim;
125     try {
126         A.bounds = new int[dim];//开辟dim大小的int数组
127     }
128     catch (const bad_alloc &) {
129         throw"Array():空间开辟失败!";
130         return;
131     }
132 
133     //统计总共需要的T变量的空间的个数
134     int elemtotal = 1;
135     va_list(ap);
136     va_start(ap, dim);
137     for (int i = 0; i < dim; i++) {
138         A.bounds[i] = va_arg(ap, int);
139         if (A.bounds[i] <= 0) {
140             throw"Array(): bounds[dim]初始化错误!";
141             return;
142         }
143         elemtotal *= A.bounds[i];
144     }
145     va_end(ap);
146     try {
147         A.base = new T[elemtotal];//线性开辟总空间
148     }
149     catch (const bad_alloc &) {
150         throw"Array():空间开辟失败!";
151         return;
152     }
153     //初始化base
154     for (int i = 0; i < elemtotal; i++)
155         *(A.base + i) = 0;
156 
157     try {
158         A.constants = new int[dim];//记录偏移量的int数组constants分配空间
159     }
160     catch (const bad_alloc &) {
161         throw"Array():空间开辟失败!";
162         return;
163     }
164 
165     //计算并得到 偏移量数组constants
166     A.constants[dim - 1] = 1;
167     for (int i = dim - 2; i >= 0; i--) {
168         A.constants[i] = A.constants[i + 1] * A.bounds[i + 1];
169     }
170     return;
171 }
172 
173 template<class T>
174 void Array<T>::DestoryArray() {
175     delete[]A.base;
176     delete[]A.bounds;
177     delete[]A.constants;
178     return;
179 }
View Code
原文地址:https://www.cnblogs.com/guoyujiang/p/11755178.html