C Programming
C Programming
C Programming
ver 2.0
Page 1
Chapter 1 Introduction
C Programming
ver 2.0
Page 2
Objectives
In this session, you will learn to: Describe the evolution of the C programming language Describe C as a second-generation as well as a thirdgeneration language State the data types in C Write simple C functions for input and output Write C functions that employ conditional constructs Write C functions that employ iterative constructs
C Programming
ver 2.0
Page 3
The Genesis of C
Multics (Multiplexed Information and Computing Service) is a mainframe timesharing operating system begun in 1965. Multics started out as a joint venture between MIT, General Electric, and Bell Labs. It was a research project, and was an important influence on operating system development. By 1969, Bell Labs management, and even the researchers came to believe that the promise of Multics could be fulfilled only too late, and too expensively.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 4
The Genesis of C
Even before the GE-645 Multics machine was removed from the premises of Bell Labs, an informal group, led by Ken Thompson, had begun investigating alternatives. In 1969, Ken Thompson and Dennis Ritchie designed a file system for the Bell Labs in order to provide a more convenient environment for programming. This file system evolved into an early version of the UNIX Operating System.
C Programming
ver 2.0
Page 5
The Genesis of C
This file system was implemented on a PDP-7 computer, and in 1971, on a PDP-11 computer. Not long after Unix first ran on the PDP-7 in 1969, Doug McIlroy created the systems first high-level language, an implementation of McClures TMG (TransMoGrifiers). TMG is a language for writing compilers in a top-down, recursive-descent style that combines context-free syntax notation with procedural elements.
C Programming
ver 2.0
Page 6
The Genesis of C
Challenged by McIlroys feat in reproducing TMG, Thompson decided that Unix possibly it had not even been named yet needed a systems programming language. In a rapidly scuttled attempt at Fortran, he created, instead, a language of his own, which he called B. Language B was in turn influenced by BCPL (Basic Control Programming Language) of Martin Richards. Its name most probably represents a contraction of BCPL.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 7
The Genesis of C
In 1971, Dennis Ritchie made extensions to language B, and also rewrote its compiler to generate PDP-11 machine instructions instead of threaded code. Thus, the transition from B to C was contemporaneous with the creation of a compiler capable of producing programs fast and small enough to compete with assembly language. By early 1973, the essentials of modern C were complete.
C Programming
ver 2.0
Page 8
The Genesis of C
The language and compiler were strong enough to permit the rewriting of the Unix kernel for the PDP-11 in C during the summer of 1973. Also, during this period, the compiler was retargeted to other nearby machines, particularly the Honeywell 635, and IBM 360/370. Because the language could not live in isolation, the prototypes for the modern libraries of the C language were developed.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 9
C Programming
ver 2.0
Page 11
C Programming
ver 2.0
Page 13
C Programming
ver 2.0
Page 14
C Programming
ver 2.0
Page 15
C Programming
ver 2.0
Page 16
C Programming
ver 2.0
Page 17
C Programming
ver 2.0
Page 18
C Programming
ver 2.0
Page 19
Since the fundamental data types are implemented at the machine level, their storage requirement is machinedependent.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 20
C Programming
ver 2.0
Page 21
C Programming
ver 2.0
Page 22
Defining Data
The general format for defining a variable of a data type is [data type] [variable name] All data is normally defined at the beginning of a function. The definition:
char var; defines a memory location of size one byte, of character type, referred to as var.
C Programming
ver 2.0
Page 23
Defining Data
Data Definition char x, y Data Type char Memory Defined x y Size 1 byte 1 byte Value Assigned -
int
m a
4 bytes 4 bytes
22 -
float float
num num1
4 bytes 4 bytes
9.67
C Programming
ver 2.0
Page 24
Defining Data
The definition: char var; defines a variable location called var, which is one byte in size, and can therefore hold only one character. To define a memory location that can store characters in contiguous locations as in a name, and addressable by one variable name, you would need to use the following definition: char name[10]; The above definition defines a memory location called name containing 10 contiguous bytes for storing up to 9 valid characters.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 25
C Programming
ver 2.0
Page 26
Input/Output Functions
C supports Input/Output operations through functions written in C, and that are part of the standard C library along with other functions. These input/output functions may be incorporated into any program by a programmer. Any input or output operation happens as a stream of characters. The standard I/O functions are available for character-based I/O, or for string-based I/O.
C Programming
ver 2.0
Page 27
Buffered I/O
The standard I/O functions are buffered, i.e., each device has an associated buffer through which any input or output operation takes place. After an input operation from the standard input device has occurred, care must be taken to clear the standard input buffer. Otherwise, the previous contents of the buffer may interfere with subsequent input. After an output operation, the buffer need not be cleared since subsequent output data will flush the previous buffer contents.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 28
Character-Based I/O
The function getch( ) is used to accept a character from standard input. By default, it accepts characters from the keyboard, and returns the character input from the keyboard. The function putch( ) displays the character on to standard output. It takes one argument, namely, the character to be output. The function fflush( ) clears the buffer associated with the particular device.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 29
C Programming
ver 2.0
Page 30
Character-Based I/O
The macro getchar( ) by default accepts a character from the keyboard. Hence, it does not need any parameters. The macro putchar( ) is used to display the character on to standard output. It takes the character to be output as an argument.
C Programming
ver 2.0
Page 31
C Programming
ver 2.0
Page 32
String-Based I/O
The function gets( ) accepts as a parameter, a string variable, or a string literal (enclosed in double quotes) from the keyboard. The function puts( ) accepts a string variable, or a string literal to be displayed to standard output. After displaying the output, the puts( ) function causes the cursor to be positioned at the beginning of the next line.
C Programming
ver 2.0
Page 33
String-Based I/O
#include <stdio.h> #include <conio.h> main( ) { char str[11]; puts("Enter a string of maximum 10 characters"); gets(str); fflush(stdin); puts(str); }
C Programming
ver 2.0
Page 34
Conditional Constructs
The C language provides different conditional constructs for evaluating a condition in a program. The relational operators required for evaluating the conditions are similar to those in other third-generation languages, though the symbols are different.
C Programming
ver 2.0
Page 35
Conditional Constructs
Relational Operators: Operator
== != < > <= >=
Copyright Wipro Technologies Talent Transformation
Meaning
Equal to Not equal to Less than Greater than Less than or equal to Greater than or equal to
C Programming ver 2.0 Page 36
ch =
Input ch
is ch = *
Print *
Not a *
stop
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 37
C Programming
ver 2.0
Page 38
C Programming
ver 2.0
Page 39
C Programming
ver 2.0
Page 40
Page 41
Nested if Construct
A nested if statement is encountered if the statement to be executed after a condition evaluates to true is another if statement. Both the outer if statement and the inner if statement have to evaluate to true for the statement following the inner if condition to be executed.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0
no
ye s no
ye s
Page 42
C Programming
ver 2.0
Page 43
C Programming
ver 2.0
Page 44
C Programming
ver 2.0
Page 46
C Programming
ver 2.0
Page 47
C Programming
ver 2.0
Page 49
C Programming
ver 2.0
Page 50
C Programming
ver 2.0
Page 51
C Programming
ver 2.0
Page 52
false
Therefore, the loop condition is evaluated first, and if it is true, the loop body is executed. After the execution of the loop body, the condition in the while statement is evaluated again. This repeats until the condition becomes false.
Copyright Wipro Technologies Talent Transformation
true
C Programming
ver 2.0
Page 53
Therefore, when this loop construct is used, the body of the loop is guaranteed to execute at least once. The loop is entered into straightaway, and after the first execution of the loop body, the loop condition is evaluated. Subsequent executions of the loop body would be subject to the loop condition evaluating to true.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 55 false
Evaluate Condition
true
C Programming
ver 2.0
Page 56
C Programming
ver 2.0
Page 57
C Programming
ver 2.0
Page 58
C Programming
ver 2.0
Page 59
C Programming
ver 2.0
Page 60
C Programming
ver 2.0
Page 61
Summary
In this session, you learnt to: Describe the evolution of the C programming language Describe C as a second-generation as well as a thirdgeneration language State the data types in C Write simple C functions for input and output Write C functions that employ conditional constructs Write C functions that employ iterative constructs
C Programming
ver 2.0
Page 62
C Programming
ver 2.0
Page 63
C Programming
ver 2.0
Page 64
Objectives
In this session, you will learn to: Write compound conditions employing the logical operators Write functions that perform formatted input/output Declare, initialize, manipulate, and address onedimensional arrays
C Programming
ver 2.0
Page 65
Operator
NOT AND OR
Notation
! && ||
C Programming
ver 2.0
Page 66
C Programming
ver 2.0
Page 67
C Programming
ver 2.0
Page 68
C Programming
ver 2.0
Page 69
C Programming
ver 2.0
Page 70
It has the general form: !expression which evaluates to 1 (true) if the expression is 0, otherwise evaluates to 0 (false)
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 71
C Programming
ver 2.0
Page 72
Logical Expressions
b 0 1 0 1
a && b 0 0 0 1
a || b 0 1 1 1
C Programming
ver 2.0
Page 73
Formatted I/O
C provides standard functions for performing formatted input and output. These functions accept as parameters a format string and a list of variables. The format string consists of a specification for each of the variables in terms of its data type, called the conversion character, and width of input or output.
C Programming
ver 2.0
Page 74
Formatted Output
The function printf( ) is used for formatted output to standard output based on a format string. The format string, along with the data to be output, are the parameters to the printf( ) function. The syntax of the printf( ) function is: printf( format string, var1,var2..) Format string is a string containing the format specification introduced by the character %, and ended by a conversion character.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 75
Formatted Output
An example: printf(%c\n, var); The conversion characters and their meanings are:
Conversion character d c s
Meaning The data is converted to decimal The data is treated as a character The data is a string, and characters from the string are printed until a null character is reached, or until the specified number of characters have been exhausted The data is output as float or double with a default precision of 6
f
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 76
Formatted Output
Between the % character and the conversion character, there may be: A minus sign Implying left adjustment of data A digit Implying the minimum width in which the data is to be output. If the data has larger number of characters than the specified width, the width occupied by the output is larger. If the data consists of fewer characters than the specified width, it is padded to the right (if minus sign is specified), or to the left (if no minus sign is specified). If the digit is prefixed with a zero, the padding is done with zeroes instead of blanks Separates the width from the next digit. Specifying the precision, or the maximum number of characters to be output To signify that the data item is a long integer, and not an integer.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 77
A period A digit l
Formatted Output
Format String %2d %2d %03d %-2d %5s %15s %-15s %f Data 4 224 8 4 Sherlock Holmes Sherlock Holmes Sherlock Holmes 22.44 Output |4| |224| |008| |4 | | Sherlock Holmes| | Sherlock Holmes | | Sherlock Holmes | |22.440000|
C Programming
ver 2.0
Page 78
C Programming
ver 2.0
Page 79
Formatted Input
The function scanf( ) is used for formatted input, and provides many of the conversion facilities of printf( ). The syntax of the function scanf( ) is: scanf( format string, var1, var2.) The scanf( ) function reads and converts characters from standard input according to the format string, and stores the input in memory locations specified by the other arguments.
C Programming
ver 2.0
Page 80
Formatted Input
#include<stdio.h> main( ) { char name[10]; int age = 0; char gender = ' '; scanf ("%7s %c %2d", name, &gender, &age); fflush(stdin); printf( "% s %c %d", name, gender, age); }
C Programming
ver 2.0
Page 81
One-Dimensional Arrays
An array can be defined as a collection of elements of identically typed data items that are stored contiguously in memory. Each array element shares the same name as the array name, but distinguishes itself from other elements in the array using a subscript, or an index. The subscript, or the index of each array element is determined based on the number of offset positions it is from the starting position. The starting offset is taken as 0.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 83
Array Representation
The declaration int a[10]; defines an array a of size 10, as a block of 10 contiguous elements in memory.
a[0]
a[1]
a[2]
a[3] a[4]
a[5] a[6]
a[7] a[8]
a[9]
C Programming
ver 2.0
Page 84
Character Arrays
To define a character array for storing a string of n characters, we would need to define a character array of size n+1 characters. This is because all character arrays are terminated by a NULL character (\0). To define a character array called name for storing a ten-character name, we will define the array as: Char name[11]; where name[0] through name[9] will contain the characters comprising the name, and name[10] will store the NULL character.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 85
name
a
name[0]
b
name[1]
c
name[2]
d
name[3]
e
name[4]
f
name[5]
g
name[6]
h
name[7]
i
name[8]
j
name[9]
\0
name[10]
C Programming
ver 2.0
Page 86
Array Initialization
Since an array is a set of elements located at contiguous memory locations, its initialization involves moving element by element, or one data at a time into the array. An array is initialized by specifying each element in an initialization list separated by commas. The size of the array, in this case, may or may not be specified. The number of elements stored in the array determines its size.
C Programming
ver 2.0
Page 87
C Programming
ver 2.0
Page 88
Array Processing
#include<stdio.h> main( ) { char array1[ ] = {A, R, R, A, Y, \0}; char array2[ ] = {ARRAY}; char dayofweek[ ] = {M, T, W, T, F, S, S, \0}; float values[ ] = {100.56, 200.33, 220.44, 400.22, 0}; int i = 0; printf( String 1 is %s\n, array1); printf( String 2 is %s\n, array2); for( i = 0; dayofweek[i] != \0; i = i +1) printf ( The Day %d in a week is %c\n, i + 1, dayofweek[i]; for( i = 0; values[i] != 0; i = i +1) printf ( The amount %d in a week is %f\n, i + 1, values[i]; }
C Programming ver 2.0 Page 89
C Programming
ver 2.0
Page 90
C Programming
ver 2.0
Page 91
C Programming
ver 2.0
Page 92
Array Addressing
In the declaration: char string[11); the name of the array refers to the starting address of the area that gets allocated for storing the elements of the array. Thus, string contains the address of string[0]. In the aforesaid declaration, string refers to the starting position of the array, and the subscript refers to the offset position from the starting position.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 96
Array Addressing
string 100
100
101
102
103
104
105
106
107
108
109
110
a
0
b
1
c
2
d
3
e
4
f
5
g
6
h
7
i
8
j
9
\0
10
C Programming
ver 2.0
Page 97
Array Addressing
In the previous declaration, string represents the starting point of the array, and the subscript refers to the offset position from the starting point. To arrive at the address of the particular element, the compiler applies the following simple formula:
starting address of the array + ( offset position * size of data type) Address of element 4 = 100 + ( 3 * 1) = 100 +3 = 103
C Programming
ver 2.0
Page 98
Summary
In this session, you learnt to: Write compound conditions employing the logical operators Write functions that perform formatted input/output Declare, initialize, manipulate, and address one-dimensional arrays
C Programming
ver 2.0
Page 99
C Programming
ver 2.0
Page 100
C Programming
ver 2.0
Page 101
Objectives
In this session, you will learn to: Apply the unary, binary, ternary, compound assignment operators, increment, and decrement operators Use character arithmetic, and understand the rules of conversion between different data types Declare, initialize, manipulate and print from a twodimensional array
C Programming
ver 2.0
Page 102
Unary Operators
Unary operators, as the name suggests, works on one operand or variable. The ++ and the -- operators are examples of unary operators. When these operators prefix an operand, they are referred to as prefix operators, and when they are suffixed to an operand, they are referred to as postfix operators. Prefix and postfix operators, when used in an expression, can have totally different results, and hence it is necessary to know their workings.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 103
Unary Operators
Incrementing and decrementing by 1 is such a ubiquitous operation that C offers the prefix and postfix implementations of the ++ and the -- operators. The expression i = i + 1; can also be written as i++. When used as a standalone statement, writing i++, or ++i does not make any difference at all. It is only when they are used as part of an expression that the prefix and the postfix operators can have totally different results.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 104
Unary Operators
Consider the following two statements: total = i++; total = ++i; The first statement total = i++; is equivalent to: total = i; i++; This is equivalent to assigning to total the current value of i, and then incrementing i.
C Programming
ver 2.0
Page 105
Unary Operators
The second statement total = ++i; is equivalent to: i = i + 1; total = i; This is equivalent to first incrementing the value of i, and then assigning the incremented value of i to total. The same principle holds true when working with the unary -- operators.
C Programming
ver 2.0
Page 106
Binary Operators
Binary operators as the name suggests, works on two operands. The binary operators in C (as in other programming languages) are:
The add ( + ) operator The subtract ( - ) operator. The multiply (* ) operator The divide ( / ) operator The modulo ( % ) operator
C Programming
ver 2.0
Page 107
Binary Operators
Examples of binary operators: int x, y, z; x = 27; y = x % 5; /* y set to 2 */ z = x / 5 /* z set to 5 and not 5.4 */
C Programming
ver 2.0
Page 108
Type Conversions
When an operator has operands of different types, they are converted to a common type according to a small number of rules. In general, the only automatic conversions are those that convert a narrower operand into a wider one without losing information, such as converting an integer into floating point
C Programming
ver 2.0
Page 109
Type Conversions
Expressions that might lose information, like assigning a longer integer type to a shorter, or a floating-point type to an integer, may draw a warning, but they are not illegal. A char is just a small integer, so chars may be freely used in arithmetic expressions. This permits considerable flexibility in certain kinds of character transformations. Implicit arithmetic conversions work much as expected. In general, if an operator like +, or * that takes two operands (a binary operator) has operands of different types, the lower type is promoted to the higher type before the operation proceeds.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 110
Type Conversion
The following informal set of rules will suffice: If either operand is long double, convert the other to long double. Otherwise, if either operand is double, convert the other to double. Otherwise, if either operand is float, convert the other to float. Otherwise, convert char and short to int. Then, if either operand is long, convert the other to long. Conversions take place across assignments; the value of the right side is converted to the type of the left, which is the type of the result.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 111
Type Conversions
Consider the following assignments: int i; char c; i = c;
In the aforesaid assignment, the data type on the right (char) is converted to the data type on the left (int), which is the type of the result. If x is float and i is int, then x = i and i = x both cause conversions; float to int causes truncation of any fractional part. When a double is converted to float, whether the value is rounded, or truncated is implementation-dependent.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 112
C Programming
ver 2.0
Page 113
The problem with the above assignment is that the fractional portion of the above division is lost, and d is effectively assigned the integer quotient of the two integers i and j.
C Programming
ver 2.0
Page 114
Ternary Operators
if (a > b) z = a; else z = b;
The aforesaid statements evaluate z to the maximum of a and b. The conditional expression, written with the ternary operator ?:, provides an alternate way to write this, and similar constructions. In the expression expr1 ? expr2 : expr3
C Programming
ver 2.0
Page 116
Ternary Operators
If it is non-zero (true), then the expression expr2 is evaluated, and that is the value of the conditional expression. Otherwise expr3 is evaluated, and that is the value. Only one of expr2 and expr3 is evaluated. Thus to set z to the maximum of a and b, z = (a > b) ? a : b; /* assign z the maximum of a and b */
C Programming
ver 2.0
Page 117
C Programming
ver 2.0
Page 118
C Programming
ver 2.0
Page 119
Two-Dimensional Arrays
While a one-dimensional array can be visualized in onedimension as either a row of elements, or a column of elements, a two-dimensional array needs to be visualized along two dimensions, i.e., along rows and columns. To be precise, a two-dimensional array can be represented as an array of m rows by n columns. A general way of representing or visualizing a twodimensional array is in the form of a two-dimensional grid. But, in memory, even a two-dimensional array is arranged contiguously as an array of elements.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 120
Two-dimensional Arrays
col 0 row 0 col 1
col 2
row 1
row 2
r0,c0
r0,c1
r0,c2
r1,c0
r1,c1
r1,c0
r2,c0
r2,c1
r2,c2
C Programming
ver 2.0
Page 121
Two-Dimensional Arrays
The Scenario: Consider a situation where you want to record the region-wise, product-wise figures of sales. The regions are A, B and C. The products are X, Y and Z Sales data for the region-wise, product-wise breakup should be shown as follows:
C Programming
ver 2.0
Page 122
Two-Dimensional Arrays
Prod X reg A Prod Y Prod Z
reg B
reg C
C Programming
ver 2.0
Page 123
C Programming
ver 2.0
Page 125
C Programming
ver 2.0
Page 126
C Programming
ver 2.0
Page 127
C Programming
ver 2.0
Page 128
C Programming
ver 2.0
Page 129
C Programming
ver 2.0
Page 130
C Programming
ver 2.0
Page 131
C Programming
ver 2.0
Page 132
C Programming
ver 2.0
Page 134
Page 135
C Programming
ver 2.0
Page 136
Particular elements can also be printed from a two dimensional array by using the second subscript. Printf(%c, team_india[10][6] would print the character P from the string Pathan
C Programming
ver 2.0
Page 137
C Programming
ver 2.0
Page 138
Chapter 4 Pointers
C Programming
ver 2.0
Page 139
Objectives
At the end of this session, you should be able to: Declare, initialize, and manipulate pointers Use pointers for manipulating one-dimensional and twodimensional arrays Distinguish between arrays and pointers Use pointer arithmetic
C Programming
ver 2.0
Page 140
Pointer Definition
When a variable is declared (such as int i = 22) in a program, space is reserved in memory for the variable i. To be precise, each variable is assigned a particular memory location referenced by its address. In our case, the integer i would be stored at a specific memory location having the address, say, 1000 (addresses are typically hexadecimal values). The declaration of i can be conceptualized as follows:
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 141
Pointer Definition
i is a named location in memory that can hold an integer and having the address 1000
22 1000
C Programming
ver 2.0
Page 142
Pointer Definition
In C, it is possible to manipulate a variable either by its name, or by its address. The address of a variable can be stored in another variable (called a pointer variable), and access can be had to the variable through this pointer variable. A pointer can therefore be defined as a variable that holds the address of another variable. If you want to define a pointer to hold the address of an integer variable, then you must define the pointer as a pointer to an integer.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 143
C Programming
ver 2.0
Page 145
C Programming
ver 2.0
Page 146
Dereferencing a Pointer
Returning the value pointed to by a pointer is known as pointer dereferencing. To deference the contents of a pointer, the * operator is used.
#include<stdio.h> main( ) { int x, y, *pointer; x = 22; pointer = &x; y = *pointer; /* obtain whatever pointer is pointing to */ }
C Programming ver 2.0 Page 147
C Programming
ver 2.0
Page 148
22 1000
C Programming
ver 2.0
Page 149
x 44 y 44
C Programming ver 2.0 Page 151
C Programming
ver 2.0
Page 152
C Programming
ver 2.0
Page 153
C Programming
ver 2.0
Page 154
C Programming
ver 2.0
Page 155
C Programming
ver 2.0
Page 157
C Programming
ver 2.0
Page 158
C Programming
ver 2.0
Page 159
Pointer Arithmetic
The most common arithmetic operation using pointers is incrementing by 1. Consider the following statement: char *p = Sherlock H; printf(%s\n, p); The initialization of the character pointer with the string Sherlock H can be visualized as shown in the following slide.
C Programming
ver 2.0
Page 161
Pointer Arithmetic
p 100
100
101
102
103
104
105
106
107
108
109
110
S
0
h
1
e
2
r
3
l
4
o
5
c
6
k
7 8
H
9
\0
10
C Programming
ver 2.0
Page 162
Pointer Arithmetic
Now, let us increment the pointer p by 1, as in: p++; p initially pointed to the base address of the string Sherlock H, i.e., 100. After incrementing the pointer p by 1, it points to the next element in the string or the character array, i.e., character h after S. p now contains the address of the element h, i.e., 101
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 163
Pointer Arithmetic
p 101
100
101
102
103
104
105
106
107
108
109
110
S
0
h
1
e
2
r
3
l
4
o
5
c
6
k
7 8
H
9
\0
10
C Programming
ver 2.0
Page 164
Pointer Arithmetic
But will the statement p++; always make p point to the next memory location. The answer is an emphatic No. This depends upon the data type that p is pointing to.
Consider the following piece of code: #include <stdio.h> main( ) {
C Programming ver 2.0 Page 165
Pointer Arithmetic
int int_array[3] = {4, 8, 22}; /* int_array is a constant pointer */ int * p; p = int_array; printf (%d, p); p++; printf(%d, p); } The value of p afer being initialized
p 100
100 4
Copyright Wipro Technologies Talent Transformation
104 8
108 12
C Programming
ver 2.0
Page 166
Pointer Arithmetic
C Programming
ver 2.0
Page 167
Pointer Arithmetic
The key point to note is that when pointers are incremented by 1, the size of the data type to which it is pointing to (4 bytes in our case, since an integer needs 4 bytes of storage) is taken into account. To summarize, the operation p++; will result in the following computation: New address of p = old address of p + size of data type
C Programming
ver 2.0
Page 168
Pointer Arithmetic
Consider the following declaration of a two-dimensional integer array: int p[3][5] = { { 2, 4, 6, 8, 10}, { 3, 6, 9, 12, 15}, { 5, 10, 15, 20, 25} }; The aforesaid declaration declares an array of three integer pointers, each pointing to the first element of an array of 5 integers. This can be visualized as follows:
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 169
Pointer Arithmetic
p 100
200 100 200 2 300 104 300 3 204 4 304 6 208 6 308 9 212 8 312 12 216 10 316 15
404 10
408 15
412 20
416 25
C Programming
ver 2.0
Page 170
Pointer Arithmetic
Here, p points to the first element of the array of pointers. *p equals p[0], i.e., it returns the address 200. This address points to the element at offset [0,0], i.e., element 2. Therefore, *(*p) returns the value 2. Since p is a pointer to another pointer, incrementing p by 1 makes it point to the next element in the array of pointers, i.e., it now points to the element containing the address 300.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 171
Pointer Arithmetic
Hence, *(p + 1) returns the address 300. Therefore, * (*(p + 1)) returns the value at this address, i.e., the element with the value 3. In other words, the element at the offset [1,0]. The following table gives various pointer expressions, and their values:
C Programming
ver 2.0
Page 172
Pointer Arithmetic
Pointer Expression
*(*p) *(*p+1) *(*(p + 1)) *(*(p+1)+1) *(*(p+1)+1)+1
Copyright Wipro Technologies Talent Transformation
Resulting Address
200 204 300 304 304
Variable
p[0][0] p[0][1] p[1][0] p[1][1] p[1][1] + 1
Value
2 4 3 6 6+1=7
C Programming
ver 2.0
Page 173
C Programming
ver 2.0
Page 174
Summary
In this session, you learnt to: Declare, initialize, and manipulate pointers Use pointers for manipulating one-dimensional and twodimensional arrays Distinguish between arrays and pointers Use pointer arithmetic
C Programming
ver 2.0
Page 176
C Programming
ver 2.0
Page 177
C Programming
ver 2.0
Page 178
Objectives
In this session, you will learn to: Write programs that invoke functions through a:
Call by value Call by reference
Define function prototypes Describe the function call mechanism Pass arguments to main( ) in the form of command-line arguments Use the Auto, Static, and Extern storage qualifiers Use string handling functions, conversion functions, and functions for formatting strings in memory
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 179
Advantages of Function
Functions facilitate the factoring of code. Every C program consists of one main( ) function typically invoking other functions, each having a well-defined functionality. Functions therefore facilitate:
Reusability Procedural abstraction
By procedural abstraction, we mean that once a function is written, it serves as a black box. All that a programmer would have to know to invoke a function would be to know its name, and the parameters that it expects.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 180
Function Parameters
Function parameters are defined as part of a function header, and are specified inside the parentheses of the function. The reason that functions are designed to accept parameters is that you can embody generic code inside the function. All that would be required by the function would be the values that it would need to apply the generic code on the values received by it through its parameters.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 181
Function Parameters
Consider the following printf( ) statement: printf(%d, i); This is actually a call to the printf( ) function with two pieces of information passed to it, namely, the format string that controls the output of the data, and the variable that is to be output. The format string, and the variable name can be called the parameters to the function printf( ) in our example.
C Programming
ver 2.0
Page 182
Function Parameters
Function parameters are therefore a mechanism wherein values can be passed down to a function for necessary processing, and the processed value returned back from the function, as the case may be. It is important to remember that not all function need be defined to accept parameters, though most functions do. This brings us now to the important concept of a function returning a value, and also the return type of a function.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 183
Invoking Functions
In C, functions that have parameters are invoked in one of two ways: Call by value Call by reference
C Programming
ver 2.0
Page 184
Call by Value
void swap(int,int ); main() { int a=10, b=20; swap(a, b); printf( %d %d \n,a,b); } void swap (int x, int y) { int temp = x; x= y; y=temp; }
C Programming
ver 2.0
Page 185
Call by Value
In the preceding example, the function main( ) declared and initialized two integers a and b, and then invoked the function swap( ) by passing a and b as arguments to the function swap( ). The function swap( ) receives the arguments a and b into its parameters x and y. In fact, the function swap( ) receives a copy of the values of a and b into its parameters. The parameters of a function are local to that function, and hence, any changes made by the called function to its parameters affect only the copy received by the called function, and do not affect the value of the variables in the called function. This is the call by value mechanism.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 186
Call by Reference
Call by reference means that the called function should be able to refer to the variables of the calling function directly, and not create its own copy of the values in different variables. This would be possible only if the addresses of the variables of the calling function are passed down as parameters to the called function. In a call by reference, therefore, the called function directly makes changes to the variables of the calling function.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 187
Call by Reference
Consider the same swap( ) that we discussed earlier now rewritten using a call by reference. void swap( int *, int *); main() { int a=10, b=20; swap(&a, &b); printf( %d %d \n,a,b); } void swap (int *x, int *y) { int temp=*x; *x=*y; *y=temp; }
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 188
C Programming
ver 2.0
Page 190
C Programming
ver 2.0
Page 193
Function Prototype
C assumes that a function returns a default value of int if the function does not specify a return type. In case a function has to return a value that is not an integer, then the function itself has to be defined of the specific data type it returns. Consider the following code:
#include <stdio.h> main( ) {
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 194
Function Prototype
Functions should be declared before they are used. Consider the situation where you want to use the pow( ) function, called the power function, one of many functions in the mathematics library available for use by the programmer. A function call such as pow(x, y) returns the value of x raised to the power y. To elucidate further, pow(2.0, 3.0) yields the value 8.0
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 195
Function Prototype
The declaration of the function is given by: double pow( double x, double y); Function declarations of this type are called function prototypes. An equal function prototype is given by: double pow( double, double);
C Programming
ver 2.0
Page 196
Function Prototype
A function prototype tells the compiler the number and data types of arguments to be passed to the function and the data type of the value that is to be returned by the function. ANSI C has added the concept of function prototypes to the C language.
C Programming
ver 2.0
Page 197
Function Prototype
float add(float a, float b); float i, j, value; scanf(%f %f, &i, &j); fflush(stdin); value = add(i, j); printf( the total is %d\n, value); }
C Programming
ver 2.0
Page 198
Function Prototype
#include <stdio.h> main( ) { void add( float, float); float i, j, value; scanf(%f %f, &i, &j); fflush(stdin); add(i, j); printf( the total is %d\n, value); } void add(float a, float b) { printf(%f, a + b); return; }
C Programming
ver 2.0
Page 199
Function Calls
It is important for us to know what happens under the hood when a function executes. A logical extension of the aforesaid point is the situation that arises when a function calls another function. It is important to know how the CPU manages all this, i.e., knowing where to look for when a function call is encountered, and having executed the function, to also know where it has to return to. In short, we need to know the call mechanism, and the return mechanism.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 200
C Programming
ver 2.0
Page 201
C Programming
ver 2.0
Page 202
C Programming
ver 2.0
Page 204
Code Area
Entry point for procedure 1 Code for Procedure 1 Entry point for procedure 2 Code for Procedure 2 . . Entry point for procedure n Code for Procedure n
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 205
Data Area
Only a small part of data can be assigned fixed locations before execution begins Global and/or static data Compile-time constants Large integer values Floating-point values Literal strings
C Programming
ver 2.0
Page 206
Dynamic Memory
The memory area for the allocation of dynamic data can be organized in many different ways. A typical organization divides the dynamic memory into stack area (LIFO protocol) heap area
C Programming
ver 2.0
Page 207
Memory Organization
code area global/static area stack free space
heap
C Programming
ver 2.0
Page 208
A Procedure Activation Record or a Stack Frame arguments bookkeeping information (return address) local data local temporaries
ver 2.0 Page 209
Registers
Registers may be used to store temporaries, local variables, or even global variables. When a processor has many registers, the entire static area and whole activation records may be kept in the registers. Special purpose registers: Program counter (PC) Stack pointer (SP)
C Programming
ver 2.0
Page 210
Calling Sequence
The calling sequence is the sequence of operations that must occur when a procedure or function is called. Allocation of memory for the activation record The computation and storing the arguments Storing and setting registers
C Programming
ver 2.0
Page 211
Return Sequence
The return sequence is the sequence of operations needed when a procedure or function returns. The placing of the return value where it can be accessed by the caller Readjustment of registers Releasing of activation record memory
C Programming
ver 2.0
Page 212
Each procedure has only a single activation record, which is allocated statically prior to execution. Such environment can be used to implement a language in which: There are no pointers or dynamic allocation, Procedures cannot be called recursively. Example: COBOL & FORTRAN
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 213
C Programming
ver 2.0
Page 214
Global Procedures
In a language where all procedures are global (the C language), a stack-based environment requires two things:
1. A pointer to the current activation record to allow access to local variables.
This pointer is called the frame pointer (fp) and is usually kept in a register.
C Programming
ver 2.0
Page 215
.. . . . }
return instruction
. . . }
C Programming
ver 2.0
Page 216
C Programming
ver 2.0
Page 217
Access to Variables
In static environment, parameters and local variables can be accessed by fixed addresses. In a stack-based environment, they must be found by offset from the current frame pointer. In most languages, the offset for each local variable is still statically computable by compiler.
The declarations of a procedure are fixed at compile time and the memory size to be allocated for each declaration is fixed by its data type.
C Programming
ver 2.0
Page 218
Calling Sequence
1. Compute the arguments and store them in their correct positions in the new activation record (pushing them in order onto the runtime stack) 2. Store (push) the fp as the control link in the new activation record. 3. Change the fp so that it points to the beginning of the new activation record (fp=sp) 4. Store the return address in the new activation record. 5. Jump to the code of the procedure to be called.
C Programming
ver 2.0
Page 219
Return Sequence
1. 2. 3. 4. Copy the fp to the sp Load the control link into the fp Jump to the return address Change the sp to pop the arguments.
C Programming
ver 2.0
Page 220
Variable Length-Data
There is a possibility that data may vary, both in the number of data objects and the size of each object. Two examples:
The number of arguments in a call may vary from call to call. The size of an array parameter or a local array variable may vary from call to call.
C Programming
ver 2.0
Page 221
Local Temporaries
Local temporaries are partial results of computations that must be saved across procedure calls. Example: x[i]=(i+j)*(i/k+f(i));
Three partial results need to be saved: the address of x[i], the sum i+j, and the quotient i/k.
C Programming
ver 2.0
Page 223
Nested Declarations
Nested declarations can be treated in a similar way to temporary expressions, allocating them on the stack as the block is entered and deleting them on exit. void p (int x, double y) { char a; int i; { double x; // block A int y; } { double x; // block B int j; } { char *a; // block C int k; } }
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 224
Command-Line Arguments
The function main( ) can receive arguments from the command line. Information can be passed to the function main( ) from the operating system prompt as command line arguments. The command line arguments are accepted into special parameters to main( ), namely, argc and argv. Their declarations are as follows: main(int argc, char * argv[ ])
C Programming
ver 2.0
Page 226
Command-Line Arguments
argv 100
argv[0]
argc = 3
200
\0
argv[1]
300 S h e r l o c k H o l m e s \0 s
C Programming
ver 2.0
Page 229
C Programming
ver 2.0
Page 230
Storage Qualifiers
The storage qualifier determines the lifetime of the storage associated with the identified variable. A variable also has a scope, which is the region of the program in which it is known. The storage qualifiers in C are: auto static extern register
C Programming ver 2.0 Page 231
automatic Variables
automatic variables are local to a block, and are discarded on exit from the block. Block implies a function block, a conditional block, or an iterative block. Declarations within a block create automatic variables if no storage class specification is mentioned, or if the auto specifier is used. Variable declarations, therefore, are by default, auto.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 232
automatic Variables
#include<stdio.h> main( ) { char var; while ((var = getchar( )) != *) { if ((var >= A) && (var <= Z)) { uppercase_count( ); } } } uppercase_count( ) { auto int counter = 0; counter ++; }
C Programming ver 2.0 Page 233
Global Variables
Global variable is defined outside all functions. A typical convention of defining global variables is before the main( ) function. A variable declared as global is visible to the function main( ) as well as to any other functions called from main( ). A variable defined as global has file scope, that is, it is visible to all the functions written within the scope of a program file.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 234
Global Variables
/* A sample C program */ # include <stdio.h> int sum( ); /* function prototype */ int a=10, b=20; /* a and b are global variables, visible to main( ) as well as to sum( ) */ main() { int c; c = sum(); printf(%d+%d = %d \n,a,b,c); } int sum() { return(a+b); }
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 235
Static Variables
Static variables may be local to a block or external to all blocks, but in either case retain their values across exit from, and reentry to functions and blocks. Within a block, including a block that provides the code for a function, static variables are declared with the keyword static. Let us rewrite the code for the example involving auto variables to incorporate the declaration of static variables.
C Programming
ver 2.0
Page 236
Static Variables
#include<stdio.h> main( ) { char var; while ((var = getchar( )) != *) { if ((var >= A) && (var <= Z)) { uppercase_count( ); } } } uppercase_count( ) { static int counter = 0; counter ++; }
C Programming
ver 2.0
Page 237
C Programming
ver 2.0
Page 238
Extern Variables
Variables declared as extern are useful especially when building libraries of functions. This means that functions required to run a program can be saved in separate program files, which can be compiled separately, and linked up with the file containing the function main( ) prior to running the program. In such a case, if the functions use the same global variables, then their declarations would involve the use of the extern qualifier
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 239
Extern Variables
Program a.c int val /* global */ main( ) { printf(Enter value); scanf(%d, &val); compute( ); /* function call */ } Program b.c compute( ) { extern int val; /* implies that val is defined in another program containing a function to which the current function will be linked to at the time of compilation */ }
C Programming
ver 2.0
Page 240
Extern Variables
From the preceding example, it is clear that though val is declared global in the function main( ) in program a.c, it has been declared again within the function compute( ), which is defined in its own program file, b.c. However, the qualifier extern has been added to its declaration. The extern qualifier in the function compute( ) in b.c indicates to the compiler (when a.c and b.c are compiled together) that the variable used in this program file has been declared in another program file.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 241
Implication
ASCII value of the character of the first string is less than the ASCII value of the corresponding character of the second string ASCII value of the character of the first string is less than the ASCII value of the corresponding character of the second string If the strings are identical
Example
i = strcmp(XYZ, xyz)
Greater than 0
i = strcmp(xyz, XYZ)
Equal to 0
i = strcmp(XYZ, XYZ)
C Programming
ver 2.0
Page 242
C Programming
ver 2.0
Page 243
C Programming
ver 2.0
Page 244
C Programming
ver 2.0
Page 245
a number, and returns its double equivalent. For example, if the string str contains the value 1234, then the following statement: i = atoi(str); will cause i to have the value 1234.000000 To use the function atof( ) in any function, its prototype must be declared at the beginning of the function where it is used: double atof( )
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 247
C Programming
ver 2.0
Page 248
C Programming
ver 2.0
Page 249
Summary
In this session, you learnt to: Write programs that invoke functions through a:
Call by value Call by reference
Define function prototypes Describe the function call mechanism Pass arguments to main( ) in the form of command-line arguments Use the Auto, Static, and Extern storage qualifiers Use string handling functions, conversion functions, and functions for formatting strings in memory
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 250
C Programming
ver 2.0
Page 251
C Programming
ver 2.0
Page 252
Objectives
In this session, you will learn to: Use pointers of type FILE when performing file I/O Perform Input/Output with files Use character-based file input/output functions Use string-based file input/output functions Perform random access on files using the functions
fseek( ) ftell( ) rewind( ) feof( )
C Programming
ver 2.0
Page 253
Files
A collection of logically related information Examples: An employee file with employee names, designation, salary etc. A product file containing product name, make, batch, price etc. A census file containing house number, names of the members, age, sex, employment status, children etc. Two types: Sequential file: All records are arranged in a particular order Random Access file: Files are accessed at random
C Programming
ver 2.0
Page 254
File Access
The simplicity of file input/output in C lies in the fact that it essentially treats a file as a stream of characters, and accordingly facilitates input/output in streams of characters. Functions are available for character-based input/output, as well as string-based input/output from/to files. In C, there is no concept of a sequential or an indexed file. This simplicity has the advantage that the programmer can read and write to a file at any arbitrary position.
C Programming
ver 2.0
Page 255
File Access
The examples so far have involved reading from standard input, and writing to standard output, which is the standard environment provided by the operating system for all applications. You will now look at the process that a program needs to follow in order to access a file that is not already connected to the program. Before a file can be read from, or written into, a file has to be opened using the library function fopen( )
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 256
File Access
The function fopen( ) takes a file name as an argument, and interacts with the operating system for accessing the necessary file, and returns a pointer of type FILE to be used in subsequent input/output operations on that file. This pointer, called the file pointer, points to a structure that contains information about the file, such as the location of a buffer, the current character position in the buffer, whether the file is being read or written, and whether errors, or end of file have occurred.
C Programming
ver 2.0
Page 257
File Access
This structure to which the file pointer point to, is of type FILE, defined in the header file <stdio.h>. The only declaration needed for a file pointer is exemplified by:
FILE *fp; FILE *fopen(char *name, char *mode); fp = fopen( file name, mode);
Once the function fopen( ) returns a FILE type pointer stored in a pointer of type FILE, this pointer becomes the medium through which all subsequent I/O can be performed.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 258
C Programming
ver 2.0
Page 259
r+ w+ a+
C Programming
ver 2.0
Page 260
C Programming
ver 2.0
Page 261
C Programming
ver 2.0
Page 263
C Programming
ver 2.0
Page 264
C Programming
ver 2.0
Page 265
C Programming
ver 2.0
Page 267
C Programming
ver 2.0
Page 268
C Programming
ver 2.0
Page 269
The statement scanf( %6s%d, string, &i) can be rewritten using the function fscanf( ) as:
fscanf(stdin, %6s%d, string, &i);
C Programming
ver 2.0
Page 272
Random Access
Input from, or output to a file is effective relative to a position in the file known as the current position in the file. For example, when a file is opened for input, the current position in the file from which input takes place is the beginning of the file. If, after opening the file, the first input operation results in ten bytes being read from the file, the current position in the file from which the next input operation will take place is from the eleventh byte position.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 273
Random Access
It is therefore clear that input or output from a file results in a shift in the current position in the file. The current position in a file is the next byte position from where data will be read from in an input operation, or written to in an output operation. The current position advances by the number of bytes read or written. A current position beyond the last byte in the file indicates end of file.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 274
Random Access
For example, when a file is opened for input, the current position in the file from which input takes place is the beginning of the file. If, after opening the file, the first input operation results in ten bytes being read from the file, the current position in the file from which the next input operation will take place is from the eleventh byte position. This is sequential access, in which a file is opened, and you start reading bytes from the file sequentially till end of file. The same argument cab be extended to sequential write.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 275
Random Access
In sharp contrast to sequential access is random access that involves reading from any arbitrary position in the file, or writing to any arbitrary position in the file. Random access therefore mandates that we must have a mechanism for positioning the current position in the file to any arbitrary position in the file for performing input or output. To facilitate this, C provides the fseek( ) function, the prototype of which is as follows:
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 276
current offset
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 278
current offset
C Programming
ver 2.0
Page 279
current offset
C Programming
ver 2.0
Page 280
current offset
C Programming
ver 2.0
Page 281
After invoking rewind( ), the current position in the file is always the first byte position, i.e., at the beginning of the file.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 282
C Programming
ver 2.0
Page 283
C Programming
ver 2.0
Page 284
ftell returns the current file position for stream, or -1 on error. The prototype declaration for the function feof( ) is:
int feof(FILE *fp)
feof returns non-zero if the end of file indicator for stream is set.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 287
Summary
In this session you learnt to: Use pointers of type FILE when performing file I/O Perform Input/Output with files Use character-based file input/output functions Use string-based file input/output functions Perform random access on files using the functions
fseek( ) ftell( ) rewind( ) feof( )
C Programming
ver 2.0
Page 288
C Programming
ver 2.0
Page 289
C Programming
ver 2.0
Page 290
Objectives
In this session, you will learn to: Trace down the genesis of user-defined data types Declare user-defined data types, namely
Structures Unions Enumerations
Use pointers to structures and unions Declare arrays of structures Pass structures to functions Use the typedef declaration for easier and compact coding Use the functions fread( ) and fwrite( ) to read and write structures to and from files
C Programming ver 2.0 Page 291
C Programming
ver 2.0
Page 294
Declaring a Structure
The C language provides the struct keyword for declaring a structure. The following is a structure declaration for employee attributes.
struct empdata { int empno; char name[10]; char job[10]; float salary; };
C Programming
ver 2.0
Page 297
Declaring a Structure
The keyword struct introduces a structure declaration, which is a list of declarations enclosed in braces. An optional name called a structure tag may follow the word struct, as with employee in the previous example. The tag names this kind of structure, and can be used subsequently as a shorthand for the part of the declaration in braces. A struct declaration defines a type.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 298
C Programming
ver 2.0
Page 300
Declaring a Structure
Declaring a structure only defines a template or a blueprint for a data type. It does not therefore result in the allocation of memory. Memory is allocated only when a variable of a structure type is declared in the program. Till a variable of a structure type is created, a structure declaration is only identified as a type, and no memory is allocated. Even for fundamental data types, the compiler does not allocate memory for types. Rather, it allocates memory for implementations of fundamental data types, in short, memory is allocated only for a variable declaration.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 301
C Programming
ver 2.0
Page 302
C Programming
ver 2.0
Page 303
C Programming
ver 2.0
Page 304
product_unit_price[salesptr->product_number 1] }
C Programming
ver 2.0
Page 305
Array of Structures
Just as it is possible to declare arrays of primitive data types, it should also be possible to declare arrays of structures as well. Consider the structure declaration for the employee details used earlier.
struct empdata { int empno; char name[10]; char job[10]; float salary; };
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 306
Array of Structures
If one were to define an array of structure variables, one would do so as follows:
struct empdata employee_array[4];
The rationale for declaring an array of structures becomes clear when one wants to improve I/O efficiency in a program. Once an array of structures is defined, it is possible to read in a block of records from a file using an appropriate function (fread( )), the details of which you will see shortly.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 307
C Programming
ver 2.0
Page 308
Here, the first parameter &salesvar is the address of the structure variable salesvar into which 1 record is to be read from the file pointed to by the FILE type pointer fp. The second parameter specifies the size of the data to be read into the structure variable.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 310
Union
Can hold objects of different types and sizes at different times Syntax similar to structure but meaning is different All members of union share same storage space Only the last data member defined can be accessed Means of conserving memory union declaration similar to struct declaration eg. union u_type { int i; char ch; }; union u_type cnvt;
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 312
Unions
In cnvt, both integer i and character ch share the same memory location. Of course, i occupies 2 bytes (assuming 2-byte integers, and ch uses only one byte. i
Byte 0
Byte 1
ch
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 313
Unions
To access a member of a union, use the same syntax that you would use for structures: the dot and arrow operators. If you are operating on the union directly, use the dot operator. If the union is accessed through a pointer, use the arrow operator. For example, to assign the integer 10 to element i of cnvt, write cnvt.i = 10;
C Programming
ver 2.0
Page 314
Unions
In the following code snippet, a pointer to cnvt is passed to a function: void func1( union u_type *un) { un->i = 10; /* assign 10 to cnvt using function */ } Using a union can aid in the production of machineindependent (portable) code. Because the compiler keeps track of the actual size of the union members, no unnecessary machine dependencies are produced.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 315
Unions
Unions are used frequently when specialized type conversions are needed because you can refer to the data held in the union in fundamentally different ways. Consider the problem of writing a short integer to a disk file. The C standard library defines no function specifically designed to write a short integer to a file. While you can write any type of data to a file using fwrite( ), using fwrite( ) incurs excessive overhead for such a simple operation.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 316
Unions
However, using a union, you can easily create a function called putw( ), which represents the binary representation of a short integer to a file one byte at a time. The following example assumes that short integers are 2 bytes long. First, create a union consisting of one short integer and a 2-byte character array: union pw { short int i; char ch[2]; };
C Programming
ver 2.0
Page 317
Unions
Now, you can use pw to create the version of putw( ) shown in the following program: #include <stdio.h> union pw { short int i; char ch[2]; }; int putw( short int num, FILE *fp);
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 318
Unions
int main (void) { FILE *fp; fp = fopen( test.tmp, wb+); putw(1000, fp); /* write the value 1000 as an integer */ fclose( fp ); return 0; }
C Programming
ver 2.0
Page 319
Unions
int putw( short int num, FILE *fp) { union pw word; word.i = num; fputc( word.ch[0], fp); /* write first half */ fputc( word.ch[1], fp); /* write second half */ } Although putw( ) is called with a short integer, it can still use the standard function fputc( ) to write each byte in the integer to a disk file one byte at a time.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 320
Enumeration
Is a set of named integer constants that specify all the legal values a variable of that type can have. The keyword enum signals the start of an enumeration type. The general form for enumeration is enum enum-type-name { enumeration list } variable_list; enum coin { penny, nickel, dime, quarter, half_dollar, dollar}; enum coin money;
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 321
Enumeration
Given these declarations, the following types of statements are perfectly valid: money = dime; if (money = = quarter) printf( Money is a quarter. \n); The key point to understand about an enumeration is that each of the symbols stands for an integer value. As such, they may be used anywhere that an integer may be used.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 322
Enumeration
Each symbol is given a value one greater than the symbol that precedes it. The value of the first enumeration symbol is 0. Therefore, printf( %d %d, penny, dime); displays 0 2 on the screen. You can specify the value of one or more of the symbols by using an initializer. Do this by following the symbol with an equal sign and an integer value.
C Programming
ver 2.0
Page 323
Enumeration
For example, the following code assigns the value of 100 to quarter: enum coin { penny, nickel, dime, quarter=100, half_dollar, dollar}; Now, the values of these symbols are: penny 0 nickel 1 dime 2 quarter 100 half_dollar 101 dollar 102
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 324
Enumeration
One common but erroneous assumption about enumerations is that the symbols can be input and output directly. This is not the case. For example, the following code fragment will not perform as desired: money = dollar; printf( %s, money); Dollar is simply a name for an integer; it is not a string.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 325
Enumeration
For the same reason, you cannot use this code to achieve the desired results: /* this code is wrong */ strcpy (money, dime); That is, a string that contains the name of a symbol is not automatically converted to that symbol. Actually creating code to input and output enumeration symbols is quite tedious (unless you are willing to settle for their integer values).
C Programming
ver 2.0
Page 326
Enumeration
For example, you need the following code to display, in words, the kind of coins that money contains:
switch (money) { case penny : printf( penny); break; case nickel : printf( nickel); break; case dime : printf( dime); break; case quarter : printf( quarter); break; case half_dollar : printf( half_dollar); break; case dollar : printf( dollar); break; }
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 327
Typedef Statements
Creates synonyms (aliases) for previously defined datatypes Used to create shorter type names Format: typedef type new-type; Example: typedef struct Card * CardPtr; defines a new type name CardPtr as a synonym for type struct Card * typedef does not create a new datatype Only creates an alias
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 328
Summary
In this session, you learnt to: Trace down the genesis of user-defined data types Declare user-defined data types, namely
Structures Unions Enumerations
Use pointers to structures and unions Declare arrays of structures Pass structures to functions Use the typedef declaration for easier and compact coding Use the functions fread( ) and fwrite( ) to read and write structures to and from files
C Programming ver 2.0 Page 329
C Programming
ver 2.0
Page 330
Chapter 8 Recursion
C Programming
ver 2.0
Page 331
Objectives
In this session, you will learn to: Define a recursive function Describe how to write a recursive function Describe recursive calls to a function using the runtime stack Define, Declare, and Use Function Pointers
C Programming
ver 2.0
Page 332
Introduction
Many concepts typically in mathematics are defined by presenting a process leading up to that concept. For example, T is defined as ratio of the circumference of a circle to its diameter. This is equivalent to the following set of instructions:
Obtain the circumference of a circle Obtain its diameter Divide circumference by the diameter and call the result T Clearly, the process specified must terminate with a definite result.
C Programming
ver 2.0
Page 333
It is cumbersome for you to list the formula for the factorial of each integer. To avoid any shorthand, and to avoid an infinite set of definitions, but yet to define the function precisely, you may present an algorithm that accepts an integer n and returns the value of n!.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 336
Such an algorithm is iterative because it calls for the explicit repetition of some process until a certain condition is met. This function can be translated readily into a C function that returns n! when n is input as a parameter.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 337
Multiplying n by the product of all integers from n 1 to 1 yields the product of all integers from n to 1.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 338
C Programming
ver 2.0
Page 339
C Programming
ver 2.0
Page 341
C Programming
ver 2.0
Page 343
C Programming
ver 2.0
Page 345
C Programming
ver 2.0
Page 349
C Programming
ver 2.0
Page 350
C Programming
ver 2.0
Page 351
Mechanics of Recursion
In the statement y = fact(x), the function fact( ) makes a recursive call to itself. This is the essential ingredient of a recursive routine. The programmer assumes that the function being computed has already been written, and uses it in its own definition. However, the programmer must ensure that this does not lead to an endless series of calls.
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 352
Mechanics of Recursion
It is important to examine the execution of this function when it is called by another program. For example, the calling program (main( )) contains the statement: printf(%d, fact(4)); When the calling function calls fact( ), the parameter n is set equal to 4. Since n is not 0, x is set equal to 3. At that point, fact( ) is called a second time with an argument of 3.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 353
Mechanics of Recursion
Therefore, the function fact( ) is reentered and the local variables (x and y) and parameter (n) of the block are reallocated. Since execution has not yet left the first call of fact( ), the first allocation of these variables remains. Thus, there are two generations of each of these variables in existence simultaneously in the stack for the first call, and the second recursive call to the function fact( ) respectively.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 354
Mechanics of Recursion
From any point within the second execution of fact( ), only the most recent copy of these variables can be referenced. In general, each time the function fact( ) is entered recursively, a new set of local variables and parameters is allocated on the stack, and only this new set may be referenced within that call of fact( ). When a return from fact( ) to a point in a previous call takes place, the most recent allocation of these variables is freed from the stack when the function returns, and the previous copy is reactivated (belonging to the previous recursive call to the function fact( )).
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 355
Mechanics of Recursion
This previous copy is the one that was allocated upon the original entry to the previous call and is local to that call. This description suggests the use of a stack to keep the successive generations of local variables and parameters. This stack is maintained by the C system and is invisible to the programmer. Each time that a recursive function is entered, a new allocation of its variables is pushed on top of the stack.
C Programming
ver 2.0
Page 356
Mechanics of Recursion
Any reference to a local variable or parameter is through the current top of the stack. When the function returns, the stack is popped, the top allocation is freed, and the previous allocation becomes the current top of the stack to be used for referencing local variables and parameters. You will now see how this mechanism is applied in computing the factorial function.
C Programming
ver 2.0
Page 357
Mechanics of Recursion
The following figure contains a series of snapshots of the stack for the variables n, x, and y as execution of the fact( ) function proceeds. Initially, the stacks are empty, as illustrated in (a). After the first call on fact( ) by the calling procedure, the situation is as shown in (b) with n equal to 4. The variables x and y are allocated but not initialized.
C Programming
ver 2.0
Page 358
Mechanics of Recursion
Since n does not equal 0, x is set to 3 and fact(3) is called as shown in (c). The new value of n does not equal 0; therefore, x is set to 2 and fact(2) is called as shown in (d). This continues until n equals 0 as shown in(f). At that point, the value 1 is returned from the call to fact(0).
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 359
Mechanics of Recursion
Execution resumes from the point at which fact(0) was called, which is the assignment of the returned value to the copy of y declared in fact(1). This is shown by the status of the stack shown in figure (g), where the variables allocated for fact(0) have been freed and y is set to 1. The statement return (n * y) is then executed, multiplying the top values of n and y to obtain 1, and returning the value to fact(2) as shown in (h).
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 360
Mechanics of Recursion
This process is repeated twice more, until finally the value of y in fact(4) equals 6. The statement return (n * y) is executed one more time. The product 24 is returned to the calling function where it is printed by the statement printf(%d, fact(4)); Note that each time that a recursive routine returns, it returns to the point immediately following the point from which it was called.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 361
Mechanics of Recursion
Thus, the recursive call to fact(3) returns to the assignment of the result to y within fact(4), but the call to fact(4) returns to the printf( ) statement in the calling function.
(a) initially (b) fact(4) (c) fact(3) (c) fact(2)
2 3 4
n x y n
* 2 3
n x
* * *
y
* 3
n x
* *
y
3 4
*
x
*
y
C Programming
ver 2.0
Page 362
Mechanics of Recursion
(e) fact(1)
(f) fact(0)
(g) y = fact(0)
(h) y = fact(1)
0 1 2 3 4 n x * 1 2 3 * * * * 1 2 3 4 n x
* 0 1 2 3
* * * *
1 2 3 4
0 1 2 3 x y
1 * * * 2 3 4 n 1 2 3 x y 1 * *
C Programming
ver 2.0
Page 363
Mechanics of Recursion
(i) y = fact(2)
(j) y = fact(3)
Pritnf(%d, fact(4))
3 4 n x
2 3 y
2 * n 4 x 3 y 6 n x y
The stack at various times during execution. An asterisk indicates an uninitialized value.
C Programming
ver 2.0
Page 364
Function Pointers
Function Pointers are pointers, i.e. variables, which point to the address of a function. You must keep in mind, that a running program gets a certain space in the main-memory. Both, the executable compiled program code and the used variables, are put inside this memory. Thus a function in the program code is, like e.g. a character field, nothing else than an address.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 365
Function Pointers
It is only important how you, or better, your compiler/processor, interpret the memory a pointer points to. When you want to call a function fn() at a certain point in your program, you just put the call of the function fn() at that point in your source code. Then you compile your code, and every time your program comes to that point, your function is called. But what can you do, if you don't know at build-time which function has got to be called? Or, invoke functions at runtime.
Copyright Wipro Technologies Talent Transformation C Programming ver 2.0 Page 366
Function Pointers
You want to select one function out of a pool of possible functions. However you can also solve the latter problem using a switch-statement, where you call the functions just like you want it, in the different branches. But there's still another way: Use a function pointer! Consider the example on the following slide:
Copyright Wipro Technologies Talent Transformation
C Programming
ver 2.0
Page 367
C Programming
ver 2.0
Page 368
C Programming
ver 2.0
Page 371
Summary
In this session, you learnt to: Define a recursive function Describe how to write a recursive function Describe recursive calls to a function using the runtime stack Define, Declare, and Use Function Pointers
C Programming
ver 2.0
Page 373