least to the uninitiated, somewhat harder to understand.
Declarations and Usage of Arrays
The definition of an array determines its name, the type of its elements, and the number of
elements in the array. The general syntax for declaring a single-dimensional array is
type name[ number_of_elements ];
The number of elements, between square brackets ([ ]), must be an integer expression whose value
is greater than zero.
For example, the declaration,
int a[10];
defines an array of size 10, that is, a block of 10 consecutive objects named a[0], a[1], ...,a[9].
char buffer[4*512];
defines an array with the name buffer, which consists of 2,048 elements of type char.
The lower bound of an array is set at 0. C++ does not allow you to override or alter this lower
bound
Declaring a C++ array entails specifying the number of members. The number of member is
equal to the upper bound plus one
The valid range of indices extends between 0 and number_of_elements -1.
Multidimensional Arrays
A multidimensional array in C is merely an array whose elements are themselves arrays. The
elements of an n-dimensional array are (n-1)-dimensional arrays. For example, each element of a
two-dimensional array is a one-dimensional array. The elements of a one-dimensional array, of
course, do not have an array type.
A multidimensional array declaration has a pair of brackets for each dimension:
char screen[10][40][80]; // A three-dimensional array.
The array screen consists of the 10 elements screen[0] to screen[9]. Each of these elements is a
two-dimensional array, consisting in turn of 40 one-dimensional arrays of 80 characters each. All
in all, the array screen contains 32,000 elements with the type char.
Two-dimensional arrays are also called matrices. Because they are so frequently used, they merit
a closer look. It is often helpful to think of the elements of a matrix as being arranged in rows and columns. Thus the matrix mat in the following definition has three rows and five columns:
float mat[3][5];
The three elements mat[0], mat[1], and mat[2] are the rows of the matrix mat. Each of these rows
is an array of five float elements. Thus the matrix contains a total of 3 x 5 = 15 float elements, as the following diagram illustrates:
Table 2.21.
0
1
2
3
4
mat[0] 0.0 0.1 0.2 0.3 0.4
mat[1] 1.0 1.1 1.2 1.3 1.4
mat[2] 2.0 2.1 2.2 2.3 2.4
Accessing Array Elements
The subscript operator [ ] provides an easy way to address the individual elements of an array by
index. If myArray is the name of an one dimensional array and i is an integer, then the expression
myArray[i] designates the array element with the index i. Array elements are indexed beginning
with 0. Thus, if len is the number of elements in an array, the last element of the array has the
index len-1.
The following code fragment defines the array myArray and assigns a value to each element.
#define A_SIZE 4
long myarray[A_SIZE];
for (int i = 0; i < A_SIZE; ++i)
myarray[i] = 2 * i;
The diagram in Figure 2.16 illustrates the result of this assignment loop.
Figure 2.16.
Values assigned to elements by index
To access a char element in the three-dimensional array screen, you must specify three indices.
For example, the following statement writes the character Z in a char element of the array:
screen[9][39][79] = 'Z';
Initializing Arrays
If you do not explicitly initialize an array variable, the usual rules apply: if the array has
automatic storage duration, then its elements have undefined values. Otherwise, all elements are
initialized by default to the value 0.
You cannot include an initialization in the definition of a variable-length array.
If the array has static storage duration, then the array initializers must be constant expressions.
If the array has automatic storage duration, then you can use variables in its initializers.
You may omit the length of the array in its definition if you supply an initialization list. The
array's length is then determined by the index of the last array element for which the list
contains an initializer. For example, the definition of the array a in the previous example is
equivalent to this:
int a[ ] = { 1, 2, 4, 8 }; // An array with four elements.
If the definition of an array contains both a length specification and an initialization list, then
the length is that specified by the expression between the square brackets. Any elements for
which there is no initializer in the list are initialized to zero (or NULL, for pointers). If the list contains more initializers than the array has elements, the superfluous initializers are simply
ignored.
A superfluous comma after the last initializer is also ignored.
As a result of these rules, all of the following definitions are equivalent:
int a[4] = {1, 2};
int a[ ] = {1, 2, 0, 0};
int a[ ] = {1, 2, 0, 0, };
int a[4] = {1, 2, 0, 0, 5};
Operations on arrays
Read the elements of a 1-dimensional array:
float a[10]; // declare a float array of size 10
int i;
// read the second element of the array : a[1]
scanf(“%f”,&a[1]);
// Assign an expression to the third element of the array
a[2] = a[1] + 5;
To read the value for each element of an array, you should use for statement. For example,
int b[10];
int i;
// Read the value for each element of the array
for(i = 0; i < 10; i++)
{
printf(“\n Enter the value of b[%d]”, i);
scanf(“%d”,&b[i]);
}
In case you do not now the exact number of elements, declare the maximum number of elements
and use a variable to store the actual size of the array
int a[100]; // Declare the array with the number of elements not greater than 100
int n; // n is the actual size of the array
int i;
printf(“\n Enter the number of elements: “);
scanf(“%d”,&n);
for(i = 0; i < n; i++)
{
printf("\n a[%d] = ", i);
scanf("%d",&a[i]);
}
C allow you to associate initializers with specific elements . To specify a certain element to
initialize, place its index in square brackets. In other words, the general form of an element
designator for array elements is:
int a[4] = {4, 9, 22, 16};
float b[3] = {40.5, 20.1, 100};
char c[5] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’};
The first statement is equivalent to four assign statements
a[0] = 4; a[1] = 9; a[2] = 22; a[3] = 16;
Printing array elements
printf function are used to print the element of an array. In the following example, we print the
element of array a in different ways
#include <stdio.h>
#include <conio.h>
void main()
{
int a[5];
int i, k;
// Read the elements of the array
for(i = 0; i < 5; i++)
{
printf(“\n a[%d] = “, i);
scanf(“%d”, &a[i]);
}
// print the value of element a[3]
printf(“\n a[3] = %d”, a[3]);
// Display all the elements of array a, each element in a line.
for(i = 0; i < 5; i++)
printf(“\n%d”, a[i]);
// Display all the elements of array a in a line
printf(“\n”); // change to a new line
for(i = 0; i < 5; i++)
printf(“%d “, a[i]);
// Display all the elements of array a, k elements in a line
printf(“\n Enter the value of k = “);
scanf(“%d”,&k);
for(i = 0; i < 5; i++)
{
printf(“%d “,a[i]);
if((i+1)%k == 0) // change to a new line after printing k
//elements
printf(“\n”);
}
getch();
}
here is the sample session with the above program
a[0] = 6
a[1] = 14
a[2] = 23
a[3] = 37
a[4] = 9
a[3] = 37
6
14
23
37
9
6 14 23 37 9
Input the value of k = 2
6 14
23 37
9
Find the maximum value stored in the array.
The purpose of this function is to find the maximum value stored in the array
Set up a trial minimum value. The function begins by declaring a variable named min and
initializing that variable with a trial minimum value – value of the first element .
Then the function uses a while loop to:
Fetch the value stored in each element in the array
Compare each of those values with the current value stored in the variable named max
Possibly replace if the value fetched from an element is algebraically greater than the current
value stored in max:
The value fetched from the element is stored in the variable named max
Replacing the value that was previously stored in the variable named max by the new value
from the element.
When all of the array elements have been examined and processed in this manner, the variable
named max will contain the maximum value of all the values stored in the array.
int a[100];
int i, n;
int max;
printf("\n Enter the size of the array: ");
scanf("%d",&n);
// Read the number of elements of the array
for(i = 0; i < n; i++)
{
printf("\n a[%d] = ",i);
scanf("%d",&a[i]);
}
// Find the maximum element
max = a[0]; // max is initialized by a[0]
// compare max to other elements
for(i = 1; i < n; i++)
if(max < a[i]) //meet an element greater than max
max = a[i]; // replace max by the new value from the elements.
printf("\n The maximum element of the array is: %d", max);
Searching
The simplest type of searching process is the sequential search. In the sequential search, each
element of the array is compared to the key, in the order it appears in the array, until the first
element matching the key is found. If you are looking for an element that is near the front of the
array, the sequential search will find it quickly. The more data that must be searched, the longer it will take to find the data that matches the key using this process.
here is the sample session with the above program
#include <stdio.h>
#include <conio.h>
void main()
{
int m[100], idx[100];
int n; // n is the actual size of the array
int i, k, test;
clrscr(); // clear screen
// Read array m
// Read the actual size of m
printf(“ Enter the number of elements
scanf(“%d”,&n);
// Read array’s elements
for(i = 0;i<n;i++)
{
int temp;
printf(“\n Enter the value of m[%d] = “,i);
scanf(“%d”,&temp);
m[i] = temp;
}
// Read the searching key k
printf(“\n Enter the value you want to search : “);
scanf(“%d”,&k);
// Begin searching
test = 0;
// Scan all the elements
for(i = 0;i<n;i++)
if(m[i] = = k)//Compare the current element with the
//searching key k
{
// save the index of the current element
idx[test] = i;
test ++;
}
// Conclusion
if(test > 0)
{
printf(“\n there are %d elements which has the value of %d”,test,k);
printf(“\n Indexes of those elements: “);
for(i = 0;i < test;i++)
printf(“%3d”,idx[i]);
}
else
printf(“\n No element has the value %d”,k);
getch(); // Wait until the user press any key
}
Sorting
Selection sort is a sorting algorithm, specifically an in-place comparison sort. Selection sort is
noted for its simplicity, and also has performance advantages over more complicated algorithms
in certain situations. It works as follows:
Find the minimum value in the list
Swap it with the value in the first position
Repeat the steps above for remainder of the list (starting at the second position)
Effectively, we divide the list into two parts: the sublist of items already sorted, which we build
up from left to right and is found at the beginning, and the sublist of items remaining to be sorted, occupying the remainder of the array.
Here is an example of this sort algorithm sorting five elements:
31 25 12 22 11
11 25 12 22 31
11 12 25 22 31
11 12 22 25 31
#include <stdio.h>
#include <conio.h>
void main()
{
int m[100];//100 is the maximum size for array m
int n; // n is the number of elements int i, j, k;
clrscr(); // clear screen
// Read the elements of array m
// Read the actual size of the array
printf(“ Enter the number of elements: “);
scanf(“%d”,&n);
// Read array elements
for(i = 0;i<n;i++)
{
int temp;
printf(“\n Enter the value of m[%d] = “,i);
scanf(“%d”,&temp);
m[i] = temp;
}
// Print the array
printf(“\n The array before sorting: “);
for(i=0;i<n;i++)
printf(“%3d”,m[i]);
// Begin to sort
for(i = 0; i<n-1;i++)
{
// Put the minimum value in the list of n-i elements
//to the ith position
for(j = i+1;j<n;j++)
{
// compare m[i] with other element of the sublist
// and swap m[i] and m[j] if m[j] < m[i].
if(m[j]<m[i])
{
int temp;
temp = m[j]; m[j] = m[i]; m[i] = temp;
}
}
// Print the array after the i+1 th step of sorting process
printf(“\n The array after step %d”,i+1);
for(k = 0;k < n ;k++)
printf(“%3d”,m[k]);
}
getch(); // Wait until the user press any key.
}
here is the sample session with the above program
Enter the number of elements: : 5
Enter the value of m[0]: 34
Enter the value of m[1]: 20
Enter the value of m[2]: 17
Enter the value of m[3]: 65
Enter the value of m[4]: 21
The array before sorting: 34 20 17 65 21
The array after step 1: 17 34 20 65 21
The array after step 2: 17 20 34 65 21
The array after step 3: 17 20 21 65 34
The array after step 4: 17 20 21 34 65
Pointers vs Arrays
Pointers occur in many C programs as references to arrays , and also as elements of arrays. A
pointer to an array type is called an array pointer for short, and an array whose elements are
pointers is called a pointer array.
Array Pointers
For the sake of example, the following description deals with an array of int. The same principles
apply for any other array type, including multidimensional arrays.
To declare a pointer to an array type, you must use parentheses, as the following example
illustrates:
int (* arrPtr)[10] = NULL; // A pointer to an array of
// ten elements with type int.
Without the parentheses, the declaration int * arrPtr[10]; would define arrPtr as an array of 10
pointers to int. Arrays of pointers are described in the next section.
In the example, the pointer to an array of 10 int elements is initialized with NULL. However, if we
assign it the address of an appropriate array, then the expression *arrPtr yields the array, and
(*arrPtr)[i] yields the array element with the index i. According to the rules for the subscript
operator, the expression (*arrPtr)[i] is equivalent to *((*arrPtr)+i). Hence **arrPtr yields the first element of the array, with the index 0.
In order to demonstrate a few operations with the array pointer arrPtr, the following example uses
it to address some elements of a two-dimensional array that is, some rows of a matrix:
int matrix[3][10]; // Array of three rows, each with 10 columns.
// The array name is a pointer to the first
// element; i.e., the first row.
arrPtr = matrix; // Let arrPtr point to the first row of
// the matrix.
(*arrPtr)[0] = 5; // Assign the value 5 to the first element of the
// first row.
//
arrPtr[2][9] = 6; // Assign the value 6 to the last element of the
// last row.
//
++arrPtr; // Advance the pointer to the next row.
(*arrPtr)[0] = 7; // Assign the value 7 to the first element of the
// second row.
After the initial assignment, arrPtr points to the first row of the matrix, just as the array name
matrix does. At this point you can use arrPtr in the same way as matrix to access the elements. For
example, the assignment (*arrPtr)[0] = 5 is equivalent to arrPtr[0][0] = 5 or matrix[0][0] = 5.
However, unlike the array name matrix, the pointer name arrPtr does not represent a constant
address, as the operation ++arrPtr shows. The increment operation increases the address stored in
an array pointer by the size of one array in this case, one row of the matrix, or ten times the
number of bytes in an int element.
If you want to pass a multidimensional array to a function, you must declare the corresponding
function parameter as a pointer to an array type.
One more word of caution: if a is an array of ten int elements, then you cannot make the pointer
from the previous example, arrPtr, point to the array a by this assignment:
arrPtr = a; // Error: mismatched pointer types.
The reason is that an array name, such as a, is implicitly converted into a pointer to the array's
first element, not a pointer to the whole array. The pointer to int is not implicitly converted into a pointer to an array of int. The assignment in the example requires an explicit type conversion,
specifying the target type int (*)[10] in the cast operator:
arrPtr = (int (*)[10])a; // OK
You can derive this notation for the array pointer type from the declaration of arrPtr by removing
the identifier. However, for more readable and more flexible code, it is a good idea to define a
simpler name for the type using typedef:
typedef int ARRAY_t[10]; // A type name for "array of ten int elements".
ARRAY_t a, // An array of this type,
*arrPtr; // and a pointer to this array type.
arrPtr = (ARRAY_t *)a; // Let arrPtr point to a.
Pointer Arrays
Pointer arrays that is, arrays whose elements have a pointer type are often a handy alternative to
two-dimensional arrays. Usually the pointers in such an array point to dynamically allocated
memory blocks.
For example, if you need to process strings, you could store them in a two-dimensional array
whose row size is large enough to hold the longest string that can occur:
#define ARRAY_LEN 100
#define STRLEN_MAX 256
char myStrings[ARRAY_LEN][STRLEN_MAX] =
{ // Several corollaries of Murphy's Law:
"If anything can go wrong, it will.",
"Nothing is foolproof, because fools are so ingenious.",
"Every solution breeds new problems."
};
However, this technique wastes memory, as only a small fraction of the 25,600 bytes devoted to
the array is actually used. For one thing, a short string leaves most of a row empty; for another,
memory is reserved for whole rows that may never be used. A simple solution in such cases is to
use an array of pointers that reference the objects in this case, the strings and to allocate memory only for the pointer array and for objects that actually exist. Unused array elements are null
pointers.
#define ARRAY_LEN 100
char *myStrPtr[ARRAY_LEN] = // Array of pointers to char
{ // Several corollaries of Murphy's Law:
"If anything can go wrong, it will.",
"Nothing is foolproof, because fools are so ingenious.",
"Every solution breeds new problems."
};
Figure 2.17.
Pointer array
The diagram in illustrates how the objects are stored in memory. The pointers not yet used can be
made to point to other strings at runtime. The necessary storage can be reserved dynamically in
the usual way. The memory can also be released when it is no longer needed.
2.5. Functions*
Basic of C functions
Functions break large computing tasks into smaller ones, and enable people to build on what
others have done instead of starting over from scratch. Appropriate functions hide details of
operation from parts of the program that don't need to know about them, thus clarifying the whole,
and easing the pain of making changes.
C has been designed to make functions efficient and easy to use; C programs generally consist of
many small functions rather than a few big ones. A program may reside in one or more source
files. Source files may be compiled separately and loaded together, along with previously
compiled functions from libraries. We will not go into that process here, however, since the
details vary from system to system.
Function declaration and definition is the area where the ANSI standard has made the most
changes to C. It is now possible to declare the type of arguments when a function is declared. The
syntax of function declaration also changes, so that declarations and definitions match. This
makes it possible for a compiler to detect many more errors than it could before. Furthermore,
when arguments are properly declared, appropriate type coercions are performed automatically.
Every function is defined exactly once. A program can declare and call a function as many times
as necessary.
Declaration and Usage of Function
Function Declarations
The definition of a function consists of a function head (or the declarator) and a function block .
The function head specifies the name of the function, the type of its return value, and the types
and names of its parameters, if any. The statements in the function block specify what the function
does. The general form of a function definition is as follows:
//function head
type function-name(parameter declarations)
//function block
{
declarations and statements
}
In the function head, name is the function's name, while type (return-type) consists of at least one type specifier, which defines the type of the function's return value. The return type may be void
or any object type, except array types. Furthermore, type may include the function specifier inline, and/or one of the storage class specifiers extern and static.
A function cannot return a function or an array. However, you can define a function that returns a
pointer to a function or a pointer to an array.
The parameterdeclarations are contained in a comma-separated list of declarations of the
function's parameters. If the function has no parameters, this list is either empty or contains
merely the word void.