Arrays
Introduction
• Often we need many different variables that are of the same type and play a
similar role in the program
• For example, suppose we have a temperature reading for each day of the year
and need to manipulate these values several times within a program.
• With simple variables,
– We would need to declare 365 variables.
– We would not be able to loop over these variables.
Definition
• An array is a numbered collection of variables of the same type.
• An array is a homogeneous collection of data.
• An array is a collection of similar elements i. e all are same data type.
• The variables in an array share the same name and are distinguished from one
another by their numbers or subscripts.
• We can loop through the variables of an array by using a variable for the
subscript.
• The subscripts are always 0,1,…, size-1
Array Characteristics
An array represents a group of related data.
An array has two distinct characteristics:
An array is ordered: data is grouped sequentially. In other words, here
is element 0, element 1, etc.
An array is homogenous: every value within the array must share the
same data type. In other words, an int array can only hold ints, not
doubles.
How to create an Array
Before you create an array, you need to decide on two properties:
Element type: what kind of data will your array hold? ints, double,
chars? Remember, you can only choose one type.
Array size: how many elements will your array contain?
When you initially write your program, you must pick an array size.
Your array will stay this size throughout the execution of your program.
In other words, you can change the size of an array at compile time, but
cannot change it at run-time.
Declaring Arrays
To declare regular variables we just specify a data type and a unique name: int number;
syntax
data _type array_name [array_size];
Where:
Data_ type: data type of each element in the array.
Array_Name: name of the variable you are declaring.
Array_size: number of elements allowed for this array.
[ ] : tells the compiler that we are dealing with an array.
• How to access elements of an array?
- Index is used to access the array elements
- Index must be an integer or expression evaluated to
some integer.
- The number in the brackets following the array name.
- This number specifies the elements position in the
array.
- a[8]- shows the value at the position 9 in an array a.
Store values in an array
• When an array is declared and defined
only reserves space for the elements in
the array.
• If no values are stored by default all are
initialized to garbage value.
• To store values in the array we can read it
from key board or assign values to each
individual element.
Read values through key board
main()
{
int i;
int a[5];
printf(“enter the array elements\n”);
for (i=0;i<5;i++)
scanf (“%d”, &a [i]);
printf(“ the elements in an array\n);
for (i=0;i<5;i++)
printf (“%d”, a [i]);
}//main
Initializing Arrays
You have three options for initializing your arrays.
But, first, REMEMBER THIS: Just like regular variables, arrays that have
not been initialized may contain “garbage values.”
Data_type array_name[size]= {list of values};
Option 1: If you know all the data at compile time, you can specify all your
data within brackets:
int temp [5] = {45, 47, 44, 56, 49};
Option 2: If you omit the size of your array, but specify an initial set of data,
the compiler will automatically determine the size of your array.
int temp [] = {45, 47, 44, 56};
Here, the compiler creates an array of 4 elements.
Option 3: If you do not know any data ahead of time, but you want to
initialize everything to 0, just use 0 within { }.
For example:
int temp[5] = {0};
This will initialize every element within the array to 0.
Referencing Array Elements
• Suppose we have an array, temperature, for the temperature readings for
the year.
• The subscripts would be 0,1,…,364.
• To refer to the reading for a given day, we use the name of the array with
the subscript in brackets: temperature[4] for the fifth day.
temperature
75 79 82 70 68 65 58 63 67 61
temperature[4]
• Assigning values:
• To assign the value 89 for the 150th day:
temperature[149] = 89;
• We can loop through the elements of an array by varying the subscript.
To set all of the values to 0, say
for(i=0;i<3;i++)
scanf(“%d”,&a[i]);
35 28 45
Iteration 1:
i=0 1<3 (T)
exe scanf(&a[0])
i++; // i=1
Iteration 2:
1<3 (T)
exe scanf(&a[1])
i++; // i=2
Iteration 3:
2<3 (T)
exe scanf(&a[2])
i++; //i=3
Iteration 4:
3<3 (F)
control comes out of for loop
Character array
• Char a;- it stores only one character at a time.
• To store a string (collection of characters) we
can use arrays.
• In c , character strings are treated as array of
characters (character array)
• char name[10];
where name is a character array (string)
variable that can hold a maximum of 10
characters.
Strings
• C has no native string type, instead we use arrays of char
• A special character, called a “null”, marks the end
• This may be written as ‘\0’ (zero not capital ‘o’)
• This is the only character whose ASCII value is zero
• Depending on how arrays of characters are built, we may need to add the null
by hand, or the compiler may add it for us
Example
char
char first_name[5]
first_name[5] == {{ 'J',
'J', 'o',
'o', 'h',
'h', 'n',
'n', '\0'
'\0' };
};
char
char last_name[6]
last_name[6] == "Minor";
"Minor";
char
char other[]
other[] == "Tony
"Tony Blurt";
Blurt";
char
char characters[7]
characters[7] == "No
"No null";
null";
this special case
first_name 'J' 'o' 'h' 'n' \0 specifically excludes the
null terminator
last_name 'M' 'i' 'n' 'o' 'r' \0
other 'T' 'o' 'n' 'y' 32 'B' 'l' 'u' 'r' 't' \0
number
type of element of columns
name
in of number
each slot array of rows
• They are stored in memory as
col0 col1 col2
Row0 [0][0] [0][1] [0][2]
Row1 [1][0] [1][1] [1][2]
Row2 [2][0] [2][1] [2][2]
Initializing 2D arrays
• An array may be initialized at the time of declaration:
char names[3][4] = {
{ 'J', 'o', 'h', 'n'} ,
{ 'M', 'a', 'r', 'y'} ,
• An integer array may be initialized
{ 'I', 'v', 'a', 'n'}
to all zeros as follows:
};
int nums[3][4] = {0};
• This only works for zero.
nums[0][0] = 16;
• To access an element of a 2D
printf("%d", nums[1][2]);
array, you need to specify both
the row and the column: ...
'J' 4269
Address
'J' 'o' 'h' 'n' is stored: 'o' 4270
'M' 'a' 'r' 'y' 'h' 4271
'n' 4272
'M' 4273
• Two-dimensional arrays in C are stored in "row-major format": the array is laid 'a' 4274
out contiguously, one row at a time: 'r' 4275
'y' 4276
...
• int x[2][3]={1,2,3,2,4,5};
• We can also write is as
int x[2][3]={{1,2,3},{2,4,5}};
- Each elements of row are surrounded by braces.
- Commas are required at end of the each row.
• int a[2][3]={{0,0},{1,1}};
the first two elements of the first row initialized to
zero and last element to garbage value.
the first two elements of the second row initialized
to one’s and last element to garbage value.
/* Fill 2-d array, print out values, sum the array. */
#include <stdio.h>
#define M 3 /* Number of rows */
#define N 4 /* Number of columns */
intmain(void){
int a [ M ] [ N ], i, j, sum = 0;
for ( i = 0; i < M; ++i ) /* fill the array */
for (j = 0; j < N, ++j )
a [ i ] [ j ] = i + j;
for ( i = 0; i < M; ++i ){ /* print array values */
for (j = 0; j < N, ++j )
printf(“a [ %d ] [ %d ] = %d “, i, j, a[ i ] [ j ]);
printf (“\n”);
}
for ( i = 0; i < M; ++i ) /* sum the array */
for (j = 0; j < N, ++j )
sum += a[ i ] [ j ];
printf(“\nsum = %d\n\n”);
return 0;
} Produces the output:
a[ 0 ] [ 0 ] = 0 a[ 0 ] [ 1 ] = 1 a[ 0 ] [ 2 ] = 2 a[ 0 ] [ 3 ] = 3
a[ 1 ] [ 0 ] = 1 a[ 1 ] [ 1 ] = 2 a[ 1 ] [ 2 ] = 3 a[ 1 ] [ 3 ] = 4
a[ 2 ] [ 0 ] = 0 a[ 2 ] [ 1 ] = 3 a[ 2 ] [ 2 ] = 4 a[ 2 ] [ 3 ] = 5
sum = 30
Multi Dimensional Arrays
• Array declarations read right-to-left
• int a[10][3][2];
• “an array of ten arrays of three arrays of two ints”
• In memory
3 3 3
...
2 2 2 2 2 2 2 2 2
10
Character I/O from Keyboard
To read characters from the keyboard and write to screen:
c = getchar( );
putchar(c);
• To input strings, you can use scanf() or gets().
• But it’s important to understand the difference between the two.
• scanf reads in character data until the first white space character.
– Whitespace = space, tab, or new line character.
• For example, given the following program:
scanf ("%s", name);
printf ("Hello, %s!", name);
• If I enter "Ethan Cerami", the program will print: Hello, Ethan!
• That’s because scanf reads up until the first space character.
gets()
• Gets: reads in character data until the new line character.
• For example:
gets (name);
printf ("Hello, %s!", name);
• If I enter "Ethan Cerami", the program will print: Hello, Ethan Cerami!
Functions
• Divide and conquer
– Construct a program from smaller pieces or components
– Each piece more manageable than the original program
Local Variables
main () {
char password[255];
printf ("Enter password: ");
scanf ("%s", password);
while (strcmp (password, "bluemoon") != 0) {
printf ("Access Denied. Enter Password: ");
scanf ("%s", password);
}
printf ("Welcome!");
getch();
}
Using strcat()
#include <stdio.h>
#include <string.h>
main ()
{
char opening[255] = "And, the Oscar goes to... ";
char winner[255] = "American Beauty";
strcat (opening, winner);
printf ("%s", opening);
getchar();
}
Output:
And, the Oscar goes to... American
When using strcat, be
Beauty
careful that you do not
overrun the array size. For
example, do not append a
255 char word to opening.
Using strcpy()
#include <stdio.h>
#include <string.h>
main ()
{
char word1[] = "And, the winner is....";
char word2[255];
strcpy (word2, word1);
printf ("%s", word2);
getchar();
} This copies the contents of word1 into
word2.
Output:
And, the winner is....
User-Defined Functions
Allows programmers to define special purpose functions with the same
advantages of C’s library functions. Some of the advantages of using
functions are:
• Changing the program into separate pieces
• Code reusing
• Easier modification and maintenance of the program
• More understandable program
static variables are local variables that keep their previous value when
the block is reentered. A declaration
static int cnt = 0;
will set cnt to zero the first time the function is used; thereafter, it will
retain its value from previous iterations.
•This can be useful, e.g., for debugging: you can insert code like this
anywhere without interfering with the rest of the program
•
{ /* debugging starts here */
static int cnt = 0;
printf(“*** debug: cnt = %d, v = %d\n”, ++cnt, v);
}
•The variable cnt is local to the block and won’t interfere with another
variable of the same name elsewhere in an outer block; it just increases
by one every time this block is encountered.
Storage class register
Example: {
register int i;
for (i=0; i < 100; i++)
{
.....
}
}
register is freed on block exit
global variables (defined outside functions) and all functions are of the
storage class extern and storage is permanently assigned to them
extern type variable_name;
Identifiers (i.e. variables etc.) are accessible only within the block in
which they are declared.
{
int a = 2; /* outer block a */
printf(“%d\n”, a); /* 2 is printed */
{
int a = 5; /* inner block a */
printf(“%d\n”, a); /* 5 is printed */
}
printf(“%d\n”, a); /* 2 is printed */
}
/* a no longer defined */
outer a masked
Avoid masking!
Use different identifiers instead to keep your code debuggable!
Scope rules for functions
int func (int n) int main (void)
{ {
int a = 2, b = 1, c;
printf(“%d\n”,b);
c = func(a);
return n; return 0;
} }
b not defined locally!
#include <stdio.h>
func1 () { main () {
int a, b, int x, y;
c; variables
in scope
{ {
int d,e,f; int c,d,e; down
nested
{ blocks
int g;
}
(except
} block1 } block2
for
} masking)
}
• Preprocessing
– Occurs before a program is compiled
– Inclusion of other files
– Definition of symbolic constants and macros
– Conditional compilation of program code
– Conditional execution of preprocessor directives
• Use parenthesis
– Without them the macro
#define CIRCLE_AREA( x ) PI * ( x ) * ( x )
would cause
area = CIRCLE_AREA( c + 2 );
to become
area = 3.14159 * c + 2 * c + 2;
• Multiple arguments
#define RECTANGLE_AREA( x, y ) ( ( x ) * ( y ) )
would cause
rectArea = RECTANGLE_AREA( a + 4, b + 7 );
to become
rectArea = ( ( a + 4 ) * ( b + 7 ) );
Conditional Compilation
• Conditional compilation
– Control preprocessor directives and compilation
– Cast expressions, sizeof, enumeration constants cannot
be evaluated in preprocessor directives
– Structure similar to if
#if !defined( NULL )
#define NULL 0
#endif
• Determines if symbolic constant NULL has been defined
– If NULL is defined, defined( NULL ) evaluates to
1
– If NULL is not defined, this function defines NULL to
be 0
– Every #if must end with #endif
– #ifdef short for #if defined( name )
– #ifndef short for #if !defined( name )
• #
– Causes a replacement text token to be converted to a string
surrounded by quotes
– The statement
#define HELLO( x ) printf( “Hello, ” #x “\n” );
would cause
HELLO( John )
to become
printf( “Hello, ” “John” “\n” );
– Strings separated by whitespace are concatenated when using
printf