473,574 Members | 2,260 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Arrays Revealed

weaknessforcats
9,208 Recognized Expert Moderator Expert
Arrays Revealed

Introduction
Arrays are the built-in containers of C and C++. This article assumes the reader has some experiece with
arrays and array syntax but is not clear on a )exactly how multi-dimensional arrays work, b) how to call
a function with a multi-dimensional array, c) how to return a multi-dimensional array from a function,
or d) how to read and write arrays from a disc file.

Note to C++ programmers: You should be using vectors instead of arrays. The protective code you need
to write around your array is a duplication of the protective code written around the array in the STL.
The STL just calls their array plus managing code a vector.

Note to C programmers: Everything in this article conforms to ANSI-C with the exception of heap allocations.
The examples use the C++ new operator where a C programmer would call malloc().


How to Define Arrays
First, there are only one-dimensional arrays in C or C++. The number of elements is put between brackets:
Expand|Select|Wrap|Line Numbers
  1. int array[5];
  2.  
That is an array of 5 elements each of which is an int.

Expand|Select|Wrap|Line Numbers
  1. int array[];
  2.  
won't compile. You need to declare the number of elements.

Second, this array:
Expand|Select|Wrap|Line Numbers
  1. int array[5][10];
  2.  
is still an array of 5 elements. Each element is an array of 10 int.

Expand|Select|Wrap|Line Numbers
  1. int array[5][10][15];
  2.  
is still an array of 5 elements. Each element is an array of 10 elements where each element is an array of 15 int.


Expand|Select|Wrap|Line Numbers
  1. int array[][10];
  2.  
won't compile. You need to declare the number of elements.

Third, the name of an array is the address of element 0
Expand|Select|Wrap|Line Numbers
  1. int array[5];
  2.  
Here array is the address of array[0]. Since array[0] is an int, array is the address of an int. You can assign the name array to an int*.

Expand|Select|Wrap|Line Numbers
  1. int array[5][10];
  2.  
Here array is the address of array[0]. Since array[0] is an array of 10 int, array is the address of an array of 10 int. You can assign the name array to a pointer to an array of 10 int:
Expand|Select|Wrap|Line Numbers
  1. int array[5][10];
  2.  
  3. int (*ptr)[10] = array;
  4.  
Fourth, when the number of elements is not known at compile time, you create the array dynamically:

Expand|Select|Wrap|Line Numbers
  1. int* array = new int[value];
  2. int (*ptr)[10] = new int[value][10];
  3. int (*ptr)[10][15] = new int[value][10][15];
  4.  
In each case value is the number of elements. Any other brackets only describe the elements.

Using an int** for an array of arrays is incorrect and produces wrong answers using pointer arithmetic. The compiler knows this so it won't compile this code:

Expand|Select|Wrap|Line Numbers
  1. int** ptr = new int[value][10];    //ERROR
  2.  
new returns the address of an array of 10 int and that isn't the same as an int**.

Likewise:
Expand|Select|Wrap|Line Numbers
  1. int*** ptr = new int[value][10][15];    //ERROR
  2.  
new returns the address of an array of 10 elements where each element is an array of 15 int and that isn't the same as an int***.

With the above in mind this array:
Expand|Select|Wrap|Line Numbers
  1. int array[10] = {0,1,2,3,4,5,6,7,8,9};
  2.  
has a memory layout of

0 1 2 3 4 5 6 7 8 9

Wheras this array:
Expand|Select|Wrap|Line Numbers
  1. int array[5][2] = {0,1,2,3,4,5,6,7,8,9};
  2.  
has a memory layout of

0 1 2 3 4 5 6 7 8 9

Kinda the same, right?

So if your disc file contains

0 1 2 3 4 5 6 7 8 9

Does it make a difference wheher you read into a one-dimensional array or a two-dimensional array? No.

Therefore, when you do your read use the address of array[0][0] and read as though you have a
one-dimensional array and the values will be in the correct locations.

Passing Multi-dimensional Arrays to Functions

This array:

Expand|Select|Wrap|Line Numbers
  1. int arr[3][4][5];
  2.  

can be passed to a function if the argument to func() is a pointer to a [4][5] array:
Expand|Select|Wrap|Line Numbers
  1. void func(int (* arg)[4][5], unsigned int x);
  2.  
  3. int main()
  4. {
  5.     int arr[3][4][5];
  6.     func(arr, 3);
  7. }
  8.  
But if the func argument is a pointer to an [5] array of int, you need to pass the &arr[0][0]:
Expand|Select|Wrap|Line Numbers
  1. void func(int (* arg)[5], unsigned int x, int y);
  2. int main()
  3. {
  4.     int arr[3][4][5];
  5.     func(&arr[0][0], 3, 4);
  6. }
  7.  
