Container: Native C ArrayTrail Index | References and Pointers | C Array The array is a native C construct, not a proper C++ container.
Because of this, it is tightly integrated in the language,
is slightly faster than You will also see some inconsistencies in behaviour, which arise from the underlying implementation. In fact, an array is nothing but a pointer to a memory block, and array indexing is just pointer arithmetics. /* * Containers: Native C Array */ #include <iostream> #include <cstdlib> //this gives you memset and memcpy /** * A simple container for x,y,error */ struct DataPoint { double x,y,e; DataPoint(double _x, double _y, double _e): x(_x),y(_y),e(_e) {} DataPoint():x(0),y(0),e(0) {} }; /* * a function that uses an array */ void listArray(const double array[],int len) { for (int i=0;i<len;i++) { std::cout<< " "<<i<<") "<<array[i] <<std::endl; } } /* * Very badly written function for array, * that hardcodes the length of the array. * If the array length is increased, it will * fail to operate on all of it. * If the length is decreased, it may cause * a fatal segfault, or operate on invalid data. * Never do this!! */ void badArrayFunction(double array[]) { for (int i=0;i<5;i++) { std::cout<< array[i] <<std::endl; } } /* * sizeof() gives the size in memory of a variable * but something funny happens in a subroutine, * because array[] is actually just a pointer! */ void badSize(double array[], int trueLen) { std::cout << "badSize: n: "<<trueLen << " sizeof:"<< sizeof(array) << " sizeof/sizeof(double):" << sizeof(array)/sizeof(double)<<std::endl; } int main() { using std::cout; using std::endl; /* * basic array declaration: * type name[length] */ double valueArray[20]; /* * it is strongly suggested that you put the length * of the array in a variable; make sure that it is constant. */ const int nValues=5; double values[nValues]; /* * Pay attention: native types like double * are not initialized automatically, since they don't have a constructor! * You can use memset, but ONLY with zeros! * If you put anything else there it will give you something very odd * (try and see yourself). */ memset(values,0,sizeof(values)); /* * sizeof() gives the size in memory of a variable */ cout << "main: n: "<<nValues << " sizeof:"<< sizeof(values) << " sizeof/sizeof(double):" << sizeof(values)/sizeof(double)<<endl; /* * but what happens in a subroutine ? */ badSize(values,nValues); /* * the array does not know how long it is, * it's up to you to keep track of that */ cout<< "array size: "<< nValues <<endl; for (int i=0;i<nValues;i++) { cout<< " "<<i<<") "<<values[i] <<endl; } /* * Calling a function that uses an array * you to also need to pass the length information. */ listArray(values,nValues); /* * very badly written function for array, * don't do this */ badArrayFunction(values); const int nPoints=10; /** * the declaration of an array of structure * is not different from the declaration for simple types */ DataPoint points[nPoints]; for (int i=0;i<nPoints;i++) { cout<<"point "<<i<<") "<< points[i].x <<endl; } /* * Copying an array. * Here it becomes evident what a C array is: * just a convention on using pointers */ // first try: //double values2[]=values; // error: invalid initializer, initializer fails to determine size of 'values2' // second try: //double values2[nValues]=values; // error: invalid initializer // ok, another try: use a pointer (?) double* values2=values; // I can use it just like values cout<< values2[3] << endl; // now modify the original array values[3]=4; // bad surprise: values2 is not a copy, it's just another name // for the same data cout<< values2[3] << endl; /* * so, to copy an array I have to do it explicitly */ double value3[nValues]; for (int i=0;i<nValues;i++) { value3[i]=values[i]; } /* * memcpy is a faster way to do it, * but see the comments above on sizeof() */ memcpy(value3,values,sizeof(values)); listArray(value3,nValues); } Beware of |