The concept of an array is common to most programming languages. In an array, multiple values of the same data type can be stored with one variable name. The use of arrays allows for the development of smaller and more clearly readable programs.
Arrays are classified as aggregate data types. Unlike atomic data types which cannot be subdivied, aggregate data types are composed of one or more elements of an atomic or another aggregate data type. Simply put aggregate data types can be subdivided or broken down. To access individual elements of an array a subscript must be used. The subscript identifies the sub-element or component of the array that is to be accessed. Subscripts must start at 0 and proceed in increments of 1. Arrays can be of any data type supported by C, including constructed data types and arrays can be of any storage class except ‘register’.
Arrays can be declared as local variables or global variables. Initialization of an array when it is declared is allowed for both locally and globally declared arrays. Initializing an array when it is declared does not require the presence of a dimension on the array
char name[] = "John Smith";
int age[] = {21,32,43,22,25};
main()
{
.
.
.
}
OR
main()
{
int age[] = {21,32,43,22,25};
.
.
.
}
If an array is declared to hold ten elements, the subscripts start at 0 and the highest subscript allowed for that array is 9. There is no bounds checking on arrays. It is the programmers responsibility to keep the subscript within the bounds of the array. On the above array age, which has five elements if a statement such as
age[6] = 10;
is made in the program, no error or warning will be generated by the compiler. The array age should only support subscripts ranging from 0 to 5. A subscript of 6 is not within the bounds of the array, but C/C++ will allow the statement. In most cases the program will terminate with a runtime error because of the above statement.
Two and three dimensional arrays are allowed but actually there is no limit on the number of dimensions for an array.
int aver[10][20];
float sales[50][10][2];
Values in a multi-dimensional array are stored in row-major order, meaning that if array is declared as
int data[3][4];
the values are stored in memory in this order
[0][0] [0][1] [0][2] [0][3] [1][0] [1][1] [1][2] [1][3] ...
and so forth. Therefore, when initializing a multi-dimensional array at declaration time, the row designator does not have to be stated, but the column length must be stated, such as:
float monthlySalesByProduct[][4] =
{ {100.50, 234.32, 987.98}
, {324.56, 123.43, 876.83}
, {765.23, 8743.28, 27388.87}
...
};
Notice the use of nested {...} pairs to set off the column values for a row. This is required in order to delineate the boundaries of the rows. The two-dimensional array above can also be called a square array. A square array can be used to store arrays of strings.
#include <iostream.h>
int main()
{
char students[10][25]; // holds names of students
int idx;
for( idx = 0; idx < 10; ++idx )
{
cout << "Enter a students first name: ";
cin >> students[idx];
}
cout << "\nThe students in the class are:" << endl;
for( idx = 0; idx < 10; ++idx )
cout << students[idx] << endl;
return 0;
}
Notice the used of students[i] in the above example. The name of each row in the multi-dimensional array is the name of an array, which means that it represents the beginning address of where data is stored. You can use the name of a row the same as you would the name of an array. Also, notice that no matter how short the name of the student is, the same number of characters is allocated for each row, therefore leading to excessing use of memory space.
Arrays are automatically passed by reference to a function. The name of an array is the beginning address of where the array data is stored in memory; also known as a ‘pointer constant’.
#include <iostream.h>
int main()
{
int list[10]
,max = 10
,indx = 0
,largest
,num_ele
;
int find_max( int [], int );
while( indx < max)
{
cout << "\nEnter a number: ";
cin >> list[indx];
++indx;
}
largest = find_max( list, max );
cout << "\nLargest number is " << largest << endl;
return 0;
}
int find_max( int list2[], int size )
{
int
idx
,highest
;
for(highest = list2[0],idx = 1; idx < size; ++idx)
if(highest < list2[idx])
highest = list2[idx];
return(highest);
}
In the find_max() function, list2[] is an array of undetermined length. On the call to find_max() the argument list is stated without subscripts, this passes the address of list, because list is an array. The name of an array is a pointer constant that represents the beginning address of the array. Therefore, when list is stated in the call to find_max(), the address that list represents is actually passed to the function. The receiving argument list2[] only receives the address of where the array begins in memory. With the array notation used for the receiving argument, list2[] can be treated as if it is an alias that allows for the direct manipulation of the data stored in list. Multi Dimensional arrays as arguments follow the same syntax except that on the receiving side the last dimension must be stated. This is so the compiler knows where one row of data ends and another row begins.
#include <iostream.h>
#define ROWS 10
#define COLUMNS 2
int main()
{
float agents[ROWS][COLUMNS];
int indx = 0;
int maxex( float [][COLUMNS], int );
cout << "\nEnter 3-digit agent"
<< " number then travel "
<< "expenses(001 1642.50)";
do
{
cout << "\nAgents # and expenses:";
cin >> agents[indx][0]
>> agents[indx][1]);
}while( agents[indx++][0] != 0 );
indx--;
indx = maxex(agents,indx);
cout << "\nAgent with highest expenses: "
<< agents[indx][0];
cout << " Amount: %.2f"
<< agents[indx][1];
return 0;
}
int maxex(float list[][COLUMNS],int size)
{
int
idx
,maxidx
;
float
max
;
max = list[0][1];
maxidx = 0;
for(idx = 1; idx < list[idx][1])
{
max = list[idx][1];
maxidx = idx;
}
return(maxidx);
}
An array of type char ending with a NULL (‘000’) character is called a string in C.
memory value
address at address
2000 J
2001 o
2002 h
2003 n
2004
2005 S
2006 m
2007 i
2008 t
2009 h
200A \0
An array that will be used as a string must be declared with one additional byte more than is needed for data. This allots space for the NULL byte which is the signal indicating the end of the string.
//
// looks at string in memory
//
#include <iostream.h>
#include <stdio.h>
#include <string.h>
int main()
{
char name[81];
int indx;
cout << "\nEnter your name: ";
gets(name); // used because of whitespace input
cout << "\nThe string " << name
<< " is stored at address "
<< hex << unsigned(name);
for(indx=0; indx < strlen(name); ++indx)
{
cout << "\nADDR: " << hex << unsigned(name);
cout << " CHAR: " << name[indx];
cout << " DEC: " << dec << int(name[indx]);
}
return 0;
}
Strings must be manipulated with standard functions supplied with the compiler function libraries.
**char *strcat(char *str1, char *str2);**
Appends str2 to str1, terminates the resulting string with a NULL character and returns the address of the concatenated string, str1.
**char *strchr(char *str, char c);**
Returns the address of the first occurrence of c in str; the function returns NULL if the character is not found.
**int strcmp(char *str1, char *str2);**
Compares str1 and str2 lexicographically and returns a value indicating their relationship.
Value Meaning
< 0 str1 less than str2
0 str1 equal to str2
> 0 str1 greater than str2
**int strcmpi(char *str1, char *str2);**
Case-insensitive version of strcmp. Strings are compared without regard to case.
**char *strcpy(char *str1, char *str2);**
Copies str2, including the null terminating character to location specified by str1 and returns str1.
**int strcspn(char *str1, char *str2);**
Returns the index of the first character in str1 that belongs to the set of characters specified by str2.
**char *strdup(char *str);**
Allocates storage space for a copy of str and returns the address to that storage space containing the copied string. Returns NULL if storage could not be found.
**int strlen(char *str);**
Returns the length in bytes of str not including the termininating null character.
**char *strlwr(char *str);**
Converts any uppercase letters in the given null terminated string to lowercase.
**char *strncat(char *str1, char *str2, int n);**
Appends at most the first n characters of str2 to str1, terminates the resulting string with a null character and returns the address of the concatenated str1.
**int strncmp(char *str1, char *str2, int n);**
Compares at most the first n characters of str1 and str2 lexicographically and returns a value indicating the relationship between the substrings.
Value Meaning
< 0 substring1 < substring2
0 substring1 = substring2
> 0 substring1 > substring2
**char *strncpy(char *str1, char * str2, int n);**
Copies exactly n characters of str2 to str1 and returns str1.
**char *strnset(char *str, char c, int n);**
Sets at most the first n characters of str to the character c and returns the address of the altered str.
**char *strtok( char *str, char *delims );**
Searches one string for tokens, which are separated by delimiters defined in a second string.
#include <string.h>
#include <stdio.h>
int main()
{
char input[16] = "abc,d";
char *p;
/*
* strtok places a NULL terminator
* in front of the token, if found
*/
p = strtok( input, "," );
if( p )
printf( "%s\n", p);
/*
* a second call to strtok using a
* NULL as the first parameter returns
* a pointer to the character following
* the token
*/
p = strtok( NULL, "," );
if( p )
printf("%s\n", p );
return 0;
}