But if the func argument is a pointer to an int, you need to pass the &arr[0][0][0]:
Expand|Select|Wrap|Line Numbers
  1. void func(int * arg, unsigned int x, int y, int z);
  2. int main()
  3. {
  4.     int arr[3][4][5];
  5.     func(&arr[0][0][0], 3, 4, 5);
  6. }
  7.  
As you omit dimensions, notice that you need to add arguments to func() since the "array-ness" is
lost on the call. This is called decay of array and it occurs whenever an array is passed
to a function. From inside the function all you see is an address and not an array. That forces you to pass
the number of elements in the "dimensions ".

Returning Multi-dimensional Arrays from Functions

Returning an array from a function only has meaning if the array was created by the function. Otherwise,
no return is necessary since an existing array is passed by the address. However, if the function has
created the array on the heap, you can return the address of element 0.

The problem here is that you can't use the function return type unless you a) return a type or
b) return a pointer to a type. That is, you cannot return a pointer to an array since an array is not
a type. So, if you create an array of int you can return the array as an int*:
Expand|Select|Wrap|Line Numbers
  1. int* func(int arg)
  2. {
  3.     int* temp = new int[arg];
  4.     return temp;
  5. }
  6. int main()
  7. {
  8.     int* arr = func(5);
  9. }
  10.  
This does not work when you create a multi-dimensional array:
Expand|Select|Wrap|Line Numbers
  1. int (*)[5] func(int arg)   // ERROR: Cannot return an array
  2. {
  3.     int (* temp)[5] = new int[arg][5];
  4.     return temp;
  5. }
  6. int main()
  7. {
  8.     int (* arr)[5] = func(4);
  9. }
  10.  
In this case you could pass in the address of a pointer to an array of 5 int:
Expand|Select|Wrap|Line Numbers
  1. void func(int arg, int (**rval)[5])
  2. {
  3.     int (* temp)[5] = new int[arg][5];
  4.     *rval = temp;
  5. }    
  6. int main()
  7. {
  8.     int (* arr)[5] = 0;
  9.     func(4, &arr);
  10.     //arr is now a [4][5] array of int
  11. }
  12.  
However, if you need to use the function as an RVAL, then you need to return a type. Here the easiest thing to do is define a type to be a pointer to an element of your multi-dimensional array. In this example you would need a pointer to an array of 5 int:

Expand|Select|Wrap|Line Numbers
  1. typedef int (*IntArray5Ptr)[5]; 
Now you have a type that can be returned:

Expand|Select|Wrap|Line Numbers
  1. IntArray5Ptr func(int arg)    
  2.     int (* temp)[5] = new int[arg][5]; 
  3.     return temp; 
  4. }
  5.  
  6. int main() 
  7.     int (* arrA)[5] = func(4); 
You can return a pointer to type in addition to returning a type. So you could define a type to be an element of your array (in the example this is an array of 5 int) and return a pointer to that type:

Expand|Select|Wrap|Line Numbers
  1. typedef int IntArray5[5]; 
  2.  
  3. IntArray5* funcB(int arg) 
  4.     int (* temp)[5] = new int[arg][5]; 
  5.     return temp; 
  6.  
  7.  
  8. int main() 
  9.     int (* arr)[5] = func(4); 
Finally, as was stated at the beginning of this article: There are no multi-dimensional arrays in C++.
Therefore, a function could just create a one-dimensional array of the correct number of elements and return
the address of element 0. In this case, element 0 is a type and you can use the return type of a function
to return a pointer to a type. Then the calling function could typecast the return so the array can be
used with muliple dimensions:

Expand|Select|Wrap|Line Numbers
  1. int* func(int arg)
  2. {
  3.     int * temp = new int[arg];
  4.     return temp;
  5. }    
  6. int main()
  7. {
  8.     //This is arr[60]
  9.     int* arr = func(60);
  10.  
  11.     //This is arr[12][5] --> 12 x 5 = 60
  12.     int (*arr1)[5] = (int(*)[5])func(60);
  13.  
  14.     //This is arr[3][4][5] -> 3 * 4 * 5 = 60
  15.     int (*arr2)[4][5] = (int(*)[4][5])func(60);
  16.  
  17.     //This is arr[1][3][4][5] -> 1*3*4*5 = 60;
  18.     int (*arr3)[3][4][5] = (int(*)[3][4][5])func(60);
  19.  
  20.  
  21.  
  22. }
  23.  
Revision History

2010/04/11 - Added examples of returning a multi-dimensional array from an RVAL function.


Copyright 2010 Buchmiller Technical Associates North Bend WA USA
Feb 18 '08 #1
29 35415
AmberJain
884 Recognized Expert Contributor
PERFECT........ ....

What an article.......m ust read for every C newbie like me....
Thanks for such a nice article
Feb 20 '08 #2
cube
18 New Member
Very good article!

If you could write some examples that we could copy and paste them to a compiler, just to see the result, it would be nice!
Feb 20 '08 #3
weaknessforcats
9,208 Recognized Expert Moderator Expert
Very good article!

