Professional Documents
Culture Documents
Arrays and Pointers
Arrays and Pointers
where index would be an integer, in this case in the interval [0, 109]. Note that
the first student would be accessed using the index 0 and the 110th student by
the index 109!
A one-dimensional array in C is therefore a list of variables that are all of the
same type and are referenced through a common name. An individual variable
in the array is called an array element.
An one-dimensional array is declared using the syntax:
type va r ia ble na m e [ s i z e ] ;
where size is an integer. One may also declare a variable to be an array with no
storage allocated at declaration time. We will study those later.
For example,
i n t my array [ 5 0 ] ;
double v e l o c i t y [ 1 0 0 ] ;
declares an array of integers my_array with room for 50 elements and an array
of doubles velocity with room for 100 elements.
We repeat one more time that that, in C, array subscripts start at zero, so that
the valid following are valid elements of the above declared array are
my array [ 0 ] , my array [ 1 ] , . . . , my array [ 4 9 ]
velocity [0 ] , velocity [1 ] , . . . , velocity [99]
Note also that C makes no attempt to verify the validity of the indexed element
in an array so the burden is all on the programmer to make sure his or her code
does not access an invalid memory address.
#i n c l u d e < s t d i o . h>
main ( ) {
/∗ d e c l a r e a r r a y ∗/
int array [ 1 0 ] , i ;
/∗ popula t e a r r a y ∗/
f o r ( i = 0 ; i < 1 0 ; i ++)
array [ i ] = 1 + i ∗ i ;
/∗ p r i n t a r r a y ∗/
for ( i = 0; i < 10;)
p r i n t f ( "%d " , a r r a y [ i ++]);
/∗ p r i n t 6 th element ∗/
p r i n t f ( "\ nsixth element is %d\n" , a r r a y [ 5 ] ) ;
Note that the last initialization is performed without declaring the size of the
array. The compiler will make sure enough space is allocated for the array, in
this case, 3 elements. The initialization list may be smaller but not larger than
the declared array size, if one is present in the declaration.
Arrays are typically used in programs as fixed-size lists where one stores data.
Entities typically found in scientific programing are also represented as arrays,
#i n c l u d e < s t d i o . h>
#i n c l u d e <math . h>
main ( ) {
/∗ d e c l a r e v a r i a b l e s ∗/
int i ;
double x [ 3 ] = { 1 . , 3 . , − 2.};
double y [ 3 ] = { 5 . , 0 , . 2 } ;
double tmp ;
/∗ compute d i f f e r e n c e ∗/
tmp = x [ i ] − y [ i ] ;
/∗ compute a ngle ∗/
a ngle = acos ( i n n e r p r o d u c t / ( norm x ∗ norm y ) ) ;
Recall that the Euclidean norm, the standard inner product and angle between
two 3-dimensional vectors is given by the formulas:
v
u 3 3
uX
2
X hx, yi
kxk = t xi , hx, yi = xi yi, ∠x, y = arccos .
i=1 i=1
kxkkyk
5.2 Pointers
A pointer is a variable that holds the memory address of another object. If a
variable called p contains the address of another variable called q, then p is said
to point to q. As we will see in this section, understanding pointers is
fundamental to understanding arrays in C.
In order to declare a pointer variable precede it by the * operator as in
type ∗ va r ia ble na m e ;
For example:
i n t ∗p ;
double ∗q1 , ∗q2 ;
void ∗v ;
declare a pointer to an integer variable (p), two pointers to double variables (q1
and q2) and one pointer without a specific type (v).
When declared uninitialized, pointers do not hold valid memory addresses. In
order to assign the address of one existing variable to a pointer, use the
operator address-of (&). Recall that & returns the address of the variable it
precedes. This can be done at the pointer declaration or anywhere in your
program through assignment. For example:
int q ;
i n t ∗p1 ; /∗ p1 i s a p o i n t e r not i n i t i a l i z e d ∗/
i n t ∗p2 = &q ; /∗ p2 i s a p o i n t e r h o l d i n g the a ddr ess o f q ∗/
#i n c l u d e < s t d i o . h>
main ( ) {
/∗ d e c l a r e v a r i a b l e and p o i n t e r ∗/
double q , r , ∗p = &q ;
/∗ a s s i g n v a l u e to v a r i a b l e s ∗/
q = 1.34;
r = 6.78;
/∗ change v a r i a b l e v a l u e ∗/
q = − 7.89;
/∗ change v a r i a b l e v a l u e through p o i n t e r ∗/
∗p = 1 2 . 8 6 ;
/∗ change v a l u e o f p o i n t e r and v a r i a b l e r ∗/
p = &r ;
r = 5.69;
and
i n t ∗p = &q ;
whereas
i n t ∗p ;
p = &q ;
Note that the precedence and binding of * is higher than all arithmetic
operators but not higher than ++, hence *p++ increments p not *p, whereas
*p+3 adds 3 to *p.
One often needs to use sizeof when using void pointers. At the end of this
excerpt both pointers contain the exact same address:
double l [ 1 0 ] ;
double ∗ x = &l ;
v o i d ∗ v = ( v o i d ∗) &l ;
x += 2 ;
v += 2 ∗ s i z e o f ( double ) ;
In particular, they both point to the second element of the list l. Note the type
cast from (double *) to (void *).
p1 = a ;
p2 = &a [ 0 ] ;
in that both p1 and p2 point to the first element of the array a. Indeed, a itself
is a pointer and we can use equivalently pointer arithmetic or array indexing in
order to access an element of an array. For example:
i n t ∗p1 , ∗p2 ;
p1 = a + 3 ;
p2 = &a [ 2 ] ;
which will set the first element of a to 2, then copy this value to the second
element in the second statement. Finally we set the third element of the array
to 4.
Here is an example where an integer array is manipulated through pointers:
/∗ Program w5−1a . c ∗/
#i n c l u d e < s t d i o . h>
main ( ) {
/∗ d e c l a r e a r r a y ∗/
int array [ 1 0 ] , i ;
/∗ d e c l a r e p o i n t e r ∗/
i n t ∗p ;
/∗ popula t e a r r a y ∗/
f o r ( p = a r r a y , i = 0 ; i < 1 0 ; i ++)
∗( p + i ) = i + 1 ;
/∗ p r i n t a r r a y ∗/
for ( i = 0; i < 10; )
p r i n t f ( "%d " , ∗( a r r a y + i ++));
p r i n t f ( "\n" ) ;
/∗ popula t e a r r a y ∗/
f o r ( i = 10 , p = a r r a y ; p < a r r a y + 1 0 ; ∗p++ = i −−);
/∗ p r i n t a r r a y ∗/
for (p = array ; p < array + 10; )
p r i n t f ( "%d " , ∗p++);
p r i n t f ( "\n" ) ;
Note that str5 is a 13 character array rather than a 12 character array because
one extra character is allocated and initialized as the end of string character.
This is a feature of str2 being initialized as a character string using double
quotes ("). In contrast, str2 and str3 are initialized as character arrays, and
therefore their constructor behaves as a standard array constructor. Note also
that str2 and str3 will not work properly on most C-string functions that
expect an end-of-string character.
C provides several functions for reading character strings from the terminal,
such as gets and scanf with the ‘%s’ modifier. THEY ARE ALL UNSAFE
AND SHOULD NOT BE USED! The reason why they are unsafe is because
/∗ Uses a c h a r a c t e r a r r a y to p r o c e s s a s t r i n g . ∗/
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t r i n g . h>
main ( ) {
char s t r [ 8 1 ] ;
int size ;
The meaning of stdin in fgets will be clear when we study files. A couple of
details on using fgets: the newline character ‘\n’ is part of the string; the
function fgets returns a pointer to the string read; if none than it returns the
null pointer ‘NULL’. This can be used to terminate terminal input. Note that we
added the header <string.h> so as to access the library function strlen to
compute the length of the string; this is part of the standard C library so there
is no need to add any -l flag at compilation. Note also the use of the modifier
‘%s’ with printf which is used to print a null-terminated string.
The next improved version of the previous code takes care of those issues:
/∗ Program w5−5a . c ∗/
/∗ Uses a c h a r a c t e r a r r a y to p r o c e s s a s t r i n g ( b e t t e r v e r s i o n ) . ∗/
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t r i n g . h>
/∗ loop u n t i l u s e f u l s t r i n g i s i n p u t ∗/
w h i l e ( f g e t s ( s t r , BUFFER SIZE , s t d i n ) ) {
/∗ remove \n ∗/
i f ( s t r [ s i z e − 1 ] == ’\n’ )
/∗ t er m ina t e s t r i n g one c h a r a c t e r ahead ∗/
s t r [ s i z e −− − 1 ] = ’\0’ ;
i f ( size > 0 ) {
p r i n t f ( "You entered: ’%s ’\n" , s t r ) ;
p r i n t f ( "Length of string is %d\n" , s i z e ) ;
break ;
} else
p r i n t f ( "Enter a string:\n" ) ;
}
}
After one hits <ENTER> we first remove the trailing ‘\n’ and decrement the size
of the string. If the length of str is 0, the loop will keep prompting you to
enter a non-empty string.
In science and engineering analysis, we often deal with matrices. Even though
matrices can be thought as the quintessential two dimensional array, using a
two-dimensional array to represent matrices is often a bad choice and may lead
However, the inner braces are mostly cosmetic, as the compiler will perform the
exact same initialization out of
i n t s v a r [ 3 ] [ 5 ] = { 1 , 0 , 3 , −1, 3 , 4 , 9 , 6 , 0 , 8 , 7 , 4 , 9 , 1 , −10 } ;
svar [ 1 ] [ 3 ] = svar [ 2 ] [ 0 ] = 5;
will set the elements in the second row and forth column and third row and first
column of svar to 5. Recall that indexing starts at 0!
/∗ I l l u s t r a t e s two−d i m e n s i o n a l a r r a y s ∗/
#i n c l u d e < s t d i o . h>
main ( ) {
/∗ d e c l a r e v a r i a b l e s ∗/
int i , j ;
/∗ d e c l a r e two−d i m e n s i o n a l a r r a y ∗/
double a r r a y [ 3 ] [ 4 ] = { {3 , 7 , 4 , 6} ,
{−1, 2 , 8 , . 5 } ,
{0 , −3, 2 , 10} } ;
/∗ p r i n t m a t r ix ∗/
f o r ( i = 0 ; i < 3 ; i ++) {
/∗ p r i n t rows ∗/
f o r ( j = 0 ; j < 4 ; j ++)
/∗ p r i n t element i , j ∗/
p r i n t f ( "%12.4f " , a r r a y [ i ] [ j ] ) ;
/∗ end o f row ∗/
p r i n t f ( "\n" ) ;
p1 = &a r r a y [ 0 ] [ 0 ] ;
p2 = a r r a y [ 0 ] ;
p3 = ∗ a r r a y ;
/∗ I l l u s t r a t e s a r r a y s o f p o i n t e r s to i n t s ∗/
#i n c l u d e < s t d i o . h>
main ( ) {
/∗ d e c l a r e v a r i a b l e s ∗/
int i , j , n;
/∗ d e c l a r e rows ∗/
/∗ the f i r s t element i n a row i s the number o f elements to f o l l o w ∗/
i n t row1 [ ] = {3 , 7 , 4 , 6 } ;
i n t row2 [ ] = {2 , −1, 3 } ;
i n t row3 [ ] = {5 , 1 , 2 , 3 , 4 , 5 } ;
/∗ d e c l a r e a r r a y o f p o i n t e r s to hold non−r e c t a n g u l a r a r r a y ∗/
i n t ∗ a r r a y [ ] = { row1 , row2 , row3 } ;
f o r ( i = 0 ; i < 3 ; i ++) {
/∗ p r i n t row l a b e l ∗/
p r i n t f ( " Row %d:\n" , i + 1 ) ;
p r i n t f ( "\n" ) ;
The next example uses an array of pointers to hold strings of different lengths:
/∗ Program w5−7.c ∗/
/∗ I l l u s t r a t e s a r r a y s o f p o i n t e r s to s t r i n g s ∗/
#i n c l u d e < s t d i o . h>
main ( ) {
/∗ d e c l a r e v a r i a b l e s ∗/
int i ;
char ∗ messages [ ] = { "MAE 9 rocks!" ,
"How I like my tutor!" ,
"I was born to program in C." } ;
f o r ( i = 0 ; i < 3 ; i ++)
p r i n t f ( " Message %d: ’%s ’\n" , i + 1 , messages [ i ] ) ;
#i n c l u d e < s t d i o . h>
int i ;