标签:
首先先介绍一下可变参数表需要用到的宏:
头文件:#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; }
标签:
原文地址:http://www.cnblogs.com/hujunzheng/p/4639440.html