It is also possible to represent multidimensional array in terms of a pointer as with the case of one dimensional array.A two-dimensional array is actually a collection of one-dimensional array.Therefore, a two-dimensional array can be defined as a pointer to a group of contiguous one dimensional arrays.Thus, a two-dimensional array declaration can be written as
data-type (*ptvar)[expression 2];
rather than
data-type array[expression 1][expression 2];
This concept can be generalized to higher dimensional arrays; that is,
data-type (*ptvar)[expression 2][expression 3].........[expression n];
replaces
data-type array[expression 1][expression 2]...........[expression n];
In the declaration data-type refers to the data type of the array, ptvar is the name of the pointer variable, array is the corresponding array name, and expression 1, expression 2,...........,expression n are positive-valued integer expression that indicate the maximum number of array elements associated with each subscript.
Suppose x is a two-dimensional integer array having 10 rows and 20 columns.We can declare x as
int (*x)[20];
rather than
int x[10][20];
In the first declaration, x is defined to be a pointer to a group of contiguous, one-dimensional, 20-element integer arrays.Thus, x points to the first 20-element array, which is actually the first row (i.e. row 0) of the original two-dimensional array. Similarly, (x+1)point to second 20-element array, which is the second row (row 1) of the two-dimensional array, and so on.
Now consider a three-dimensional floating point array t.This array can be defined as
float (*t)[20][30];
rather than
float[10][20][30];
Thursday, December 31, 2009
8.6 OPERATIONS ON POINTERS
In section 8.4 we have seen that an integer value added to an array name in order to access an individual array element is interpreted as an array subscript;it points to the location of the array element relative to the first element in the array.
In the program shown below, the first and last elements of an integer array are pointed by two different pointer variables.
Execution of the program results in the following output
The first line indicates that addresses of a[0] and a[5] are 52 and 5C respectively.The difference between these two hexadecimal numbers is 10 (converted to decimal).
The permissible operations on pointers are summarized below:
1. The address of an ordinary variable can be assigned to a pointer variable (e.g, pv=&v).
2. The value of a pointer variable can be assigned to another pointer vatiable (e.g., pv=px) provided both pointers point to objects of the same data type.
3. A null (zero) value can be assigned to a pointer variable (e.g., pv=NULL, NULL--->symbolic constant that represent the value 0).
4. An integer quantity can be added or subtracted from a pointer variable (e.g., pv+3, ++pv etc.).
5. One pointer variable can be subtracted from another provided both pointers point to the elements of the same array.
6. Two pointer variables pointing to objects of the same data type can be compared.
Other arithmetic operations on pointers are not allowed.Thus, a pointer variable cannot be multiplied by a constant;two pointer variables cannot be added and so on.
In the program shown below, the first and last elements of an integer array are pointed by two different pointer variables.
#include < stdio.h >
main()
{
int *px, *py; /*integer pointers*/
static int a[6] = {1, 2, 3, 4, 5, 6};
px = &a[0];
py = &a[5];
printf("px=%X py=%X", px, py);
printf("\n\npy - px=%X ", py-px);
}
Execution of the program results in the following output
px=52 py=5C
py - px=5
The first line indicates that addresses of a[0] and a[5] are 52 and 5C respectively.The difference between these two hexadecimal numbers is 10 (converted to decimal).
The permissible operations on pointers are summarized below:
1. The address of an ordinary variable can be assigned to a pointer variable (e.g, pv=&v).
2. The value of a pointer variable can be assigned to another pointer vatiable (e.g., pv=px) provided both pointers point to objects of the same data type.
3. A null (zero) value can be assigned to a pointer variable (e.g., pv=NULL, NULL--->symbolic constant that represent the value 0).
4. An integer quantity can be added or subtracted from a pointer variable (e.g., pv+3, ++pv etc.).
5. One pointer variable can be subtracted from another provided both pointers point to the elements of the same array.
6. Two pointer variables pointing to objects of the same data type can be compared.
Other arithmetic operations on pointers are not allowed.Thus, a pointer variable cannot be multiplied by a constant;two pointer variables cannot be added and so on.
Wednesday, December 30, 2009
8.5 DYNAMIC MEMORY ALLOCATION
Since an array name is actually a pointer to the first element within the array, it should be possible to define the array as a pointer variable rather than as a conventional array.For conventional array definition, a fixed block of memory is reserved at the beginning of program execution, but this does not occur in case of array represented in terms of pointer variable.Therefore, in order to represent an array, the use of a pointer variable requires some type of initial memory assignment before the array elements are processed.This is known as dynamic memory allocation. Generally, the malloc library function is used for this purpose.
Let us write a C program to illustrate the use of dynamic memory allocation.
/*reorder a one-dimensional, integer array from smallest to largest, using pointer notation*/
#include < stdio.h >
#include < stdlib.h >
void reorder (int n, int *x);
main()
{
int i, n, *x;
/*read in a value for n*/
printf("How many numbers will be entered? ");
scanf("%d", &n);
printf("\n");
/*allocate memory*/
x = (int *) malloc(n * sizeof(int));
/*read in the list of numbers*/
for (i =0;i < n;++i) {
printf("i = %d x = ", i+1);
scanf("%d", x+i);
}
/*reorder all array elements*/
reorder(n, x);
/*display the reordered list of numbers*/
printf("\n\nReordered list of numbers: \n\n");
for (i =0;i < n;++i)
printf("i = %d x = %d\n", i+1, *(x+i));
}
void reorder (int n, int *x) /*rearrange the list of numbers*/
{
int i, item, temp;
for (item=0; item < n-1; ++item)
/*find the smallest of all remaining elements*/
for (i = item+1; i < n; ++i)
if (*(x+i) < *(x+item)) {
/*interchange two elements*/
temp = *(x+ item);
*(x+ item) = *(x+ i);
*(x+ i) = temp;
}
return;
}
In this program, the integer array is defined as a pointer to a integer. The malloc library function is used to assign memory to the pointer variable.
We can also see that the scanf function specifies the address of ith element as x+i rather than x[i].
Within the function reorder,we can see that the second formal argument is now defined as a pointer variable rather than an integer array.In the if statement, we can see that x[i] is written as *(x+i), and x[item] as *(x+ item)
An advantage of dynamic memory allocation is that it is able to reserve as much as memory required during program execution, and then release the memory when it is no longer needed.
Let us write a C program to illustrate the use of dynamic memory allocation.
/*reorder a one-dimensional, integer array from smallest to largest, using pointer notation*/
#include < stdio.h >
#include < stdlib.h >
void reorder (int n, int *x);
main()
{
int i, n, *x;
/*read in a value for n*/
printf("How many numbers will be entered? ");
scanf("%d", &n);
printf("\n");
/*allocate memory*/
x = (int *) malloc(n * sizeof(int));
/*read in the list of numbers*/
for (i =0;i < n;++i) {
printf("i = %d x = ", i+1);
scanf("%d", x+i);
}
/*reorder all array elements*/
reorder(n, x);
/*display the reordered list of numbers*/
printf("\n\nReordered list of numbers: \n\n");
for (i =0;i < n;++i)
printf("i = %d x = %d\n", i+1, *(x+i));
}
void reorder (int n, int *x) /*rearrange the list of numbers*/
{
int i, item, temp;
for (item=0; item < n-1; ++item)
/*find the smallest of all remaining elements*/
for (i = item+1; i < n; ++i)
if (*(x+i) < *(x+item)) {
/*interchange two elements*/
temp = *(x+ item);
*(x+ item) = *(x+ i);
*(x+ i) = temp;
}
return;
}
In this program, the integer array is defined as a pointer to a integer. The malloc library function is used to assign memory to the pointer variable.
We can also see that the scanf function specifies the address of ith element as x+i rather than x[i].
Within the function reorder,we can see that the second formal argument is now defined as a pointer variable rather than an integer array.In the if statement, we can see that x[i] is written as *(x+i), and x[item] as *(x+ item)
An advantage of dynamic memory allocation is that it is able to reserve as much as memory required during program execution, and then release the memory when it is no longer needed.
Tuesday, December 29, 2009
8.4 POINTERS AND ONE DIMENSIONAL ARRAYS
An array name is really a pointer to the first element in the array. Therefore, if x is one dimensional array, then the address of the first array element can be expressed as either &x[0] or simply as x. Moreover, the address of second array element can be written as either &x[1] or as (x+1), and so on.
Since &x[i] and (x+i) both represent the address of the ith element of x, it would seem reasonable that x[i] and *(x+i) both represent the content of the address i.e., the value of the ith element of x.
Here is a simple C program that illustrates the relationship between array elements and their addresses.
Execution of the program results in the following output.
Since &x[i] and (x+i) both represent the address of the ith element of x, it would seem reasonable that x[i] and *(x+i) both represent the content of the address i.e., the value of the ith element of x.
Here is a simple C program that illustrates the relationship between array elements and their addresses.
#include < stdio.h >
main()
{
static int x[10] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
int i;
for (i = 0;i <= 9; ++i) {
/*display an array element*/
printf("\ni= %d x[i]= %d *(x+i)= %d", i, x[i], *(x+i));
/*display the corresponding array address*/
printf(" &x[i]= %X x+i= %X", &x[i], (x+i));
}
}
Execution of the program results in the following output.
i=0 x[i]=10 *(x+i)=10 &x[i]=72 x+i =72
i=1 x[i]=11 *(x+i)=10 &x[i]=74 x+i =74
i=2 x[i]=12 *(x+i)=10 &x[i]=76 x+i =76
i=3 x[i]=13 *(x+i)=10 &x[i]=78 x+i =78
i=4 x[i]=14 *(x+i)=10 &x[i]=7A x+i =7A
i=5 x[i]=15 *(x+i)=10 &x[i]=7C x+i =7C
i=6 x[i]=16 *(x+i)=10 &x[i]=7E x+i =7E
i=7 x[i]=17 *(x+i)=10 &x[i]=80 x+i =80
i=8 x[i]=18 *(x+i)=10 &x[i]=82 x+i =82
i=9 x[i]=19 *(x+i)=10 &x[i]=84 x+i =84
8.3 PASSING POINTERS TO A FUNCTION
Pointers are often passed to a function as arguments.This allows data items within the calling portion of the program to be accessed by the function, altered within the function, and then returned to the calling portion of the program in the altered form.We refer to this use of pointers as passing arguments by reference (or by address or by location).
While using pointers as arguments to a function, some care is required with the formal argument declarations within the function. Specifically, formal pointer arguments that must be preceded by asterisk.Function prototypes are written in the same manner. If a function declaration does not include variable names, the data type of each pointer argument must be followed by an asterisk.
The difference between ordinary arguments, which are passed by value, and pointer arguments, which are passed by reference is illustrated with the help of the following C program.
After execution of the program, the following output is generated;
While using pointers as arguments to a function, some care is required with the formal argument declarations within the function. Specifically, formal pointer arguments that must be preceded by asterisk.Function prototypes are written in the same manner. If a function declaration does not include variable names, the data type of each pointer argument must be followed by an asterisk.
The difference between ordinary arguments, which are passed by value, and pointer arguments, which are passed by reference is illustrated with the help of the following C program.
#include < stdio.h >
void funct1 (int u, int v); /*function prototype*/
void funct2 (int *pu, int *pv); /*function prototype*/
main()
{
int u = 1, v = 3;
printf("\nBefore calling funct1: u=%d v=%d", u, v);
funct1(u, v);
printf ("\nAfter calling funct1: u=%d v=%d", u, v);
printf ("\n\nBefore calling funct2: u=%d v=%d", u, v);
funct2(&u, &v);
printf ("\nAfter calling funct2: u=%d v=%d", u, v);
}
void funct1 (int u, int v)
{
u = 0;
v = 0;
printf ("\nwithin funct1: u=%d v=%d", u, v);
return;
}
void funct2 (int *pu, int *pv);
{
*pu = 0;
*pv = 0;
printf ("\nwithin funct2: *pu=%d *pv=%d", *pu, *pv);
return;
}
After execution of the program, the following output is generated;
Before calling funct1: u=1 v=3
within funct1: u=0 v=0
After calling funct1: u=1 v=3
Before calling funct2: u=1 v=3
within funct2: *pu=0 *pv=0
After calling funct2: u=0 v=0
Notice the values of u and v are unchanged within main after the call to funct1, though the values of these variables are changed within main after the call of funct2.
Monday, December 28, 2009
8.2 POINTER DECLARATIONS
Pointer variables, like all other variables, must be declared before they may be used in a C program. The interpretation of a pointer declaration differs, however, from the interpretation of other variable declarations. When a pointer variable is declared, the variable name must be preceded by an asterisk (*). The data type that appears in the declaration refers to the object of the pointer,i.e., the data item that is stored in the address represented by the pointer, rather than the pointer itself.
Thus, a pointer declaration may be written in general terms as
data-type *ptvar;
where ptvar is the name of the pointer variable, and data-type refers to the data type of the pointer's object. Remember that an asterisk must precede ptvar.
A C program contains the following declarations.
float u, v;
float *pv;
The first line declares u and v to be floating-point variables. The second line declares pv to be a pointer variable whose object is a floating-point quantity;i.e., pv points to floating-point quantity. Note that pv represents an address, not a floating-point quantity.
Thus, a pointer declaration may be written in general terms as
data-type *ptvar;
where ptvar is the name of the pointer variable, and data-type refers to the data type of the pointer's object. Remember that an asterisk must precede ptvar.
A C program contains the following declarations.
float u, v;
float *pv;
The first line declares u and v to be floating-point variables. The second line declares pv to be a pointer variable whose object is a floating-point quantity;i.e., pv points to floating-point quantity. Note that pv represents an address, not a floating-point quantity.
8.1 FUNDAMENTALS
A pointer is a variable that represents the location (rather than the value) of a data item, such as a variable or an array element.
Within the computer's memory, every stored data item occupies one or more contiguous memory cells (i.e. adjacent words or bytes). The number of memory cells required to store a data item depends on the type of data item.For example, a single character will typically be stored in one byte (8 bits) of memory; an integer usually requires two contiguous bytes; a floating-point number may require four contiguous bytes; and a double precision quantity may require eight contiguous bytes.
Suppose v is a variable that represents some particular data item.The compiler will automatically assign memory cells for this data item.The data item can then be accessed if we know the location (i.e. the address) of the first memory cell. The address of v's memory location can be determined by the expression &v, where & is a unary operator, called the address operator, that evaluates the address of its operand.
Now let us assign the address of v to another variable, pv. Thus,
pv = &v
This new variable is called a pointer to v, since it "points" to the location where v is stored in memory.Thus, pv is referred to as a pointer variable.
The data item represented by v (i.e. , the data item stored in v's memory cells) can be accessed by the expression *pv, where * is unary operator, called the indirection operator, that operates only on a pointer variable. Therefore, *pv and v both represent the same data item (i.e, the contents of the memory cells). Furthermore, if we write pv = &v and u = *pv, then u and v will both represent the same value; i.e., the value of v will indirectly be assigned to u.
Consider the simple C program shown below.
This program involves the use of two integer expressions. The first, 2 * (v+5), is an ordinary arithmetic expression whereas the second, 2* (*pv+5), involves the use of a pointer. The expressions are equivalent, since v and *pv each represent the same integer value.
The following output is generated when the program is executed.
Within the computer's memory, every stored data item occupies one or more contiguous memory cells (i.e. adjacent words or bytes). The number of memory cells required to store a data item depends on the type of data item.For example, a single character will typically be stored in one byte (8 bits) of memory; an integer usually requires two contiguous bytes; a floating-point number may require four contiguous bytes; and a double precision quantity may require eight contiguous bytes.
Suppose v is a variable that represents some particular data item.The compiler will automatically assign memory cells for this data item.The data item can then be accessed if we know the location (i.e. the address) of the first memory cell. The address of v's memory location can be determined by the expression &v, where & is a unary operator, called the address operator, that evaluates the address of its operand.
Now let us assign the address of v to another variable, pv. Thus,
pv = &v
This new variable is called a pointer to v, since it "points" to the location where v is stored in memory.Thus, pv is referred to as a pointer variable.
The data item represented by v (i.e. , the data item stored in v's memory cells) can be accessed by the expression *pv, where * is unary operator, called the indirection operator, that operates only on a pointer variable. Therefore, *pv and v both represent the same data item (i.e, the contents of the memory cells). Furthermore, if we write pv = &v and u = *pv, then u and v will both represent the same value; i.e., the value of v will indirectly be assigned to u.
Consider the simple C program shown below.
#include < stdio.h >
main ()
{
int u1, u2;
int v = 3;
int *pv; /* pv pointer to v*/
u1= 2* (v+5); /*ordinary expression*/
pv = &v;
u2= 2* (*pv +5); /*equivalent expression*/
printf("\nu1=%d u2=%d", u1, u2);
}
This program involves the use of two integer expressions. The first, 2 * (v+5), is an ordinary arithmetic expression whereas the second, 2* (*pv+5), involves the use of a pointer. The expressions are equivalent, since v and *pv each represent the same integer value.
The following output is generated when the program is executed.
u1=16 u2=16
Sunday, December 27, 2009
7.5 ARRAYS AND STRINGS
Most C compilers include library functions that allow strings to be compared, copied or concatenated (i.e combined, one behind another).Other library functions permit operations on individual characters within strings; e.g., they allow individual characters to be located within strings, and so on.The following example illustrates the use of some of these library functions.
The strcmp function appears in two different places within this program : in main, when testing for a stopping condition, and in rearrange, when testing for the need to interchange two strings.The actual string interchange is carried out using strcpy.The dialog resulting from a typical execution of the program is shown below.The user's response are underlined, as usual.
/* sort a list of strings alphabetically using a two-dimensional character array*/
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
void reorder (int n, char x[][12]); /* function prototype*/
main()
{
int i, n = 0;
char x[10][12];
printf ("Enter each string on a separate line below\n\n");
printf ("Type \ 'END\ ' when finished\n\n");
/*read in the list of strings*/
do {
printf ("string %d: ", n+1);
scanf ("%s", x[n]);
} while (strcmp(x[n++], "END"));
/* adjust the value of n*/
n--;
/* reorder the list of strings*/
reorder(n, x);
/* display the reordered list of strings */
printf("\n\nReordered List of strings: \n");
for (i=0; i < n;++i)
printf("\nstring %d: %s", i+1, x[i]);
}
void reorder(int n, char x[][12]) /* rearrange the list of strings */
{
char temp[12];
int i, item ;
for (item=0; item < n-1;++item)
/* find the lowest of all remaining strings */
for (i=item+1; i < n;++i)
if (strcmp(x[item], x[i]) > 0) {
/* interchange the two strings */
strcpy(temp, x[item]);
strcpy(x[item], x[i]);
strcpy(x[i], temp);
}
return;
}
The strcmp function appears in two different places within this program : in main, when testing for a stopping condition, and in rearrange, when testing for the need to interchange two strings.The actual string interchange is carried out using strcpy.The dialog resulting from a typical execution of the program is shown below.The user's response are underlined, as usual.
Enter each string on a separate line below
Type 'END ' when finished
string 1: PACIFIC
string 2: ATLANTIC
string 3: INDIAN
string 4: CARIBBEAN
string 5: BERING
string 6: BLACK
string 7: RED
string 8: NORTH
string 9: BALTIC
string 10: CASPIAN
string 11: END
Reordered List of strings:
string 1: ATLANTIC
string 2: BALTIC
string 3: BERING
string 4: BLACK
string 5: CARIBBEAN
string 6: CASPIAN
string 7: INDIAN
string 8: NORTH
string 9: PACIFIC
string 10: RED
Saturday, December 26, 2009
7.4 MULTIDIMENSIONAL ARRAYS
Multidimensional arrays are defined in much the same manner as one-dimensional arrays, except that a separate pair of square brackets is required for each subscript.Thus, a two dimensional array will require two pair of square brackets, a three-dimensional array will require three pair of square brackets, and so on.
In general terms a multidimensional array definition can be written as
storage-class data-type array[expression 1][expression 2].....[expression n]
where storage-class refers to the storage class of the array, data-type is its data type, array is the array name, and expression 1, expression 2,......,expression n are positive valued integer expressions that indicate the number of array elements associated with each subscript.Remember that the storage-class is optional ;the default values are automatic for arrays that are defined inside of a function, and external for arrays defined outside of a function.
Consider the following two dimensional array definition.
int values[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
Note that the value can be thought of a table having 3 rows and 4 columns (4 elements per row).Since initial values are assigned by rows (i.e. last subscript increasing most rapidly), the results of this initial assignments are as follows.
values[0][0] = 1 values[0][1] = 2 values[0][2] = 3 values[0][3] = 4
values[1][0] = 5 values[1][1] = 6 values[1][2] = 7 values[1][3] = 8
values[2][0] = 9 values[2][1] = 10 values[2][2] = 11 values[2][3] = 12
Remember the first subscript ranges from 0 to 2, and the second subscript ranges from 0 to 3.
Now consider the following three dimensional array definition.
int t[10][20][30] = {
{ /*table 1*/
{1, 2, 3, 4}, /*row 1*/
{5, 6, 7, 8}, /*row 2*/
{9, 10, 11, 12} /*row 3*/
},
{ /*table 2*/
{21, 22, 23, 24}, /*row 1*/
{25, 26, 27, 28}, /*row 2*/
{29, 30, 31, 32} /*row 3*/
}
}
Think of this array as a collection of 10 tables, each having 20 rows and 30 columns.The groups of initial values will result in the assignment of the following nonzero values in the first two tables.
t[0][0][0] = 1 t[0][0][1] = 2 t[0][0][2] = 3 t[0][0][3] = 4
t[0][1][0] = 5 t[0][1][1] = 6 t[0][1][2] = 7 t[0][1][3] = 8
t[0][2][0] = 9 t[0][2][1] = 10 t[0][2][2] = 11 t[0][2][3] = 12
t[1][0][0] = 21 t[0][0][1] = 22 t[0][0][2] = 23 t[0][0][3] = 24
t[1][1][0] = 25 t[0][1][1] = 26 t[0][1][2] = 27 t[0][1][3] = 28
t[1][2][0] = 29 t[0][2][1] = 30 t[0][2][2] = 31 t[0][2][3] = 32
All of the remaining array will be assigned zeros.
In general terms a multidimensional array definition can be written as
storage-class data-type array[expression 1][expression 2].....[expression n]
where storage-class refers to the storage class of the array, data-type is its data type, array is the array name, and expression 1, expression 2,......,expression n are positive valued integer expressions that indicate the number of array elements associated with each subscript.Remember that the storage-class is optional ;the default values are automatic for arrays that are defined inside of a function, and external for arrays defined outside of a function.
Consider the following two dimensional array definition.
int values[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
Note that the value can be thought of a table having 3 rows and 4 columns (4 elements per row).Since initial values are assigned by rows (i.e. last subscript increasing most rapidly), the results of this initial assignments are as follows.
values[0][0] = 1 values[0][1] = 2 values[0][2] = 3 values[0][3] = 4
values[1][0] = 5 values[1][1] = 6 values[1][2] = 7 values[1][3] = 8
values[2][0] = 9 values[2][1] = 10 values[2][2] = 11 values[2][3] = 12
Remember the first subscript ranges from 0 to 2, and the second subscript ranges from 0 to 3.
Now consider the following three dimensional array definition.
int t[10][20][30] = {
{ /*table 1*/
{1, 2, 3, 4}, /*row 1*/
{5, 6, 7, 8}, /*row 2*/
{9, 10, 11, 12} /*row 3*/
},
{ /*table 2*/
{21, 22, 23, 24}, /*row 1*/
{25, 26, 27, 28}, /*row 2*/
{29, 30, 31, 32} /*row 3*/
}
}
Think of this array as a collection of 10 tables, each having 20 rows and 30 columns.The groups of initial values will result in the assignment of the following nonzero values in the first two tables.
t[0][0][0] = 1 t[0][0][1] = 2 t[0][0][2] = 3 t[0][0][3] = 4
t[0][1][0] = 5 t[0][1][1] = 6 t[0][1][2] = 7 t[0][1][3] = 8
t[0][2][0] = 9 t[0][2][1] = 10 t[0][2][2] = 11 t[0][2][3] = 12
t[1][0][0] = 21 t[0][0][1] = 22 t[0][0][2] = 23 t[0][0][3] = 24
t[1][1][0] = 25 t[0][1][1] = 26 t[0][1][2] = 27 t[0][1][3] = 28
t[1][2][0] = 29 t[0][2][1] = 30 t[0][2][2] = 31 t[0][2][3] = 32
All of the remaining array will be assigned zeros.
Friday, December 25, 2009
7.3 PASSING ARRAYS TO A FUNCTION
An entire array can be passed to a function as an argument.The manner in which the array is passed differs markedly, however, from that of an ordinary variable.
To pass an array to a function, the array name must appear by itself, without brackets or subscripts, as an actual argument within the function call.The corresponding formal argument is written in the same manner,though it must be declared as an array within the formal argument declarations.when declaring a one-dimensional array as a formal argument,the array name is written with a pair of empty square brackets.The size of the array is not specified within formal argument declaration.
Some care is required when writing function prototypes that include array arguments.An empty pair of square brackets must follow the name of each array argument, thus indicating that the argument is an array.If argument names are not included in a function declaration, then an empty pair of square brackets must follow the array argument data type.
When an array is passed to a function, however, the values of the array elements are not passed to the function.Rather, the array name is interpreted as the address of the first array element (i.e. the address of the memory location containing the first array element).This address is assigned to the corresponding formal argument when the function is called.Therefore the formal argument becomes a pointer to the first array element.Arguments that are passed in this manner are said to be passed by reference rather than by value.
Here is a simple C program that passes a three-element integer array to function, where the array elements are altered.The values of the array elements are displayed at three different places in the program, thus illustrating the effects of alterations.
The array elements are assigned the values a[0] = 1, a[1] =2 and a[2] =3 within the first loop appearing in main.These values are displayed as soon as they are assigned.The array is then passed to the function modify, when each array element is assigned the value -9.These new values are then displayed from within the function.Finally the values of the array elements are again displayed from main, after control has been transferred back to main from modify.
When the program is executed, the following output is generated.
These results show that the elements of a are altered within main as a result of the changes that were made within modify.
To pass an array to a function, the array name must appear by itself, without brackets or subscripts, as an actual argument within the function call.The corresponding formal argument is written in the same manner,though it must be declared as an array within the formal argument declarations.when declaring a one-dimensional array as a formal argument,the array name is written with a pair of empty square brackets.The size of the array is not specified within formal argument declaration.
Some care is required when writing function prototypes that include array arguments.An empty pair of square brackets must follow the name of each array argument, thus indicating that the argument is an array.If argument names are not included in a function declaration, then an empty pair of square brackets must follow the array argument data type.
When an array is passed to a function, however, the values of the array elements are not passed to the function.Rather, the array name is interpreted as the address of the first array element (i.e. the address of the memory location containing the first array element).This address is assigned to the corresponding formal argument when the function is called.Therefore the formal argument becomes a pointer to the first array element.Arguments that are passed in this manner are said to be passed by reference rather than by value.
Here is a simple C program that passes a three-element integer array to function, where the array elements are altered.The values of the array elements are displayed at three different places in the program, thus illustrating the effects of alterations.
#include < stdio.h >
void modify (int a[]); /*function prototype*/
main()
{
int count,a[3]; /*array definition*/
printf("\nFrom main, before calling the function: \n");
for (count=0; count <= 2; ++count)
{
a[count] = count + 1;
printf("a[%d] =\n", count, a[count]);
}
modify(a);
printf("\nFrom main, after calling the function: \n");
for (count=0; count <= 2; ++count)
printf("a[%d] =\n", count, a[count]);
}
void modify (int a[]) /*Function definition*/
{
int count;
printf("nFrom the function, after modifying the values: \n");
for (count=0; count <= 2; ++count) {
a[count] = -9;
printf("a[%d] =\n", count, a[count]);
}
return;
} The array elements are assigned the values a[0] = 1, a[1] =2 and a[2] =3 within the first loop appearing in main.These values are displayed as soon as they are assigned.The array is then passed to the function modify, when each array element is assigned the value -9.These new values are then displayed from within the function.Finally the values of the array elements are again displayed from main, after control has been transferred back to main from modify.
When the program is executed, the following output is generated.
From main, before calling the function:
a[0] = 1
a[1] =2
a[2] =3
From the function, after modifying the values:
a[0] =-9
a[1] =-9
a[2] =-9
From main, after calling the function:
a[0] =-9
a[1] =-9
a[2] =-9
Tuesday, December 22, 2009
7.2 PROCESSING AN ARRAY
Single operations which involve entire arrays are not permitted in C.Thus, if a ans b are similar arrays (i.e. same data type, same dimensionality and same size), assignment operations, comparison operations, etc. must be carried out on an element-by-element basis.This is usually accomplished within a loop, where each pass through the loop is used to process one array element.The number of passes through the loop will therefore equal the number of array elements to be processed.
Let us write a C program that calculates the average of n numbers, then compute the deviation of each number about the average
Now suppose the program is executed using the following five numerical quantities: x1=3, x2=-2, x3=12, x4=4.4, x5=3.5.The interactive session, including the data entry and the calculated results, is shown below. The user's response is underlined.
The average is 4.18
i=1 x= 3.00 d= -1.18
i=2 x= -2.00 d= -6.18
i=3 x= 12.00 d= 7.82
i=4 x= 4.40 d= 0.22
i=5 x= 3.50 d= -0.68
Let us write a C program that calculates the average of n numbers, then compute the deviation of each number about the average
#include < stdio.h>
main()
{
int n, count;
float avg, d, sum=0;
float list[100];
/*read a value for n*/
printf("\nHow many numbers will be averaged?");
scanf("%d", &n);
printf("\n");
/*read the numbers and calculate their sum*/
for (count=0;count < n;++count) {
printf("i=%d x= ", count+1);
scanf("%f", &list[count]);
sum +=list [count];
}
/*calculate and display the average*/
avg= sum / n;
printf("\nThe average is %5.2f\n\n", avg);
/*calculate and display the deviations about the average*/
for (count=0;count < n; ++count) {
d= list[count] - avg;
printf("i=%d x=%5.2f d=%5.2f\n", count+1, list[count], d);
}
}
Now suppose the program is executed using the following five numerical quantities: x1=3, x2=-2, x3=12, x4=4.4, x5=3.5.The interactive session, including the data entry and the calculated results, is shown below. The user's response is underlined.
How many numbers will be averaged? 5
i=1 x=3
i=2 x=-2
i=3 x=12
i=4 x=4.4
i=5 x=3.5The average is 4.18
i=1 x= 3.00 d= -1.18
i=2 x= -2.00 d= -6.18
i=3 x= 12.00 d= 7.82
i=4 x= 4.40 d= 0.22
i=5 x= 3.50 d= -0.68
Sunday, December 20, 2009
7.1 DEFINING AN ARRAY
Arrays are defined in much the same manner as ordinary variables, except that each array name must be accompanied by a size specification (i.e the number of elements).For a one-dimension array, the size is specified by a positive integer expression, enclosed in square brackets.The expression is usually written as a positive integer constatnt.
In general terms, a one-dimensional array definition may be expressed as
storage-class data-type array[ expression];
where storage-class refers to the storage class of the array,data-type is the data type, array is the array name, and expression is a positive-valued integer expression which indicates the number of array elements.The storage-class is optional;default values are automatic for arrays that are defined within a function or a block, and external for arrays that are defined outside of a function.
Several typical one-dimensional array definitions are shown below.
int x[100];
char text[80];
static char message[25];
static float n[12];
The first line states that x is a 100-element integer array, and the second defines text to be an 80-element character array.In the third line,message is defined as a static 25-element character array, whereas the fourth line establishes n as a static 12-element floating-point array.
Automatic arrays, unlike automatic variables, cannot be initialized.However, external and static array definitions can include the assignment of initial value if desired.The initial values must appear in the order in which they will be assigned to the individual array elements, enclosed in braces and separated by commas.The general form is
storage-class data-type array[expression]= {value1,value2,....,value n};
where value 1 refers to the value of the first array element,value 2 refers to the value of the second array element, and so on.The appearance of the expression, which indicates the number of array elements, is optional wen initial values are present.
Consider the following array definitions.
int digits[10] = {3, 3, 3};
static float x[6] = {-0.3, 0, 0.25};
The results, on an element-by-element basis, are as follows.
digits[0] = 3 x[0] = -0.3
digits[1] = 3 x[1] = 0
digits[2] = 3 x[2] = 0.25
digits[3] = 0 x[3] = 0
digits[4] = 0 x[4] = 0
digits[5] = 0 x[5] = 0
digits[6] = 0
digits[7] = 0
digits[8] = 0
digits[9] = 0
In each case, all of the array elements are automatically set to zero except those that have been explicitly initialized within the array definitions.
The array size need not be specified explicitly when initial values are included as a part of an array definition.With a numerical array, the array size will automatically be set equal to the number of initial values included within the definition.
For example,
int digits[10] = {3, 3, 3};
static float x[6] = {-0.3, 0, 0.25}; can also be written as
int digits[ ] = {3, 3, 3};
static float x[ ] = {-0.3, 0, 0.25};
In general terms, a one-dimensional array definition may be expressed as
storage-class data-type array[ expression];
where storage-class refers to the storage class of the array,data-type is the data type, array is the array name, and expression is a positive-valued integer expression which indicates the number of array elements.The storage-class is optional;default values are automatic for arrays that are defined within a function or a block, and external for arrays that are defined outside of a function.
Several typical one-dimensional array definitions are shown below.
int x[100];
char text[80];
static char message[25];
static float n[12];
The first line states that x is a 100-element integer array, and the second defines text to be an 80-element character array.In the third line,message is defined as a static 25-element character array, whereas the fourth line establishes n as a static 12-element floating-point array.
Automatic arrays, unlike automatic variables, cannot be initialized.However, external and static array definitions can include the assignment of initial value if desired.The initial values must appear in the order in which they will be assigned to the individual array elements, enclosed in braces and separated by commas.The general form is
storage-class data-type array[expression]= {value1,value2,....,value n};
where value 1 refers to the value of the first array element,value 2 refers to the value of the second array element, and so on.The appearance of the expression, which indicates the number of array elements, is optional wen initial values are present.
Consider the following array definitions.
int digits[10] = {3, 3, 3};
static float x[6] = {-0.3, 0, 0.25};
The results, on an element-by-element basis, are as follows.
digits[0] = 3 x[0] = -0.3
digits[1] = 3 x[1] = 0
digits[2] = 3 x[2] = 0.25
digits[3] = 0 x[3] = 0
digits[4] = 0 x[4] = 0
digits[5] = 0 x[5] = 0
digits[6] = 0
digits[7] = 0
digits[8] = 0
digits[9] = 0
In each case, all of the array elements are automatically set to zero except those that have been explicitly initialized within the array definitions.
The array size need not be specified explicitly when initial values are included as a part of an array definition.With a numerical array, the array size will automatically be set equal to the number of initial values included within the definition.
For example,
int digits[10] = {3, 3, 3};
static float x[6] = {-0.3, 0, 0.25}; can also be written as
int digits[ ] = {3, 3, 3};
static float x[ ] = {-0.3, 0, 0.25};
Thursday, December 17, 2009
6.4 STATIC VARIABLES
In this section and the next, we make the distinction between a single-file program,in which the entire program is contained within a single source file, and a multiple program,where the functions that make up the program are contained in separate source files.the rules governing the static storage class are different in each situation.
In a single-file program,static variables are defined within individual functions and therefore have the same scope as automatic variables;i.e. they are local to the functions in which they are defined.Unlike automatic variables,however,static variable retain their values throughout the life of the program.Thus,if a function is exited and then re-entered at a later time,the static variables defined within that function will retain their former values.This feature allows function to retain information permanently throughout the execution of a program.
Static variables are defined within a function in the same manner as automatic variables,except that the variable declaration must begin with the static storage-class designation.Static variables can be utilized within the function in the same manner as other variables.They cannot,however, be accessed outside of their defining function.
Initial values can be included in the static variable declarations.The rules associated with the assignment of these values are essentially the same as the rules associated with the initialization of external variables, even though the static variables are defined locally within a function.In particular-
1. The initial values must be expressed as constants, not expressions.
2. The initial values are assigned to their respective variables at the beginning of program execution.The variables retain these values throughout the life of the program, unless different values are assigned during the course of the computation.
3. Zeroes will be assigned to all static variables whose declarations do not explicit initial values.Hence, static variables will always have assigned values.
Generating Fibonacci Numbers The Fibonacci numbers form an interesting sequence in which each number is equal to the sum of the previous two numbers.In other words,
F3 =F2 + F1
Let us write a C program that generates the first n Fibonacci numbers, where n is value specified by the user.
You should understand that f1 and f2 are strictly local variables, even though they retain their values from one function call to another.
The output corresponding to a value of n=6 is shown below.As usual the user's response is underlined.
In a single-file program,static variables are defined within individual functions and therefore have the same scope as automatic variables;i.e. they are local to the functions in which they are defined.Unlike automatic variables,however,static variable retain their values throughout the life of the program.Thus,if a function is exited and then re-entered at a later time,the static variables defined within that function will retain their former values.This feature allows function to retain information permanently throughout the execution of a program.
Static variables are defined within a function in the same manner as automatic variables,except that the variable declaration must begin with the static storage-class designation.Static variables can be utilized within the function in the same manner as other variables.They cannot,however, be accessed outside of their defining function.
Initial values can be included in the static variable declarations.The rules associated with the assignment of these values are essentially the same as the rules associated with the initialization of external variables, even though the static variables are defined locally within a function.In particular-
1. The initial values must be expressed as constants, not expressions.
2. The initial values are assigned to their respective variables at the beginning of program execution.The variables retain these values throughout the life of the program, unless different values are assigned during the course of the computation.
3. Zeroes will be assigned to all static variables whose declarations do not explicit initial values.Hence, static variables will always have assigned values.
Generating Fibonacci Numbers The Fibonacci numbers form an interesting sequence in which each number is equal to the sum of the previous two numbers.In other words,
F3 =F2 + F1
Let us write a C program that generates the first n Fibonacci numbers, where n is value specified by the user.
/*program to calculate successive Fibonacci numbers*/
#include < stdio.h >
long int fibonacci (int count);
main()
{
int count, n;
printf ("How many Fibonacci numbers?");
scanf ("%d", &n);
printf ("\n");
for (count=1;count <= n;++count)
printf ("\ni= %2d F=%1d", count, fibonacci (count));
}
long int fibonacci (int count)
/*calculate a fibonacci number using the formulas F=1 for n < 3 and F3= F1+F2 for n >=3*/
{
static long int f1=1, f2=1;
long int f;
f= (count < 3)? 1 : f1+f2;
f2=f1;
f1=f;
return (f);
}You should understand that f1 and f2 are strictly local variables, even though they retain their values from one function call to another.
The output corresponding to a value of n=6 is shown below.As usual the user's response is underlined.
How many Fibonacci numbers? 6
i=1 F=1
i=2 F=1
i=3 F=2
i=4 F=3
i=5 F=5
i=6 F=8
6.3 EXTERNAL (GLOBAL) VARIABLES
External variables,in contrast to automatic variables, are not confined to single functions.Their scope extends from the point the point of definition through the remainder of the program.They are often referred to as global variables.
Since external variables are recognized globally,they can be accessed from any function that falls within their scope.They retain their assigned values within this scope.
When working with external variables, we must distinguish between external variable definitions and external variable declarations.An external variable definition is written in the same manner as an ordinary variable declaration.It must appear outside of ,and usually before,the functions that access the external variables.An external variable definition will automatically allocate the required storage space for the external variables within the computer's memory.The assignment of initial values can be included within an external variable definition if desired.
An external variable declaration must begin with the storage class specifier extern. The name of the external variable and its data type must agree with the corresponding external variable definition that appears outside of the function. Storage space for external variables will not be allocated as a result of an external variable declaration.Moreover, an external variable declaration cannot include the assignment of initial values.These distinctions between an external variable definition and external variable declaration are very important.
Let us write a program that makes use of external variables to represent the total (cumulative) numbers of characters read, and the total number of lines.
/*read several lines of text and determine the average number of characters per line*/
Notice that sum and lines are external variables that represent the total (cumulative) number of characters read and the total number of lines,respectively.Both of these variables are assigned initial values of zero.These values are successively modified within main,as additional lines of text are read.
Finally, it should be pointed out that there are inherent dangers in the use of external variables, since an alteration in the value of an external variable within a function will be carried over into other parts of the program.
Since external variables are recognized globally,they can be accessed from any function that falls within their scope.They retain their assigned values within this scope.
When working with external variables, we must distinguish between external variable definitions and external variable declarations.An external variable definition is written in the same manner as an ordinary variable declaration.It must appear outside of ,and usually before,the functions that access the external variables.An external variable definition will automatically allocate the required storage space for the external variables within the computer's memory.The assignment of initial values can be included within an external variable definition if desired.
An external variable declaration must begin with the storage class specifier extern. The name of the external variable and its data type must agree with the corresponding external variable definition that appears outside of the function. Storage space for external variables will not be allocated as a result of an external variable declaration.Moreover, an external variable declaration cannot include the assignment of initial values.These distinctions between an external variable definition and external variable declaration are very important.
Let us write a program that makes use of external variables to represent the total (cumulative) numbers of characters read, and the total number of lines.
/*read several lines of text and determine the average number of characters per line*/
#include < stdio.h>
int sum=0; /*total number of characters*/
int lines=0; /*total number of lines*/
int linecount(void)
main()
{
int n; /*number of chars in a given line*/
float avg; /*average number of chars per line*/
printf("Enter the text below\n");
/*read a line of text and update the cumulative counters*/
while (n=linecount() > 0) {
sum +=n;
++lines;
}
avg=(float) sum/lines;
printf("\nAverage number of characters per line: %5.2f", avg);
}
/*read a line of text and count the number of characters*/
int linecount(void)
{
char line[80];
int count=0;
while((line[count]=getchar()) != '\n')
++count;
return (count);
}
Notice that sum and lines are external variables that represent the total (cumulative) number of characters read and the total number of lines,respectively.Both of these variables are assigned initial values of zero.These values are successively modified within main,as additional lines of text are read.
Finally, it should be pointed out that there are inherent dangers in the use of external variables, since an alteration in the value of an external variable within a function will be carried over into other parts of the program.
6.2 AUTOMATIC VARIABLES
Automatic variables are always declared within a function and are local to the function in which they are declared; that is,their scope is confined to that function.Automatic variables defined in different functions will therefore be independent of one another,even though they may have the same name.
Any variable declared within a function is interpreted as an automatic variable unless a different storage class specification is shown within within the declaration.This includes formal argument declarations.All of the variables in the programming examples encountered earlier have been automatic variables.
Since the location of the variable declarations within the program determines the automatic storage class, the keyword auto is not required at the beginning of each declaration.There is no harm in including an auto specifications within a declaration,though this is normally not done.
Consider once again the program mentioned in section 5.6 for calculating factorials.Within main, n is an automatic variable ,the formal argument n is also an automatic variable.
The storage class designation auto could have been included explicitly in the variable declarations if we had wished.Thus the program could have been written as follows.
Either method is acceptable.As a rule, however, the auto designation is not included in variable or formal argument declarations,since this is the default storage class.Thus the program shown in 5.6 represents a more common programming style.
An automatic variable does not retain its value once control is transferred out of its defining function.There for any value assigned to an automatic variable within a function will be lost once the function is exited.
Any variable declared within a function is interpreted as an automatic variable unless a different storage class specification is shown within within the declaration.This includes formal argument declarations.All of the variables in the programming examples encountered earlier have been automatic variables.
Since the location of the variable declarations within the program determines the automatic storage class, the keyword auto is not required at the beginning of each declaration.There is no harm in including an auto specifications within a declaration,though this is normally not done.
Consider once again the program mentioned in section 5.6 for calculating factorials.Within main, n is an automatic variable ,the formal argument n is also an automatic variable.
The storage class designation auto could have been included explicitly in the variable declarations if we had wished.Thus the program could have been written as follows.
/*calculate the factorial of an integer quantity using recursion*/
#include stdio.h
long int factorial (int n); /*function prototype*/
main()
{
auto int n;
long int factorial (int n);
/*read in the integer quantity*/
printf ("n= ");
scanf ("%d", &n);
/*calculate and display the factorial*/
printf ("n!=%d\n", factorial(n));
}
long int factorial (auto int n) /*calculate the factorial*/
{
if (n <= 1);
return(1);
else
return (n * factorial (n-1));
}Either method is acceptable.As a rule, however, the auto designation is not included in variable or formal argument declarations,since this is the default storage class.Thus the program shown in 5.6 represents a more common programming style.
An automatic variable does not retain its value once control is transferred out of its defining function.There for any value assigned to an automatic variable within a function will be lost once the function is exited.
Wednesday, December 16, 2009
6.1 STORAGE CLASSES
There are two different ways to characterize variables: by data type,and by storage class.Data type refers to the type of information represented by a variable ,e.g. integer number,floating-point number,character etc.Storage class refers to the permanence of a variable,and its scope within the program,i.e. the portion of the program over which the variable is recognized.
There are four different storage class specifications in C: automatic,external,static and register.They are identified by the keywords auto,extern,static and register respectively.
The storage class associated with a variable can sometimes be established simply by the location of the variable declaration within the program.In other situations,however, the keyword that specifies a particular storage class must be placed at the beginning of the variable declaration.
Shown below are several typical variable declarations that include the specification of a storage class.
auto int a,b,c;
extern float root1,root2;
static int count=0;
extern char star;
There are four different storage class specifications in C: automatic,external,static and register.They are identified by the keywords auto,extern,static and register respectively.
The storage class associated with a variable can sometimes be established simply by the location of the variable declaration within the program.In other situations,however, the keyword that specifies a particular storage class must be placed at the beginning of the variable declaration.
Shown below are several typical variable declarations that include the specification of a storage class.
auto int a,b,c;
extern float root1,root2;
static int count=0;
extern char star;
5.6 RECURSION
Recursion is a process by which a function calls itself repeatedly,until some specified condition has been satisfied.The process is used for repetitive computations in which each action is stated in terms of a previous result.Many iterative (i.e. repetitive) can be written in this form.
Here is a program that calculates the factorial of a given input quantity using recursion.
The main portion of the program simply reads the integer quantity n and then calls the long-integer recursive function factorial..The function factorial calls,itself recursively, with an actual argument (n-1) that decreases in magnitude for each successive call.The recursive calls terminate when the value of the actual argument becomes equal to 1.
When the program is executed ,the function factorial will be accessed repeatedly,once in main and (n-1) times within itself ,though the person using the program will not be aware of this.Only the final answer will be displayed;for example
Here is a program that calculates the factorial of a given input quantity using recursion.
/*calculate the factorial of an integer quantity using recursion*/
#include stdio.h
long int factorial (int n); /*function prototype*/
main()
{
int n;
long int factorial (int n);
/*read in the integer quantity*/
printf ("n= ");
scanf ("%d", &n);
/*calculate and display the factorial*/
printf ("n!=%d\n", factorial(n));
}
long int factorial (int n) /*calculate the factorial*/
{
if (n <= 1);
return(1);
else
return (n * factorial (n-1));
}The main portion of the program simply reads the integer quantity n and then calls the long-integer recursive function factorial..The function factorial calls,itself recursively, with an actual argument (n-1) that decreases in magnitude for each successive call.The recursive calls terminate when the value of the actual argument becomes equal to 1.
When the program is executed ,the function factorial will be accessed repeatedly,once in main and (n-1) times within itself ,though the person using the program will not be aware of this.Only the final answer will be displayed;for example
n=10
n!=3628800
5.5 PASSING ARGUMENTS TO A FUNCTION
When a single value is passed to a function via an actual argument,the value of the actual argument is copied to the function.Therefore,the value of the corresponding formal argument can be altered within the function, but the value of the actual argument within the calling routine will not change.This procedure of passing the value of an argument to a function is known as passing by value.
Here is a simple C program containing a function that alters the value of its argument.
The original value of a (i.e. a=2) is displayed when the main begins execution.This value is then passed to the function modify,where it is multiplied by 3 and the new value is valued.Note that it is the altered value of the formal argument that is displayed within the function.Finally,the value of a within main (i.e. the actual argument) is again displayed,after control is transferred back to main from modify.
When the program is executed the folloing output is generated.
These results show that a is not altered within the main,even though the corresponding value of a is changed within modify.
Passing an argument by value has advantages and disadvantages.On the plus side,it allows a single valued actual argument to be written as an expression rather than being restricted to a single variable.Moreover, if the
actual argument is expressed simply as a single variable,it protects the value of this variable from alteration within the function.On the other hand, it does not allow information to be transferred back to the calling portion of program via arguments.Thus, passing by value is restricted to a one-way transfer of information.
Here is a simple C program containing a function that alters the value of its argument.
#include stdio.h
void modify (int a) /*function prototype*/
main()
{
int a=2;
printf("\na=%d (from main, before calling the function)", a);
modify(a);
printf("\na=%d (from main, after calling the function)",a );
}
void modify(int a)
{
a*=3;
printf("\na=%d (from the function, after being modified)",a );
return;
}
The original value of a (i.e. a=2) is displayed when the main begins execution.This value is then passed to the function modify,where it is multiplied by 3 and the new value is valued.Note that it is the altered value of the formal argument that is displayed within the function.Finally,the value of a within main (i.e. the actual argument) is again displayed,after control is transferred back to main from modify.
When the program is executed the folloing output is generated.
a=2 (from main, before calling the function)
a=6 (from the function, after being modified)
a=2 (from main, after calling the function)
These results show that a is not altered within the main,even though the corresponding value of a is changed within modify.
Passing an argument by value has advantages and disadvantages.On the plus side,it allows a single valued actual argument to be written as an expression rather than being restricted to a single variable.Moreover, if the
actual argument is expressed simply as a single variable,it protects the value of this variable from alteration within the function.On the other hand, it does not allow information to be transferred back to the calling portion of program via arguments.Thus, passing by value is restricted to a one-way transfer of information.
5.4 FUNCTION PROTOTYPES
In the programs that we have examined earlier in this chapter,the programmer defined function has always preceded the main.Thus,when these programs are compiled,the programmer defined function will have been defined before the first function access.However, many programmers prefer a "top-down" approach,in which the main appears ahead of the programmer defined function definition.In such situations the function access (within main) will precede the function definition.This can be confusing to the compiler,unless the compiler is first alerted to the fact that the function being accessed will be defined later in the program.A function prototype is used for this purpose.
Function prototypes are usually written at the beginning of a program,ahead of any programmer defined functions (including main).The general form of a function prototype is
data-type name (type 1 arg 1,type 2 arg 2,.........,type n arg n);
where data-type represents the data type of the item that is returned by the function,name represents the function name, and type 1, type 2,............., type n represent the data types of the arguments arg 1, arg 2,...., arg n.Notice that a function prototype resembles the first line of a function definition (though a function prototype end with semicolon).
Function prototypes are not mandatory in C.They are desirable,however, because they further facilitate error checking between the calls to function and the corresponding function definition.
Function prototypes are usually written at the beginning of a program,ahead of any programmer defined functions (including main).The general form of a function prototype is
data-type name (type 1 arg 1,type 2 arg 2,.........,type n arg n);
where data-type represents the data type of the item that is returned by the function,name represents the function name, and type 1, type 2,............., type n represent the data types of the arguments arg 1, arg 2,...., arg n.Notice that a function prototype resembles the first line of a function definition (though a function prototype end with semicolon).
Function prototypes are not mandatory in C.They are desirable,however, because they further facilitate error checking between the calls to function and the corresponding function definition.
Tuesday, December 15, 2009
5.3 ACCESSING A FUNCTION
A function can be accessed (i.e. called) by specifying its name,followed by a list of arguments enclosed in parentheses and separated by commas.If the function call does not require any arguments,an empty pair of parentheses must follow the name of the function.
The arguments appearing in the function call are referred to as actual arguments,in contrast to the formal arguments that appear in the first line of the function definition.(They are also known simply as arguments,or as actual parameters).In a normal function call,there will be one actual argument for each formal argument.Each actual argument must be of the same data type as its corresponding formal argument.Remember that it is the value of each actual argument that is transferred into the function and assigned to the corresponding formal argument.
If the function returns a value,the function access is often written as an assignment statement.e.g
y=polynomial(x);
This function access causes the value returned by the function to be assigned to the variable y.
On the other hand,if the function does not return anything,the function access appears by itself.
e.g display(a,b,c);
This function access causes the value of a,b, and c to be processed internally (i.e. displayed) within the function.
The following program determines the largest of three integer quantities.This program makes use of a function that determines the larger of two integer quantities.
The function maximum is accessed from two different places in main.In the first call to maximum the actual arguments are the variables a and b,whereas the arguments are c and d in the second call (d is a temporary variable representing the maximum value of a and b ).
Note the two statements in main that access maximum i.e.
These two statements can be replaced by a single statement
In this statement we see that one of the calls to maximum is an argument for the other call.Thus the calls are embedded,one within the other, and the intermediary variable, d,is not required.
The arguments appearing in the function call are referred to as actual arguments,in contrast to the formal arguments that appear in the first line of the function definition.(They are also known simply as arguments,or as actual parameters).In a normal function call,there will be one actual argument for each formal argument.Each actual argument must be of the same data type as its corresponding formal argument.Remember that it is the value of each actual argument that is transferred into the function and assigned to the corresponding formal argument.
If the function returns a value,the function access is often written as an assignment statement.e.g
y=polynomial(x);
This function access causes the value returned by the function to be assigned to the variable y.
On the other hand,if the function does not return anything,the function access appears by itself.
e.g display(a,b,c);
This function access causes the value of a,b, and c to be processed internally (i.e. displayed) within the function.
The following program determines the largest of three integer quantities.This program makes use of a function that determines the larger of two integer quantities.
/*determine the largest of three integer quantities*/
#include stdio.h
int maximum (int x, int y) /*determine the larger of two integer quantities*/
{
int z;
z= (x >= y)? x: y;
return(z);
}
main()
{
int a,b,c,d;
/*read the integer quantities*/
printf("\na=");
scanf("%d", &a);
printf("\nb=");
scanf("%d", &b);
printf("\nc=");
scanf("%d", &c);
/*calculate and display the maximum value*/
d=maximum(a,b);
printf("\n\maximum=%d", maximum(c,d));
}The function maximum is accessed from two different places in main.In the first call to maximum the actual arguments are the variables a and b,whereas the arguments are c and d in the second call (d is a temporary variable representing the maximum value of a and b ).
Note the two statements in main that access maximum i.e.
d=maximum(a,b);
printf("\n\maximum=%d", maximum(c,d));
These two statements can be replaced by a single statement
printf("\n\maximum=%d", maximum(c,maximum(a,b)));
In this statement we see that one of the calls to maximum is an argument for the other call.Thus the calls are embedded,one within the other, and the intermediary variable, d,is not required.
5.2 DEFINING A FUNCTION
A function definition has two principal components:the first line (including the argument declarations), and the body of the function.
The first line of a function definition contains a type specification of the value returned by the function,followed by the function name and (optionally) a set of arguments,separated by commas and enclosed in parentheses.Each argument is preceded by its associated type declaration.An empty pair of parentheses must follow the function name if the function definition does not include any arguments.
In general terms, the first line can be written as
data-type name (type 1 arg 1,type 2 arg 2,.........,type n arg n)
where data-type represents the data type of the item that is returned by the function, name represents the function name and type 1,type 2,.......,type n represent the data types of the arguments arg 1, arg 2,......,argn.The data types are assumed to be of type int if they are not shown explicitly.
The arguments are called formal arguments, because they represent the names of data items that are transferred into the function from the calling portion of the program.they are also known as parameters or formal parameters.(The corresponding arguments in the function reference are called actual arguments,since they define the data items that are actually transferred. )The identifiers used as formal arguments are "local" in the sense that they are not recognized outside the function.Hence the name of the focal arguments need not be the same as the names of the actual arguments in the calling portion of the program.Each formal arguments must be of the same data type,however, as the data items it receives from the calling portion of the program.
The remainder of the function definition is a compound statement that defines the action to be taken by the function.This compound statement is sometimes referred to as the body of the function.Like any other compound statement,this statement can contain expression statements,other compound statements,control statements,and so on.It should include one or more return statements,in order to return a value to the calling portion of the program.
In general terms, the return statement is written as
return expression;
A function can access other functions.In fact,it can even access itself (this process is known as recursion.)
The first line of a function definition contains a type specification of the value returned by the function,followed by the function name and (optionally) a set of arguments,separated by commas and enclosed in parentheses.Each argument is preceded by its associated type declaration.An empty pair of parentheses must follow the function name if the function definition does not include any arguments.
In general terms, the first line can be written as
data-type name (type 1 arg 1,type 2 arg 2,.........,type n arg n)
where data-type represents the data type of the item that is returned by the function, name represents the function name and type 1,type 2,.......,type n represent the data types of the arguments arg 1, arg 2,......,argn.The data types are assumed to be of type int if they are not shown explicitly.
The arguments are called formal arguments, because they represent the names of data items that are transferred into the function from the calling portion of the program.they are also known as parameters or formal parameters.(The corresponding arguments in the function reference are called actual arguments,since they define the data items that are actually transferred. )The identifiers used as formal arguments are "local" in the sense that they are not recognized outside the function.Hence the name of the focal arguments need not be the same as the names of the actual arguments in the calling portion of the program.Each formal arguments must be of the same data type,however, as the data items it receives from the calling portion of the program.
The remainder of the function definition is a compound statement that defines the action to be taken by the function.This compound statement is sometimes referred to as the body of the function.Like any other compound statement,this statement can contain expression statements,other compound statements,control statements,and so on.It should include one or more return statements,in order to return a value to the calling portion of the program.
In general terms, the return statement is written as
return expression;
A function can access other functions.In fact,it can even access itself (this process is known as recursion.)
5.1 A BRIEF OVERVIEW
A function is a self contained program segment that carries out some specific, well defined task.Every C program consists of one or more functions.One of these functions must be called main.Execution of the program will always begin by carrying out the instructions in main.Additional functions will be subordinate to main, and perhaps to one another.
If a program contains multiple functions,their definitions may appear in any order,though they must be independent of one another.That is,one function definition cannot be embedded within another.
A function will carry out its intended action whenever it is accessed (i.e. whenever the function is "called") from some other portion of the program.The same function can be accessed from several different places within a program.Once the function has carried out its intended action,control will be returned to the point from which the function was accessed.
If a program contains multiple functions,their definitions may appear in any order,though they must be independent of one another.That is,one function definition cannot be embedded within another.
A function will carry out its intended action whenever it is accessed (i.e. whenever the function is "called") from some other portion of the program.The same function can be accessed from several different places within a program.Once the function has carried out its intended action,control will be returned to the point from which the function was accessed.
Monday, December 14, 2009
4.10 THE goto STATEMENT
The goto statement is used to alter normal sequence of program execution by transferring control to some other part of the program.In its general form the goto statement is written as
goto label;
where label is an identifier that is used to label the target statement to which control will be transferred.
All of the popular general purpose programming languages contain a goto statement, though modern programming practice discourages its use.
The following skeletal outline illustrates how the goto statement can be used to transfer control out of a loop if an unexpected condition arises.
/*main loop*/
scanf ("%f", &x);
while (x <=100) {
...................
if (x < 0) goto errorcheck;
...................
scanf ("%f", &x);
}
....................
/*error detection routine*/
errorcheck: {
printf("Error- Negative Value for x");
..................
}
In this example control is transferred out of the while loop, to the compound statement whose label is errorcheck, if a negative value is detected for the input variable x.
goto label;
where label is an identifier that is used to label the target statement to which control will be transferred.
All of the popular general purpose programming languages contain a goto statement, though modern programming practice discourages its use.
The following skeletal outline illustrates how the goto statement can be used to transfer control out of a loop if an unexpected condition arises.
/*main loop*/
scanf ("%f", &x);
while (x <=100) {
...................
if (x < 0) goto errorcheck;
...................
scanf ("%f", &x);
}
....................
/*error detection routine*/
errorcheck: {
printf("Error- Negative Value for x");
..................
}
In this example control is transferred out of the while loop, to the compound statement whose label is errorcheck, if a negative value is detected for the input variable x.
4.9 THE comma OPERATOR
We now introduce the comma (,) operator which is used primarily in conjunction with the for statement.This operator permits two different expressions to appear in situations where only one expression would ordinarily be used.For example it is possible to write
for (expression1a,expression1b;expression2;expression3) statement
where expression1a and expression1b are the two expressions,separated by the comma operator,where only one expression (expression1) would normally appear.
let us write a C program which uses the comma (,) operator to search for a palindrome
/*search for a palindrome*/
#include stdio.h
#include ctype.h
#define EOL '\n'
#define TRUE 1
#define FALSE 0
main()
{
char letter[80];
int tag, count, countback, flag, loop=TRUE;
/*main loop*/
while (loop) {
flag=TRUE;
/*read the text*/
printf("Please enter a word, phrase, or sentence below:'\n'");
for (count=0; (letter[count]=getchar())!= EOL; ++count)
;
if ((toupper(letter[0])= ='E' ) && (toupper(letter[1])= ='N' ) && (toupper(letter[3])= ='D' ))
break;
tag = count - 1;
/*carry out the search*/
for((count=0, countback=tag); count <=tag/2;(++count, --countback)) {
if (letter[count] != letter[countback]) {
flag = FALSE;
break;
}
}
/*display message*/
for (count=0;count <=tag; ++count)
putchar(letter[count]);
if (flag) printf("is a palindrome");
else printf("is not a palindrome");
}
}
A typical interactive session is shown below, indicating the type of output that is generated when the program is executed.As usual the user's response is underlined.
Please enter a word, phrase, or sentence below:
TOOT
TOOT is a palindrome
Please enter a word, phrase, or sentence below:
FALSE
FALSE is not a palindrome
for (expression1a,expression1b;expression2;expression3) statement
where expression1a and expression1b are the two expressions,separated by the comma operator,where only one expression (expression1) would normally appear.
let us write a C program which uses the comma (,) operator to search for a palindrome
/*search for a palindrome*/
#include stdio.h
#include ctype.h
#define EOL '\n'
#define TRUE 1
#define FALSE 0
main()
{
char letter[80];
int tag, count, countback, flag, loop=TRUE;
/*main loop*/
while (loop) {
flag=TRUE;
/*read the text*/
printf("Please enter a word, phrase, or sentence below:'\n'");
for (count=0; (letter[count]=getchar())!= EOL; ++count)
;
if ((toupper(letter[0])= ='E' ) && (toupper(letter[1])= ='N' ) && (toupper(letter[3])= ='D' ))
break;
tag = count - 1;
/*carry out the search*/
for((count=0, countback=tag); count <=tag/2;(++count, --countback)) {
if (letter[count] != letter[countback]) {
flag = FALSE;
break;
}
}
/*display message*/
for (count=0;count <=tag; ++count)
putchar(letter[count]);
if (flag) printf("is a palindrome");
else printf("is not a palindrome");
}
}
A typical interactive session is shown below, indicating the type of output that is generated when the program is executed.As usual the user's response is underlined.
Please enter a word, phrase, or sentence below:
TOOT
TOOT is a palindrome
Please enter a word, phrase, or sentence below:
FALSE
FALSE is not a palindrome
4.8 THE continue STATEMENT
The continue statement is used to bypass the remainder of the current pass through a loop.The loop does not terminate when a continue statement is encountered.Rather the remaining loop statements are skipped and the computation proceeds directly to the next pass through the loop.(Note the distinction between continue and break.)
The continue statement can be included within a while,a do-while or a for statement.It is written simply as
continue;
without any embedded statements or expressions.
Here are some illustrations of loops that contain continue statements.
First,consider a do-while loop.
do {
scanf ("%f", &x);
if (x < 0) {
printf ("Error -Negative value for x");
continue;
}
/*process of non negative value of x*/
.....................
}while (x <=100);
Here is a similar for loop.
for(count=1; x <= 100; ++count) {
scanf ("%f", &x);
if (x < 0) {
printf ("Error -Negative value for x");
continue;
}
/*process of non negative value of x*/
........................
}
In each case, the processing of the current value of x will be bypassed if the value of x is negative.Execution of the loop will then continue with the next pass.
The continue statement can be included within a while,a do-while or a for statement.It is written simply as
continue;
without any embedded statements or expressions.
Here are some illustrations of loops that contain continue statements.
First,consider a do-while loop.
do {
scanf ("%f", &x);
if (x < 0) {
printf ("Error -Negative value for x");
continue;
}
/*process of non negative value of x*/
.....................
}while (x <=100);
Here is a similar for loop.
for(count=1; x <= 100; ++count) {
scanf ("%f", &x);
if (x < 0) {
printf ("Error -Negative value for x");
continue;
}
/*process of non negative value of x*/
........................
}
In each case, the processing of the current value of x will be bypassed if the value of x is negative.Execution of the loop will then continue with the next pass.
Sunday, December 13, 2009
4.7 THE break STATEMENT
The break statement is used to terminate loops or to exit from a switch.It can be used within a for,while,do-while,or switch statement.
The break statement is simply written as
break;
without any embedded expressions or statements.
Consider once again the switch statement originally presented in section 4.6
switch(choice=toupper(getchar())) {
case 'R':
printf("RED");
break;
case 'W':
printf("WHITE");
break;
case 'B':
printf("BLUE");
break;
default:
printf("error");
break;
}
Notice that each group of statement ends with a break statement,in order to transfer control out of the switch statement.
The break statement is simply written as
break;
without any embedded expressions or statements.
Consider once again the switch statement originally presented in section 4.6
switch(choice=toupper(getchar())) {
case 'R':
printf("RED");
break;
case 'W':
printf("WHITE");
break;
case 'B':
printf("BLUE");
break;
default:
printf("error");
break;
}
Notice that each group of statement ends with a break statement,in order to transfer control out of the switch statement.
4.6 THE switch STATEMENT
The switch statement causes a particular group of statements to be chosen from several available groups.The selection is based upon the current value of an expression which is included within the switch statement.
The general form of switch statement is
switch (expression) statement
where expression results in an integer value.Note that expression may also be of type char ,since the individual characters have equivalent integer values.
A simple switch statement is illustrated below.In this example choice is assumed to be a char-type variable.
switch(choice=getchar()) {
case 'r':
case 'R':
printf("RED");
break;
case 'w':
case 'W':
printf("WHITE");
break;
case 'b':
case 'B':
printf("BLUE");
}
Thus, RED will be displayed if choice represents either r or R.white will be displayed if choice represents either w or W,and BLUE will be displayed if choice represents either b or B.Nothing will be displayed if any other character has been assigned to choice.
The general form of switch statement is
switch (expression) statement
where expression results in an integer value.Note that expression may also be of type char ,since the individual characters have equivalent integer values.
A simple switch statement is illustrated below.In this example choice is assumed to be a char-type variable.
switch(choice=getchar()) {
case 'r':
case 'R':
printf("RED");
break;
case 'w':
case 'W':
printf("WHITE");
break;
case 'b':
case 'B':
printf("BLUE");
}
Thus, RED will be displayed if choice represents either r or R.white will be displayed if choice represents either w or W,and BLUE will be displayed if choice represents either b or B.Nothing will be displayed if any other character has been assigned to choice.
4.5 NESTED CONTROL STRUCTURES
Loops,like if-else statements,can be nested,on within another.the inner and outer loops need not be generated by the same type of control structure.It is essential,however,that one loop be completely embedded within on other-there can be no overlap.Each loop must be controlled by a different index.
Let us extend the lowercase to uppercase conversion programs presented in section 4.2,4.3,4.4 so that multiple lines lowercase text can be converted to uppercase,with the conversion taking place one line at a time.In other words,we will read in a line of lowercase text,display it in uppercase,then process another line,and so on.The procedure will continue until a line is detected in which the first character is asterick.
/*convert several lines of text to uppercase continue the conversion until the first character in a line is asterick(*)*/
#include stdio.h
#include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count;
while((letter[0]=getchar())!='*')
{
/*read in aline of text*/
for(count=1;(letter[count]=getchar())!=EOL;++count)
;
fla=count;
/*display the line of text*/
for(count=0;count < fla;++count)
putchar(toupper(letter[count]));
printf("\n\n")
}/*end outer loop*/
printf("good bye");
}
}
A typical interactive session,illustrating the execution of the program,is shown below.Note that the input text supplied by the user is underlined
now is the time
NOW IS THE TIME
fourscore and seven years
FOURSCORE AND SEVEN YEARS
*
good bye
It should be understood that the decision to use a while statement for the outer loop and for statements for the inner loops is arbitrary.Other loop structures could have been selected.
Let us extend the lowercase to uppercase conversion programs presented in section 4.2,4.3,4.4 so that multiple lines lowercase text can be converted to uppercase,with the conversion taking place one line at a time.In other words,we will read in a line of lowercase text,display it in uppercase,then process another line,and so on.The procedure will continue until a line is detected in which the first character is asterick.
/*convert several lines of text to uppercase continue the conversion until the first character in a line is asterick(*)*/
#include stdio.h
#include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count;
while((letter[0]=getchar())!='*')
{
/*read in aline of text*/
for(count=1;(letter[count]=getchar())!=EOL;++count)
;
fla=count;
/*display the line of text*/
for(count=0;count < fla;++count)
putchar(toupper(letter[count]));
printf("\n\n")
}/*end outer loop*/
printf("good bye");
}
}
A typical interactive session,illustrating the execution of the program,is shown below.Note that the input text supplied by the user is underlined
now is the time
NOW IS THE TIME
fourscore and seven years
FOURSCORE AND SEVEN YEARS
*
good bye
It should be understood that the decision to use a while statement for the outer loop and for statements for the inner loops is arbitrary.Other loop structures could have been selected.
4.4 THE for STATEMENT
The for statement is the third and perhaps the most commonly used looping statement in C.This statement includes an expression that specifies an initial value for an index,another expression that determines whether or not the loop is to be continued,a third expression that allows the index to be modified at the end of each pass.
The general form of the for statement is
for(expression1;expresion2;expression3) statement
while expression1 is used to initialize some parameter(called an index) that controls the looping action,expresion2 represents a condition that must be true for the loop to continue execution,and expression3 is used to alter the value of the parameter initially assigned by expression1.
When the for statement is executed,expresion2 is evaluated and tested at the beginning of each pass through the loop,expression3 is evaluated at the end of each pass.Thus the for statement is equivalent to
expression1;
while(expresion2){
statement
expression3;
}
The looping action will continue as long as the value of expresion2 is not zero,that is as long as the logical condition represented by expresion2 is true.
Now let us rewrite the the program shown in section 4.2 and 4.3,which converts lowercase text to uppercase.Now, however, we make use of a for loop rather than while loop or do-while loop.
/*convert a lie of lowercase text to uppercase*/
#include stdio.h
#include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count;
/*read in the lowercase text*/
for(count=0;(letter[count]=getchar())!=EOL;++count);
fla=count;
/*display the uppercase text*/
for(count=0;count < flag ;++count)
putchar(toupper(letter[count]));
}
comparing this program with the corresponding programs given in section 4.2 and 4.3 we see that loops can be written more concisely using the for statement than with while or do-while statements.
The general form of the for statement is
for(expression1;expresion2;expression3) statement
while expression1 is used to initialize some parameter(called an index) that controls the looping action,expresion2 represents a condition that must be true for the loop to continue execution,and expression3 is used to alter the value of the parameter initially assigned by expression1.
When the for statement is executed,expresion2 is evaluated and tested at the beginning of each pass through the loop,expression3 is evaluated at the end of each pass.Thus the for statement is equivalent to
expression1;
while(expresion2){
statement
expression3;
}
The looping action will continue as long as the value of expresion2 is not zero,that is as long as the logical condition represented by expresion2 is true.
Now let us rewrite the the program shown in section 4.2 and 4.3,which converts lowercase text to uppercase.Now, however, we make use of a for loop rather than while loop or do-while loop.
/*convert a lie of lowercase text to uppercase*/
#include stdio.h
#include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count;
/*read in the lowercase text*/
for(count=0;(letter[count]=getchar())!=EOL;++count);
fla=count;
/*display the uppercase text*/
for(count=0;count < flag ;++count)
putchar(toupper(letter[count]));
}
comparing this program with the corresponding programs given in section 4.2 and 4.3 we see that loops can be written more concisely using the for statement than with while or do-while statements.
4.3 THE do-while STATEMENT
When a loop is constructed using the while statement the test for continuation of the loop is carried out at the beginning of each pass.Sometimes, however, it is desirable to have a loop with the test for continuation at the end of each pass.This can be accomplished by means of the do-while statement.
The general form of the do-while statement is
do statement while(expression);
The statement will be repeated,as long as the value of the expression is true.Notice the statement will be executed at least once,since the test for repetition does not occur until the end of the first pass through the loop.
Now let us rewrite the the program shown in section 4.2,which converts lowercase text to uppercase,so that the two while loops are replaced by do-while loops.
/*convert a lie of lowercase text to uppercase*/
#include stdio.h
#include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count=-1;
/*read in the lowercase text*/
do ++count;while((letter[count]=getchar())!=EOL);
fla=count;
/*display the uppercase text*/
count=0;
do{
putchar(toupper(letter[count]));
++count;
} while (count < fla )
}
The general form of the do-while statement is
do statement while(expression);
The statement will be repeated,as long as the value of the expression is true.Notice the statement will be executed at least once,since the test for repetition does not occur until the end of the first pass through the loop.
Now let us rewrite the the program shown in section 4.2,which converts lowercase text to uppercase,so that the two while loops are replaced by do-while loops.
/*convert a lie of lowercase text to uppercase*/
#include stdio.h
#include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count=-1;
/*read in the lowercase text*/
do ++count;while((letter[count]=getchar())!=EOL);
fla=count;
/*display the uppercase text*/
count=0;
do{
putchar(toupper(letter[count]));
++count;
} while (count < fla )
}
Saturday, December 12, 2009
4.2 THE while STATEMENT
Suppose that we want to display hello on output screen five times in five different lines,we might think of writing either five printf statements or one printf statements or one printf statement consisting of constant string "hello\n" five times.What if we want to print 500 times .Should we write 500 printf statements or equivalent?obviously not.It means that we need some programming facility to repeat certain works.
The while statement is used to carry out looping operations,in which a group of statements is executed repeatedly,until some condition has been satisfied.
The general form of the while statement is
while(expression) statement
The statement will be executed repeatedly,as long as the expression is true.
Let us write a program to convert a line of lowercase text to uppercase with the help of while loop
/*convert a line of lowercase text to uppercase*/
# include stdio.h
# include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count=0;
/*read in the lowercase text*/
while((letter[count]=getchar())!=EOL) ++count;
fla=count;
/*display the uppercase text*/
count=0;
while ( count < fla ){
putchar(toupper(letter[count]));
++count;
}
}
The first while loop i.e.
while((letter[count]=getchar())!=EOL) ++count;
is written very concisely.This single statement loop is equivalent to the following:
letter[count]=getchar();
while(letter[count]!=EOL)
{
count=count+1;
letter[count]=getchar();
}
when the program is executed,any line of text entered into the computer will be displayed in the uppercase.Suppose ,for example,that the following line of text had been entered:
fourscore and seven yeas ago our fathers brought forth....
The computer will respond by printing
FOURSCORE AND SEVEN YEARS AGO OUR FATHERS BROUGHT FORTH...
The while statement is used to carry out looping operations,in which a group of statements is executed repeatedly,until some condition has been satisfied.
The general form of the while statement is
while(expression) statement
The statement will be executed repeatedly,as long as the expression is true.
Let us write a program to convert a line of lowercase text to uppercase with the help of while loop
/*convert a line of lowercase text to uppercase*/
# include
# include ctype.h
#define EOL '\n'
main()
{
char letter[80];
int fla,count=0;
/*read in the lowercase text*/
while((letter[count]=getchar())!=EOL) ++count;
fla=count;
/*display the uppercase text*/
count=0;
while ( count < fla ){
++count;
}
}
The first while loop i.e.
while((letter[count]=getchar())!=EOL) ++count;
is written very concisely.This single statement loop is equivalent to the following:
letter[count]=getchar();
while(letter[count]!=EOL)
{
count=count+1;
letter[count]=getchar();
}
when the program is executed,any line of text entered into the computer will be displayed in the uppercase.Suppose ,for example,that the following line of text had been entered:
fourscore and seven yeas ago our fathers brought forth....
The computer will respond by printing
FOURSCORE AND SEVEN YEARS AGO OUR FATHERS BROUGHT FORTH...
Friday, December 11, 2009
4.1 THE if-else STATEMENT
Till now we have written programs in which instructions were executed in order of their appearance.There will be many situations where such execution sequence mat not be
sufficient .For example we want to find the bigger out of two numbers.This problem requires comparision of the two numbers and based on comparision result,the bigger number will be found.This can be implemented using the if instruction.The instruction can be written in
simple form as
if(expr) statement
The expression must be placed in paenthesis,as shown.In this form, the statement will be executed only if the expression is true.if the expression is false then the statement will be ignored.
Many times the program requires to take a specific action if a particular condition is true and another action if the condition is not true(i.e. false).Such a situation can be effectively implemented using the if else instruction.The general form of the if else instruction is
if(expr) statement1 else statement2
Let us try to use to use the if-else instruction to find the bigger out of two numbers.
#include
main()
{
int first,second;
scanf("%d %d",&first,&second);
if(first>second)
printf("First number is bigger\n");
else
printf("Second number is bigger\n");
}
In the above program,if the input value of the first number is higher than the second number then the output shown on the screen will be
First number is bigger
otherwise the output shown on the screen will be
Second number is bigger
sufficient .For example we want to find the bigger out of two numbers.This problem requires comparision of the two numbers and based on comparision result,the bigger number will be found.This can be implemented using the if instruction.The instruction can be written in
simple form as
if(expr) statement
The expression must be placed in paenthesis,as shown.In this form, the statement will be executed only if the expression is true.if the expression is false then the statement will be ignored.
Many times the program requires to take a specific action if a particular condition is true and another action if the condition is not true(i.e. false).Such a situation can be effectively implemented using the if else instruction.The general form of the if else instruction is
if(expr) statement1 else statement2
Let us try to use to use the if-else instruction to find the bigger out of two numbers.
#include
main()
{
int first,second;
scanf("%d %d",&first,&second);
if(first>second)
printf("First number is bigger\n");
else
printf("Second number is bigger\n");
}
In the above program,if the input value of the first number is higher than the second number then the output shown on the screen will be
First number is bigger
otherwise the output shown on the screen will be
Second number is bigger
3.5 THE gets AND puts FUNCTIONS
C contains a number of other library functions that permit some form of data transfer into or out of the computer.
The gets and puts functions offer simple alternatives to the use of scanf and printf for reading and displaying strings,as illustrated in the following example.
#include
main() /*read and write a line or text*/
{
char line[80];
gets(line);
puts(line);
}
This program utilizes gets and puts,rather than scanf and printf,to transfer the line of text into and out of the computer.
The gets and puts functions offer simple alternatives to the use of scanf and printf for reading and displaying strings,as illustrated in the following example.
#include
main() /*read and write a line or text*/
{
char line[80];
gets(line);
puts(line);
}
This program utilizes gets and puts,rather than scanf and printf,to transfer the line of text into and out of the computer.
3.4 WRITING OUTPUT DATA - THE printf FUNCTION
Output data can be written from the computer onto a standard output device using the library function printf.It is similar to the input function scanf,except that its purpose is to display data rather than to enter it into the computer.
In general terms, the printf function is written as
printf(control string,arg1,arg2,arg3,.....,argn)
where control string refers to a string containing certain required formatting information,and arg1,arg2,arg3,....,argn are arguments that represent the the individual output data items.
Here is a simple program that makes use of the printf function
#include
main() /*print several floating point numbers*/
{
float i=2.0,j=3.0;
printf("%f %f",i,j);
}
The output of the program will be as follows:
2.000000 3.000000
In general terms, the printf function is written as
printf(control string,arg1,arg2,arg3,.....,argn)
where control string refers to a string containing certain required formatting information,and arg1,arg2,arg3,....,argn are arguments that represent the the individual output data items.
Here is a simple program that makes use of the printf function
#include
main() /*print several floating point numbers*/
{
float i=2.0,j=3.0;
printf("%f %f",i,j);
}
2.000000 3.000000
Subscribe to:
Comments (Atom)