Link to home
Start Free TrialLog in
Avatar of learn
learn

asked on

Very simple, but i donw know.

Very simple, but i donw know.
How to do:
unsigned short asize = 999; //or use const
int i1[asize];
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

You can''t declare a local or global array (using []) with a variable size, their sizes must be constant.  That is

const int ConstInt = 5;
int VarInt = 5;

SomeClass Array1[ConstInt];  // okay.
SomeClass Array2[VarInt]; // Compiler error.

But that is okay, you don't need to.  continues.
What you can do is declare a pointer to an array that is dynamically allocated using the "new [] operator". "new []" can take a variable length for the array.  

Before I show you an example, I should mention that in C and C++ pointers and arrays are closely related.  When you declare an local or global array, like

int IntAry[5];

You are creating an array of 5 ints.  But "IntAry" is not the array. IntAry is really a pointer.  It is a pointer to the first entry in the array.  You can access items in the array using either of these syntaxes

int i1 = IntAry[2];  // Get third item.
int i1 = IntAry+2;  // Get third item.

In the first case, with the [], it makes it seem like IntAry is an array.  And the second case, +2, it makes IntAry seem like a pointer.  but both cases are the same.  IntAry is really a pointer and the two cases generate the same code for the computer.

That means that you can use new to generate a dynamic array in memory and get back a pointer to that array.  And then use that pointer just like you are used to with arrays.  

Continues.

unsigned short asize = 999;

//  asize could be altered now.
int * i1 = new int[asize];

Now even though i1 is not an array, it can be used syntactically like one, like

int Int1 = i1[1]; // array like.
int Int2 = i1[2];
int Int3 = *(i+3);  // pointer like.

The difference between this approach and you original approach is that you must remember to destroy this array when you are done using delete [].

Now I have to go!!!  I'll get back to you about the other question in a few hours.
There's an uglier, older, but sometimes ass-saving method... use manifest constants which operate at the preprocessor level, ie

#define MAX_ARRAY_SIZE 999

int i1[MAX_ARRAY_SIZE];

This can sometimes bail you out of otherwise intractable problems because you can perform the #defines outside of the compiler, in the compiler command line.  This lets you compile the same source code in different ways depending on the values of defines.
Depending on what your problem is CArray class might be an answer, but if your not familiar with C++ classes and templates it may be a bit confusing.  Try looking in the documentation for Carray.  Basically what it is, is a class that looks like a natural array, so once you declare it you can index like normal:
MyCArray[53]=255; and so on, but the differance is it allocates more space if you need it.  This means you can declare it with say 500 elements with a grow rate of 10 elements.  What happens is if you end up needing more than 500 elements, it will automatically make the array larger, 10 elements at a time.  This will help if what you are trying to do is allocate space but you just don't know how much you need until runtime.  Now in the case that you need to allocate an exact amount of space, but you don't know this exact amount until runtime, you need to use the Win32 Memory Allocation functions.  It's a bit more complicated than the CArray, but still not too hard to follow.  Let me know if you need more info.
Warmcat there is absolutely no reason to use a #define like that.  You can use a C++ constant instead.  Like

const int MAX_ARRAY_SIZE = 999

int i1[MAX_ARRAY_SIZE];

This has the advantage of  type and scope safety that the #define does not have.
bequette, the CArray class is an MFC class.  Learn does not appear to be using MFC (from other questions and the fact that this is the C++ topic area)  What he could be using is the vector container in STL.  But A he does not have the STL and B I believe he is trying to write a similar container himself (good learning experience).

>>Now in the case that you need to allocate an exact amount of space, but
>> you don't know this exact amount until runtime, you need to use the Win32
>> Memory Allocation functions
Why the Win32 memory allocation functions? C++ has new and delete.  
Avatar of learn

ASKER

Hi Nietod

>unsigned short asize = 999;
>    //  asize could be altered now.
>    int * i1 = new int[asize];

But how to resize the array latter? Using delete, new and copy? If the array is big and the elements in it is long also......

Cheers.
Yes unfortuanely, new, copy, then delete are the only safe ways.  (There are some special case ways, but they are not general purpose and should be avoided).  This can get a little slow.  (Far less than you might think however, I'm ussually surprised at how fast this stuff can be done.)  
However, there are things that you can do to make it much faster.  First of all, remember what I suggested about allocating extra space in the string array that you use for expansion, that way you don't have to allocate a new array and copy every time a letter is added to the string?  well you can do that to the array as well.  Store two lengths.  One, the storage length, is the number of items stored in the actual array (the number of items you allocated)  This is not the items that the users of the array consider to be stored in the array.  This is the number of items that can be stored before it will be necessary to resize the array.  The other number is the number of items that are currently stored in the array class.  This is the number of items that the users of the classs will care about.  As far as they are concerned, this is the number of items storedl  For example, you create the array with 10 items and record that there is room for 10 items, but you indicate that there are no itmes stored.  (that is storage length is 10, but current lengthis 0.)  Then the user can add 10 items to the array, before the first time you need to reallocate and copy.  Make sense?

Another thing you can do is use reference counting.  Reference counting is a technique that can be used to make it possible to copy items very fast (Actually, it makes it seem like you copied the item, but doesn't really copy it.  If you add refernce counting to the string class it will be much faster to copy the strings from the old array to the new array.  Many things will actually become much faster.  I would make that a goal, but I would wait before doing it.  You don't have to do it right away.  you can add it later without changing the code that uses the string class.  That is, you will change the string class, but the code that uses the string class will stay the same.  The books suggested before deal with reference counting and other optimizations.  I would read them before starting this.  (I would be happy to help you, but you would do best to read the books first in any case.)