📄 mainwzarraytest.html
字号:
<TITLE>WZ 1.1: Arrays</TITLE><H1>Arrays</H1><PRE>#define wzDebug#include "wzarray.hxx"</PRE><H2>template wzArray<></H2>The template <B>wzArray</B> defines unbounded arrays:<PRE>typedef wzArray<wzFloat> Float_Array;typedef wzArray<wzIndex> Index_Array;//#define Float_Array wzArray<wzFloat>//#define Index_Array wzArray<wzIndex></PRE><PRE>int main(){ Float_Array x; Index_Array y;</PRE>Now we have two arrays of potential infinite length. Of course, theyhave an actual length, now 0. But if you need some element x[100], itwill be automatically allocated:<PRE> x(200) = 20;</PRE>This requires a range check for each access, even if we are notdebugging - that's too much for many applications. For myapplications too. That's why I have two possibilities for access: Onewith range check and reallocation x(.) and one without range checkx[.]. Once x[200] was already allocated, I can use x[100], but I haveto use x(500):<PRE> x[100] = 50; x(500) = 60; // now x will be (possibly) reallocated now(x[100]==50);</PRE> <P>You can also make a lot of pointer operations. They are as fastas x[.]. But be careful: The pointer wzFloat *p=(x+234), oncecomputed, may become invalid after x(.) because of reallocation!<PRE> x[234] = 5.0; *(x+234) += 3; now(((int)x[234])==8);</PRE><H2>Connected Arrays</H2> <P>Now about some other possibilities of the template wzArray. Weoften have to handle different arrays over the same range. It would benice to reallocate them together, to have a consistentlength. Moreover, especially for cache machines, the speed of theprogram can depend very much on a simple design decision: using arecord of arrays or an array of records. Of course, it would be niceto hide this decision. Another problem occurs if we need temporaryarrays over the same range. In the worst case, we have to reallocatethe range during the time we have a temporary array. In this case, weshould not forget the reallocation of this temporary array. Now,wzArray is designed to handle these problems automatically. <P>The range is defined by a data type wzMultipleArrayController,which is assumed to be a private part of some other data type, whichcontrols the length of the range, like <B><A HREF="mainwzrangetest.html">wzRange</A></B>.<PRE> {wzMultipleArrayController cc;</PRE><PRE> Float_Array u(cc); // a simple array Float_Array v(cc,2); // a two-component array: 2*sizeof(wzFloat) Float_Array w(v,1); // component with offset 1*sizeof(wzFloat) Float_Array z(w,1); // component with offset 1*sizeof(wzFloat) // to w, thus, 2*sizeof(wzFloat) to v</PRE> <P>To allocate memory, we can (alternatively to the usual ()-call)request this from the array controller:<PRE> cc.available(1000);</PRE> <P>Now, in the memory of v we have the following order:v[0],w[0],v[1],w[1],v[2],... with the identificationv[1]==z[0],v[2]==z[1],... <P>Be careful: what is allocated at cc are only two components oflength 1000, z[1000] may not be allocated!<PRE> v[1000] = 90; w[1000] = 91; now(z[999]==90);</PRE>Note that we can add temporary arrays:<PRE> {Float_Array k(cc); // now k will be allocated with at least 1000. const Float_Array& l=v; k[1000] = 92; cc.available(2000); v[2000] = 93; // assignment v(3000) = 94; // reallocation with operator() is allowed too. k[3000] = 95; // yes, k has been already reallocated! v[1999] = l[2000]; // l == v after reallocation too. now(k[1000]==92); // should remain valid after reallocation. } // now k will be destoyed now(v[1999]==93); now(z[2999]==94); } // now cc together with v,w,z will be destroyed</PRE><H2>Reinitialization</H2> <P>Unfortunately, for arrays of wzArray<> we have some problemswith appropriate initialization. For this purpose, we have for everyconstructor also a explicit call named <B>reinitialize</B>. Thus, youcan use the default-initializer for arrays without loosing thefull possibilities of the wzArray template:<PRE> {Float_Array x[2]; {wzMultipleArrayController cc; x[0].reinitialize(cc,2); x[1].reinitialize(x[0],1); cc.available(100); x[0][100]=100; now(x[0][100]==100); } try{ // x[0] is no longer allocated x[0][100]=100; should_fail(); }catch(wzArrayRangeError){;} }</PRE> <P>Now the memory of x[0][100] is no longer allocated - it wasdeallocated together with the destruction of cc. Future use can causeerrors.<A NAME="errors"> <hr></A><H2><A HREF="errors.html">Errors</A></H2><H3><A NAME="RangeError">wzArrayRangeError</A></H3>For debugging purposes we have a range check also for []-access. Itraises the exception wzArrayRangeError:<PRE> try{ // x(200000) = 1.0; forgotten. x[501] = x[200000]; should_fail(); }catch(wzArrayRangeError f){ now(f.actual==200000); now(f.max <200000); }</PRE> <P>This requires to define <B>wzDebug</B> before the #include. Notethat I have included this definition into wz.hxx and probablyforgotten to remove it before releasing this version. This is apossibility to make the range check always during the debugging phase. <P>But do not rely on this test: A reallocation usually requires morememory than requested, thus, not every range error will be detected.<A NAME="End"> <hr></A> <P>You can test this code with: <BR> <BR><B>>cog main wzarray</B> <BR> <BR>The output should be simply: <BR> <BR><B>success</B><PRE> fine();}</PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -