核心知识点:
多参数函数的使用
使用标准库<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 }