Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introduction
Imagine writing a program to analyse a data set of 1000 pairs of voltages and currents from an experiment to study the electrical characteristics of some semiconductor device. You could declare enough double variables, v1, i1, v2, i2, etc, but the program would at best be difficult to implement and debug. It would be much more convenient to have some way of grouping together related variables. The most common way to achieve this in programming is the array. An array is a series of objects, all of the same type , stored next to each other in memory. The array is referred to by a single name and individual elements are accessed via an index (see below).
where size is the number of elements that the array can store, this is always an (unsigned) integer. For example:
d o u b l ex _ d a t a [ 1 0 0 ] ;
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation
1/9
4/17/2014
declares an array called x _ d a t athat stores 100 values of type double . Using array variables Array variables are used in much the same way as ordinary variables, but with an element number specified. In C the number of array elements starts at 0. This means that the last element in the array x _ d a t ahas index number 99. The index of the required element is put in square brackets after the array variable's name. So to assign the value 3.14159 to the seventh element of x _ d a t aone would use:
x _ d a t a [ 6 ]=3 . 1 4 1 5 9 ;
Since the index can be specified by an integer variable this means that loops and related structures can be used to access all the elements in an array. For instance a loop can be used to print out all the values stored in x _ d a t aarray defined above:
f o r( i = 0 ; i < 1 0 0 ; i + + )p r i n t f ( " x _ d a t a [ % d ]=% l f \ n " ,i ,x _ d a t a [ i ] ) ;
Initializing arrays As with ordinary variables it is important to make sure that sensible start values are stored in an array before using it. A loop is used initialise an array that has already been declared:
i n ta r r a y [ 5 ] ; f o r( i = 0 ; i < 5 ; i + + )a r r a y [ i ]=0 ;
The compiler uses the number of items in the initialiser list, {...}, to determine the size of the array. Thus there is no need for a number between the square brackets. In the example above an array of four integers is declared (array[0]=1, array[1]=3, etc.)
Multidimensional arrays
A two dimensional array can be declared by specifying two sizes in brackets, e.g.
i n tm a t r i x[ 5 ] [ 1 0 ] ;
this creates an array of integers that is 5 row by 10 columns large. To use such an array, both indices must be specified, e.g.:
m a t r i x[ 2 ] [ 3 ]=1 3 ;
Arrays of 3 or more dimensions may be declared by using the required number of indices in the declaration.
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation 2/9
4/17/2014
C arrays are similar to matrices in mathematics. However, the index reference system starts from 0. Whilst this is not really a problem it does mean that extra care should be taken when writing a computer program to implement some matrix based piece of mathematics. Initialising multidimensional arrays The example below shows three different ways to initialise a 2-dimensional array using lists:
d o u b l ed a t a _ a r r a y [ 2 ] [ 2 ]={ 1 . 0 , 2 . 0 , 3 . 0 , 4 . 0 } ; d o u b l ed a t a _ a r r a y [ 2 ] [ 2 ]={ { 1 . 0 , 2 . 0 } , { 3 . 0 , 4 . 0 } } ; d o u b l ed a t a _ a r r a y [] [ 2 ]={ { 1 . 0 , 2 . 0 } , { 3 . 0 , 4 . 0 } } ;
If the first bracket set is empty then the compiler uses the number of inner brace pairs to define this dimension. All the other dimensions must be specified explicitly. Extra sets of braces can be used to initialise lists for higher dimensional arrays. All of the three statements above are equivalent to:
d o u b l ed a t a _ a r r a y [ 2 ] [ 2 ] ; d a t a _ a r r a y [ 0 ] [ 0 ]=1 . 0 ; d a t a _ a r r a y [ 0 ] [ 1 ]=2 . 0 ; d a t a _ a r r a y [ 1 ] [ 0 ]=3 . 0 ; d a t a _ a r r a y [ 1 ] [ 1 ]=4 . 0 ;
Next a block of memory of the required size is allocated using the m a l l o c ( )function:
a r r a y _ n a m e=( t y p e * )m a l l o c ( s i z e ) ;
where size is an integer corresponding to the number of bytes of memory required for the array. This size can be obtained by using the s i z e o f ( )function which returns the number of bytes that a given variable type holds. Having finished using the array, the memory must be emptied so that it can be re-used. This is done with the f r e e ( ) function as follows:
f r e e ( ( v o i d * )a r r a y _ n a m e ) ;
If memory is not re-claimed after use, and more and more memory is dynamically reserved during run-time, then there will be memory-leaks and run-time failures. The cast to v o i d *prevents the pointer being accidentally reused for some other purpose elsewhere in the program.
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation 3/9
4/17/2014
The functions m a l l o c ( ) ,f r e e ( )and s i z e o f ( )are provided by the header file s t d l i b . h The following example illustrates how to dynamically declare and then use an array called i _ a r r a ythat stores a number of integers that is specified by the user at run-time:
# i n c l u d e< s t d i o . h > # i n c l u d e< s t d l i b . h > i n tm a i n ( v o i d ) { i n ti ; i n t *i _ a r r a y ; i n tj ;
/ /t h i sw i l lb et h ea r r a y
/ /f i n do u th o wm a n yi n t e g e r sa r er e q u i r e d p r i n t f ( " H o wm a n yi n t e g e r s ?" ) ; s c a n f ( " % d " , & i ) ; / /N o wa l l o c a t em e m o r ys p a c e i _ a r r a y=( i n t * ) m a l l o c ( i * s i z e o f ( i n t ) ) ; / /c o d et h a tu s e st h en e wa r r a y f o r( j = 0 ; j < i ; j + + ) { i _ a r r a y [ j ] = j ; p r i n t f ( " % d \ n " , i _ a r r a y [ j ] ) ; } f r e e ( ( v o i d * )i _ a r r a y ) ; s y s t e m ( " p a u s e " ) ; r e t u r n0 ; }
/ /a l l o c a t es t o r a g ef o rt h ea r r a y
/ /t h ep o i n t e rc a nb eu s e da sa na r r a y
/ /f r e eu pm e m o r yf o rr e u s e .
Multidimensional arrays
The case of dynamically allocating a multidimensional array using the m a l l o cmethod is a little more complicated. A 2-dimensional array can be thought of as a "array of arrays", so first an array of pointers is made for the rows and then each element of this array is, in turn, a pointer to an array which forms the columns of the 2D array. This is best illustrated by the following example:
# i n c l u d e< s t d i o . h > # i n c l u d e< s t d l i b . h > i n tm a i n ( v o i d ) { i n ti , n r o w s , n c o l s ; / /D e f i n et h es i z eo ft h ea r r a ya tr u nt i m e p r i n t f ( " E n t e rn u m b e ro fr o w sa n dn u m b e ro fc o l u m n s" ) ; s c a n f ( " % d% d " , & n r o w s , & n c o l s ) ; i n t * *a r r a y ; a r r a y = ( i n t * * ) m a l l o c ( n r o w s * s i z e o f ( i n t * ) ) ; f o r( i = 0 ;i < n r o w s ;i + + ) a r r a y [ i ] = ( i n t * ) m a l l o c ( n c o l s * s i z e o f ( i n t ) ) ; f u n c ( a r r a y ,n r o w s ,n c o l s ) ;/ /s o m ef u n c t i o nt h a tu s e st h ea r r a y. . . . f o r( i = 0 ;i < n r o w s ;i + + )
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation 4/9
4/17/2014
f r e e ( ( v o i d * ) a r r a y [ i ] ) ; f r e e ( ( v o i d * ) a r r a y ) ; s y s t e m ( " p a u s e " ) ; r e t u r n0 ; }
The definition of the array pointer and the f r e ecommands remain the same. The example above, dynamically creating a one-dimensional array called i _ a r r a yvia the m a l l o ccommand is repeated here using n e winstead:
# i n c l u d e< s t d i o . h > # i n c l u d e< s t d l i b . h > i n tm a i n ( v o i d ) { i n ti ; i n t *i _ a r r a y ; i n tj ;
/ /t h i sw i l lb et h ea r r a y
/ /t h ep o i n t e rc a nb eu s e da sa na r r a y
5/9
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation
4/17/2014
} f r e e ( ( v o i d * )i _ a r r a y ) ; s y s t e m ( " p a u s e " ) ; r e t u r n0 ; }
/ /f r e eu pm e m o r yf o rr e u s e .
Multidimensional arrays
Multidimensional arrays can be dynamically allocated via the n e wmethod too. The following is an example of this which shows the 2-dimensional array created in the m a l l o cexample above being dynamically allocated using the n e wmethod instead.
# i n c l u d e< s t d i o . h > # i n c l u d e< s t d l i b . h > i n tm a i n ( v o i d ) { i n ti ,n r o w s , c o l s ; / /D e f i n et h es i z eo ft h ea r r a ya tr u nt i m e p r i n t f ( " E n t e rn u m b e ro fr o w sa n dn u m b e ro fc o l u m n s" ) ; s c a n f ( " % d% d " , & n r o w s , & n c o l s ) ; i n t * *a r r a y ; a r r a y = n e wi n t * [ n r o w s ] ; f o r( i = 0 ;i < n r o w s ;i + + ) a r r a y [ i ] = n e wi n t [ n c o l s ] ; f u n c ( a r r a y ,n r o w s ,n c o l s ) ;/ /s o m ef u n c t i o nt h a tu s e st h ea r r a y. . . . f o r( i = 0 ;i < n r o w s ;i + + ) f r e e ( ( v o i d * ) a r r a y [ i ] ) ; f r e e ( ( v o i d * ) a r r a y ) ; s y s t e m ( " p a u s e " ) ; r e t u r n0 ; }
4/17/2014
d o u b l ea v e r a g e ( d o u b l ed a t a _ a r r a y [ ] ,i n tn ) ;
alternatively, the array type name and size can be given, e.g.
d o u b l ea v e r a g e ( d o u b l ed a t a _ a r r a y [ 9 ] ,i n tn ) ;
As an example of the usage of arrays with functions, a program to calculate the cross product of two vectors is shown below:
# i n c l u d e < s t d i o . h > # i n c l u d e < s t d l i b . h > # i n c l u d e < m a t h . h > v o i dc r o s s( d o u b l ev 1 [ ] ,d o u b l ev 2 [ ] ,d o u b l ev c r o s s [ ] ) ; i n tm a i n ( v o i d ) { F I L E* i n f i l e 1 ,* i n f i l e 2 ,* o u t f i l e ; d o u b l ev e c 1 [ 3 ] ,v e c 2 [ 3 ] ,v e c 3 [ 3 ] ; / /f u n c t i o np r o t o t y p e
/ /O p e nf i l e sa n ds t o pw i t he r r o rc o d e si ft h i sf a i l s i f( ( i n f i l e 1 = f o p e n ( " v e c t o r 1 . t x t " , " r " ) )= =N U L L ) { p r i n t f ( " E r r o r :i n p u tf i l ev e c t o r 1 . t x tc a n n o tb eo p e n e d " ) ; s y s t e m ( " p a u s e " ) ; r e t u r n1 ; } i f( ( i n f i l e 2 = f o p e n ( " v e c t o r 2 . t x t " , " r " ) )= =N U L L ) { p r i n t f ( " E r r o r :i n p u tf i l ev e c t o r 2 . t x tc a n n o tb eo p e n e d " ) ; s y s t e m ( " p a u s e " ) ; r e t u r n1 ; } i f( ( o u t f i l e = f o p e n ( " c r o s s . t x t " , " w " ) )= =N U L L ) { p r i n t f ( " E r r o r :o u t p u tf i l ec r o s s . t x tc a n n o tb eo p e n e d " ) ; s y s t e m ( " p a u s e " ) ; r e t u r n1 ; } / /f i l e sh a v eb e e no p e n e ds on o wr e a di nd a t as e t sa n dc a l lc r o s s ( )f u n c t i o n w h i l e (( f s c a n f ( i n f i l e 1 ," % l f % l f % l f " ,& v e c 1 [ 0 ] ,& v e c 1 [ 1 ] ,& v e c 1 [ 2 ])>0 ) & &( f s c a n f ( i n f i l e 2 ," % l f % l f % l f " ,& v e c 2 [ 0 ] ,& v e c 2 [ 1 ] ,& v e c 2 [ 2 ])>0 )) { c r o s s(v e c 1 ,v e c 2 ,v e c 3) ; / /c a l lc r o s s ( )f u n c t i o n f p r i n t f ( o u t f i l e , " % l f% l f% l f \ n " , v e c 3 [ 0 ] , v e c 3 [ 1 ] , v e c 3 [ 2 ] ) ; } / /a l ld o n e ,c l o s ef i l e s f c l o s e ( i n f i l e 1 ) ; f c l o s e ( i n f i l e 2 ) ; f c l o s e ( o u t f i l e ) ; s y s t e m ( " p a u s e " ) ; r e t u r n0 ;
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation 7/9
/ /w r i t er e s u l t st of i l e
4/17/2014
v o i dc r o s s( d o u b l ev 1 [ ] ,d o u b l ev 2 [ ] ,d o u b l ev c r o s s [ ] ) { / /c o d et oc a l c u l a t ec r o s sp r o d u c t s v c r o s s [ 0 ]=v 1 [ 1 ]*v 2 [ 2 ]-v 1 [ 2 ]*v 2 [ 1 ] ; v c r o s s [ 1 ]=v 1 [ 0 ]*v 2 [ 2 ]-v 1 [ 2 ]*v 2 [ 0 ] ; v c r o s s [ 2 ]=v 1 [ 0 ]*v 2 [ 1 ]-v 1 [ 1 ]*v 2 [ 0 ] ; r e t u r n ; }
Notes: The function prototype and function definition could have the array dimensions inside the square brackets The call to function cross has the names of the arrays ONLY, i.e. no brackets (this is important) In this case function cross is of type void, see how such a function is called In the above example, pointers could also be used to pass the three arrays to the function c r o s s . In this case
v o i dc r o s s( d o u b l ev 1 [ ] ,d o u b l ev 2 [ ] ,d o u b l ev c r o s s [ ] )
must be replaced by
v o i dc r o s s (d o u b l e* v 1 ,d o u b l e* v 2 ,d o u b l e* v 3 )
in both the function definition and the function prototype. Nothing else needs changing (it is not necessary to use the deferencing operator inside function c r o s swhen referring to the array variables).
Multidimensional arrays
For arrays with more than one dimension similar rules apply. First of all the array type and array name can be given along with empty square parentheses, however, in this case in the function prototype then the size of the upper dimensions must be specified in the function prototype:
d o u b l ec a l c _ a r r a y ( d o u b l ed a t a _ a r r a y [ ] [ 3 ] ,i n tn r o w s ,i n tn c o l s ) ;
alternatively, the array type, name and dimension sizes can be explicitly given, e.g.:
d o u b l ec a l c _ a r r a y ( d o u b l ed a t a _ a r r a y [ 3 ] [ 3 ] ,i n tn r o w s ,i n tn c o l s ) ;
Finally, the arrays can be passed via pointers, for a 2D array this would look like:
d o u b l ec a l c _ a r r a y ( d o u b l e* * d a t a _ a r r a y ,i n tn r o w s ,i n tn c o l s ) ;
4/17/2014
of the array. This means that code like the following would be accepted by the compiler and will run:
# i n c l u d e < s t d l i b . h > # i n c l u d e < s t d i o . h > # i n c l u d e < m a t h . h > i n tm a i n ( v o i d ) { i n ti ; i n ta r r a y [ 1 0 ] ; / /a na r r a yo ft e ni n t e g e r s f o r( i = 0 ; i < 2 0 ; i + + )a r r a y [ i ] = 3 * i ; / /s t o r e2 0v a l u e si nt h ea r r a y f o r ( i = 1 9 ; i > = 0 ; i )p r i n t f ( " % d \ n " , a r r a y [ i ] ) ;/ /p r i n to u tv a l u e si nr e v e r s eo r d e r s y s t e m ( " p a u s e " ) ; r e t u r n0 ; }
The for loop attempts to store 20 values in an array only large enough to store 10 values. This program will compile on a lot of computer systems. The problem is that the extra memory used is not reserved and the computer's operating system and/or the program itself can store other values in this memory space. Worse, data may already be stored in this space before you overwrite it. This sort of programming error can be very difficult to trace and you should take the utmost care to prevent it occurring.
Further Reading
Kelley and Pohl: Chapter 6, Arrays, Pointers, and Strings, pp 245-330. http://en.wikibooks.org/wiki/C_Programming/Arrays http://en.wikibooks.org/wiki/C_Programming/Pointers_and_arrays http://en.wikibooks.org/wiki/C_Programming/Memory_management http://en.wikibooks.org/wiki/C_Programming/Strings Return to the course summary Retrieved from "http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays%2C_dynamic_array_allocation"
http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Arrays,_dynamic_array_allocation
9/9