If you could write some examples that we could copy and paste them to a compiler, just to see the result, it would be nice!
How do you mean? All of the code in the article can be compiled.
Feb 21 '08 #4
cube
18 New Member
How do you mean? All of the code in the article can be compiled.
Yes, but after compilation, they don't return any results to the screen (propably because there are no printf). And at least for me who just started reading about C is difficult to place a printf on examples with pointers and arrays, etc.
...or am I doing sthg wrong and I don't get results??????
Feb 28 '08 #5
whodgson
542 Contributor
On a minor point, early in the article you say that int a [ ] [10] won't compile. I assume you mean when the code is declaring the array, because it is permissable to call a function which includes an array as its arguement like void print( int a [ ] [10 ]..... or so my book says.
Thanks for your article
Apr 10 '08 #6
weaknessforcats
9,208 Recognized Expert Moderator Expert
On a minor point, early in the article you say that int a [ ] [10] won't compile. I assume you mean when the code is declaring the array, because it is permissable to call a function which includes an array as its arguement like void print( int a [ ] [10 ]..... or so my book says.
Thanks for your article
Your book is correct. As a function argument int a [ ] [10 ] is a pointer. As an array definition it is incomplete because it lacks the number of elements in the array. It is the array definition that is referred to in the article.
Apr 10 '08 #7
euclidav
2 New Member
Thank you .... What a wonderful article !!! I should have read it a couple months back :(
Jul 18 '08 #8
ajmaschinot
1 New Member
Thank you for your guide!

Correct me if I am wrong, but shouldn't the following line:

int (*ptr)[10];

be interpreted as "an array of 10 pointers to int" and not as "a ptr to an array of 10 ints"? I thought that the bracket operator had higher precedence than dereference (hence the parenthesis around *ptr).
Sep 29 '08 #9
weaknessforcats
9,208 Recognized Expert Moderator Expert
Thank you for your guide!

Correct me if I am wrong, but shouldn't the following line:

int (*ptr)[10];

be interpreted as "an array of 10 pointers to int" and not as "a ptr to an array of 10 ints"? I thought that the bracket operator had higher precedence than dereference (hence the parenthesis around *ptr).
An array of 10 pointers to int would be:

int* ptr[10];

The parentheses are needed to define ptr as a pointer to an array of 10 rather than ptr as an array of 10.
Sep 29 '08 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

354
15639
by: Montrose... | last post by:
After working in c# for a year, the only conclusion I can come to is that I wish I knew c. All I need is Linux, the gnu c compiler and I can do anything. Web services are just open sockets hooked up to interfaces. The Gtk is more than enough gui.
19
2830
by: Canonical Latin | last post by:
"Leor Zolman" <leor@bdsoft.com> wrote > "Canonical Latin" <javaplus@hotmail.com> wrote: > > > ... > >But I'm still curious as to the rational of having type > >pointer-to-array-of-size-N-of-type-T (which is fine) and not having type > >array-of-size-N-of-type-T (with some exceptions, which is curious). > > So far > >the consensus seems to...
34
4154
by: Christopher Benson-Manica | last post by:
If an array is sparse, say something like var foo=; foo=4; foo='baz'; foo='moo'; is there a way to iterate through the entire array? --
5
29236
by: JezB | last post by:
What's the easiest way to concatenate arrays ? For example, I want a list of files that match one of 3 search patterns, so I need something like DirectoryInfo ld = new DirectoryInfo(searchDir); pfiles = ld.GetFiles("*.aspx.resx|") + ld.GetFiles("*.ascx.resx") + ld.GetFiles("*.master.resx"); but of course there is no + operation allowed on...
10
4975
by: David Fort | last post by:
Hi, I'm upgrading a VB6 app to VB.net and I'm having a problem with a call to a function provided in a DLL. The function takes the address of a structure which it will fill in with values. I get an error: ---------------- An unhandled exception of type 'System.NullReferenceException' occured in
41
4913
by: Rene Nyffenegger | last post by:
Hello everyone. I am not fluent in JavaScript, so I might overlook the obvious. But in all other programming languages that I know and that have associative arrays, or hashes, the elements in the hash are alphabetically sorted if the key happens to be alpha numeric. Which I believe makes sense because it allows for fast lookup of a key.
16
2519
by: mike3 | last post by:
(I'm xposting this to both comp.lang.c++ and comp.os.ms- windows.programmer.win32 since there's Windows material in here as well as questions related to standard C++. Not sure how that'd go over at just comp.lang.c++. If one of these groups is too inappropriate, just take it off from where you send your replies.) Hi.
7
1712
by: Stefan Istrate | last post by:
I compile the following code with gcc and then I run it. It doesn't give any memory error. Is there any flag for compiler to avoid this or a method to guaranty me the access only to the valid memory? int main() { int v; v = 33; } Thank you,
0
7719
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8044
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8096
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5616
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5299
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3749
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2238
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1335
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1055
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.