C Programming Note
C Programming Note
2.1 Introduction of C
“C’ seems a strange name for a programming language but it is one of the most widely used languages
in the world. C was introduced by Dennis Ritchie in 1972 at Bell Laboratories as a successor of the
language called B (Basic Combined Programming Language – BCPL). Since C was developed along
with the UNIX operating system it is strongly associated with UNIX. UNIX was developed at Bell
Laboratories and it was written almost entirely in C.
For many years, C was used mainly in academic environments. However with the release of C compilers
for commercial use and increasing popularity of UNIX, it began to gain wide-spread interest among
computer professionals. Various languages such as C++, Visual C++, Java and C# have branched away
from C by adding object-orientation and GUI features. Today C compilers are available for a number of
operating systems including all flavors of UNIX, Linux, MS-DOS, Windows and Apple Mac.
C is a robust language whose rich set of built-in functions and operations can be used to write any
complex program. C is well suited to write both commercial applications and system software since it
incorporates features of high-level languages and Assembly language. Programs written in C are
efficient and fast. Most C programs are fairly portable; that is with little or no modification and
compiling, C programs can be executed on different operating systems.
The syntax and coding style of C is simple and well structured. Due to this reason most of the modern
languages such as C++, Java and C# inherit C coding style . Therefore it is one of the best languages to
learn the art of programming. C is also suitable for many complex engineering applications.
Preprocessing is performed by a program called the preprocessor. It modifies the source code (in
memory) according to preprocessor directives (example: #define) embedded in the source code. It
also strips comments and unnecessary white spaces from the source code. Preprocessor does not modify
the source code stored on disk, every thing is done on the copy loaded into the memory.
Compilation really happens then on the code produced by the preprocessor. The compiler translates the
preprocessor-modified source code into object code (machine code). While doing so it may encounter
syntax errors. If errors are found it will be immediately notified to the programmer and compiling will
discontinue. If the compiler finds any non-standard codes or conditions which are suspicious but
legitimate it will notify to the programmer as warnings and it continues to compile. A well written
C programming 1 Shree Prasad Aryal
program should not have any compilation errors or warnings.
Linking is the final step and it combines the program object code with other object codes to produce the
executable file. The other object codes come from run-time libraries, other libraries, or object files that
the programmer has created. Finally it saves the executable code as a file on the disk. If any linker errors
are encountered the executable file will not be generated.
Literals are factual data represented in a language. Numeric constants are an uninterrupted sequence of
digits (possibly containing a period). Numerical values such as 123, 10000 and 99.99 are examples.
Character constants represents a single character and it is surrounded by single quotation mark (‘).
Characters such as ‘a’, ‘A’, ‘$’ and ‘4’ are examples. A sequence of characters surrounded by double
quotation marks (inverted comma “”) is called a string constant. A statement such as “I like ice cream.”
is a string constant.
Identifiers are also referred as names. A valid identifier is composed of a letter followed by a sequence of
letters, digits or underscore (_) symbols. An identifier must begin with a letter and the rest can be
letters, digits or underscores. Identifies are case sensitive; therefore the identifier a bc is different from
ABC or Abc.
C identifiers can be very long and so it allows descriptive names like “number_of_students” and
“Total_number_of_cars_produced_per_year”. Sometimes a C compiler may consider only the first 32
characters in an identifier. While defining identifiers programmers should follow some of the naming
standards for better readability of the program. One such standard is the use of underscores symbol (_)
to combine two words (example: sub_total).
Operators are used with operands to build expressions. For example “4+5” is an expression containing
two operands (4 and 5) and one operator (+ symbol). C supports large number of mathematical and
logical operators such as +, -, *, /, %, ^, &, && , |, ||, etc. Operators will be discussed in chapter
3.
The C language uses several symbols such as semicolons (;), colons (:), commas (,), apostrophes (‘),
quotation marks (“”), braces ([]), brackets ({}), and parentheses (()) to group block of code as a single
unit.
2.6 Variables
A variable has a value that can change. It is a memory location that can hold a value of a certain data
type. Programmers refer to a variable by its name (identifier) so that it can be accessed during the
course of the program. Programmers cannot use any of the keywords as variable names.
2.6.1 Declaring Variables
In order to use a variable in C, the programmer must first declare it specifying the data type. The most
important restriction on using a variable in C is that they have to be declared at the beginning of the
program. The syntax to declare a new variable is to first write the data type then followed by a valid
variable identifier as given in the following examples:
int a;
float total;
unsigned int index_no;
short int number_of_students;
Above set of expressions declared, variables “a” as an integer, “tota l” as a floating point number,
“index_no” as unsigned integer (since there are no negative index numbers) and
“number_of_students” as a short integer.
Multiple variables belonging to the same data type can be defined as separate set of expressions or by
listing variable names one after the other (should be separated by a coma sign (,)).Consider the
following example s:
int a;
int b;
float total;
float sub total;
_
above variables can also be defined as:
int a,b;
float total, sub_total;
C programming 6 Shree Prasad Aryal
After declaring a variable it should be initialised with a suitable value. In C, an uninitialised variable
can contain any garbage value therefore the programmer must make sure all the variables are initialised
before using them in any of the expressions. Initialising a variable can be done while declaring it, just
after declaring it or later within the code (before accessing/evaluating its value within an expression).
In initialising a variable any of the following three approaches are valid:
int a;
a=10;
int a=10;
2.6.2 Constants
The value of a constant cannot be changed after an initial value is assigned to it. The C language
supports two types of constants; namely declared constants and defined constants. Declared constants
are more common and they are defined using the keyword const. With the const prefix the
programmer can declare constants with a specific data type exactly as it is done with variables.
const float pi = 3.141;
Programmers can define their own names for constants which are used quite often in a program.
Without having to refer to a variable such a constant can be defined simply by using the #define pre-
processor directive. These are called defined constants. Following expression illustrates the use of the
#define pre-processor directive
#define pi 3.141
or
}
Three variables are declared (a, b and sum) in Program-2.10. Values of “a” and “b” are to be read
from the keyboard using the scanf function, while the value of the variable “sum” is calculated as
the summation of “a” and “b”. The scanf function uses the same set of formatting characters as the
printf function to describe the type of expected input.
Note that the scanf function uses the variables “a” and “b”as “&a” and “&b”. The symbol “&” is
called the address of operator. The string “&a” represents the memory address containing variable
“a” and is called a pointer (see Section 8).
When the program executes, it waits for the user to type the value of “a” followed by the E nte r key
and then it waits for the value of “b” followed by another the Enter key. The supplied input values
can be separated either by pressing Enter key or by leaving a blank space between the numbers. Both
of the following inputs are valid for Program-2.10.
Operators
Expressions can be built up from literals, variables and operators. The operators define how the
variables and literals in the expression will be manipulated. C supports several types of operators and
they can be classified as:
· Assignment operator
· Arithmetic operators
· Relational operators
· Logical operators
· Bitwise operators
· Special operators
· Pointer operators
Pointer operators and special operators will not be covered in this chapter. They will be introduced later
under relevant sections.
3.1 Assignment Operator
The assignment operator is the simple equal sign (=). The assignment operator is used to assign a value
to a variable. The format of an assignment statement is:
variable-name = expression;
The expression can be a single variable or a literal, or it may contain variables, literals and operators.
The assignment operation always takes place from right to left. Consider the following set of examples:
Executing Program-3.1 with “a” as 5 and “b” as 2 will display the following:
Enter a: 5
Enter b: 2
a+b = 7
a-b = 3
a*b = 10
a/b = 2 a
%b = 1
After executing above segment of code, “a” will be 4 and “x” will be 4.
In line 3, first the variable “a” is incremented before assigning it to variable “x”. Consider the
following segment of code.
int a, x; a
= 3; x =
a++;
After executing above code segment “a” will be 4 and “x” will be 3.
In the second approach in line 3 first “a” is assigned to “x” and then “a” is incremented.
Exercise 3.1 – Predict the values of variables “a”, “b”, “sum1” and “sum2” if the following code
segment is executed.
int a, b;
a = b = 2;
sum1 = a + (++b);
sum2 = a + (b++);
3.2.2 Precedence and Associatively of Arithmetic Operators
Precedence defines the priority of an operator while associativity indicates which variable(s) an operator
is associated with or applied to. Table 3.2 illustrates the precedence of arithmetic operators and their
associativity.
Executing Program-3.2 with character “b” as the input will display the following:
Character to convert: b
Converted character: B
Executing Program-3.2 with character “Q” as the input will display the following:
Character to convert : Q
Converted character : q
3.4.1 Shift Operators
Shift operators allow shifting of bits either to left or right. We know that 8 is represented in binary as:
8 = 00001000
and when it is shifted by one bit to right, we get:
8 = 00001000 ‡ 00000100 = 4
Similarly when the number is shifted by one bit to left, we get:
16 = 00010000 f l 00001000 = 8
The C right shift (> >) operator shifts an 8-bit number by one or more bits to right while left shift (<<)
operator shifts bits to left. Shifting a binary number to left by one bit will multiply it by 2 while shifting
it to right by one bit will divide it by 2. After the shift operation the final result should also be a 8-bit
number, therefore any additional bits are removed and missing bits will be filled with zero.
In general the right shift operator is used in the form:
variable >> number-of-bits
and left shift is given in the form:
variable >> number-of-bits
In the following expression the value in the variable “a” is shift by 2 bits to right:
a >> 2
Table 3.7 summarises all the operators supported by C, their precedences and associativities. However
some operators can be confusing, as they use the same characters (for example , * is used for
multiplication and also to denote pointers). However the following rule will reduce any confusion. The
unary operators (operators with only one operand such as &a (address of a)) have a higher precedence
than the binary operators (operators with two operands such as a*b). When operators have the same
precedence an expression is evaluated left to right.
Table 3. 7 – Precedence of C operators
Operator Precedence Associativity
( ) [ ] -> . Highest Left to right
! ~ ++ --
&* Right to left
*/% Left to right
+- Left to right
<< >> Left to right
< <= > >= Left to right
= = != Left to right
& Left to right
^ Left to right
| Left to right
&& Left to right
|| Left to right
?: Left to right
= += -= *= /= Right to left
, Lowest Left to right
Conditional Control Structures
A Program is usually not limited to a linear sequence of instructions. In real life, a programme usually
needs to change the sequence of execution according to some conditions. In C, there are many control
structures that are used to handle conditions and the resultant decisions. This chapter introduces ifelse
and switch constructs.
{ int marks;
printf("Enter marks: ");
scanf("%d", &marks); //get marks
}
Executing Program-4.1 with different inputs will behave as follows :
Case 1: Enter marks : 73
You have passed the exam!
In the second and third cases, the message “You have passed the exam!” will not be displayed.
More than one statement can be executed as a result of the condition by embedding set of statements in a
block (between two braces {}).
Example 4.1 – Write a program which accepts a number (an amount of money to be paid by a customer
in rupees) entered from the keyboard. If the amount is greater than or equal to 1000 rupees, a 5%
discount is given to the customer. Then display the final amount that the customer has to pay.
First the program needs to check whether the given amount is greater than or equal to 1000; if it is the
case a 5% discount should be given. Then the final amount needs to be displayed. All these are done only
if the condition is TRUE. So instructions which compute discount and final amount should be executed
as a block. Program 4.2 is an implementation of this.
/* Program-4 . 2 * /
#include <stdio.h>
void main()
{
float amount,final_amount, discount;
printf("Enter amount: ");
scanf("%f", &amount); //get amount
}
Executing Program-4.2 with 1250.25 as the keyboard input display the following:
Enter amount: 1250.25
Discount: 62.51 Total:
1187.74
In Program-4.1 if the condition is TRUE, the set of statements inside the block are executed. If the
condition is FALSE (if the amount is less than 1000) those statements will not be executed.
Example 4.2 – Modify Program-4.2 so that it displays the message “No discount…” if the amount is
less than 1000.
Another if clause is required to check whether the amount is less than 1000. The second if clause can be
used before or after the first (existing) if clause. Program-4.3 below has been modified from Program-
4.2 to address this.
/* Program-4 . 3 * /
#include <stdio.h>
void main()
{
float amount,final_amount, discount;
printf("Enter amount: ");
scanf("%f", &amount); //get amount
}
Exercise 4.1 – Modify Program-4.1 so that it displays the message “You are failed!”, if marks are less
than or equal to 50.
In many programs it is required to perform some action when a condition is TRUE and another action
when it is FALSE. In such cases, the if clause can be used to check the TRUE condition and act upon it.
However it does not act upon the FALSE condition. Therefore the expression resulting the FALSE
condition needs to be reorganised. In example 4.2 when we wanted to identify the case where the amount
is not greater than 1000 (the FALSE case) we were checking whether it is less than 1000
(<1000).
The C language allows us to use the if-else structure in such scenarios. You can include both the cases
(TRUE and FALSE) using the if-else structure.
}
Exercise 4.2 – Modify Program-4.1 so that it displays the message “You have passed the exam! ”, if
marks are greater than 50. If not display the message “You have failed!”.
Exercise 4.3 – Write a program to identify whether a number input from the keyboard is even or odd. If
it is even, the program should display the message “Number is even”, else it should display “Number is
odd”.
// if over if(marks
75 > 75)
printf("Your grade is: A");
// if betweenelse 50 & 7
if(marks >= 50 && marks <75)
5
printf("Your grade is: B");
// if betweenelse 25 & 5
if(marks >= 25 && marks <50)
0
printf("Your grade is: C");
} else
Notice that printf ("Your grade is: F"); // if less than 25 in Program-
4.5, some of the conditional expressions inside the if clause are not as simple as they were earlier. They
combine several expressions with logical operators such as AND (&&) and OR (||). These are called
compound relational tests.
Due to the top down executio n of the if-else-if ladder Program-4.5 can also be written as follows :
/* Program-4 . 6 * /
#include <stdio.h>
void main()
{
int marks;
printf("Enter marks: ");
scanf("%d", &marks); //get marks
}
In Program-4.6, when the marks are entered from the keyboard the first expression (marks > 75) is
evaluated. If marks is not greater than 75, the next expression is evaluated to see whether it is greater
than 50. If the second expression is not satisfied either, the program evaluates the third expression and so
on until it finds a TRUE condition. If it cannot find a TRUE expression statement(s) after the else
keyword will get executed.
4.4 Nesting Conditions
Sometimes we need to check for multiple decisions. This can be accomplished by two approaches; using
compound relational tests or using nested conditions. When conditions are nested the if-else/ifelse-if
construct may contain other if-else/if-else-if constructs within themselves. In nesting you must be careful
to keep track of different ifs and corresponding elses. Consider the following example:
if (a>=2)
if (b >= 4)
printf("Result 1");
else
printf("Result 2");
An else matches with the last if in the same block. In this example the else corrosponds to the second
if. Therefore if both a >= 2 AND b >= 4 are TRUE “Res u lt 1” will be displayed; if a>= 2 is
TRUE but if b >= 4 is FALSE “Res u lt 2” will be displayed. If a >= 2 is FALSE nothing will be
displayed. To reduce any confusion braces can be used to simplify the source code. Therefore the above
can be rewritten as follows:
if (a>=2)
{
if (b >= 4)
printf("Result 1 " )
else ;
printf("Result 2 " )
} ;
In the above, if else is to be associated with the first if then we can write as follows:
if (a>=2)
{
if (b >= 4)
printf("Result 1");
} else
printf("Result 2");
Exercise 4.4 – Rewrite the program in Example 4.3 using nested conditions (i.e. using braces ‘{‘ and ‘}’
.
Example 4.4 – A car increases it velocity from u ms-1 to v ms-1 within t seconds. Write a program to
calculate the acceleration.
The relationship among acceleration (a), u, v and t can be given as v= u+ at . Therefore the v u
accel
eration can be found theformula_______________
by a = . In the program we implement users can input t
any values for u, v and t. However, to find the correct acceleration t has to be non zero and positive
(since we cannot go back in time and a number should not be divided by zero). So our program should
make sure it accepts only the correct inputs. The Program-4.7 calculates the acceleration given u, v and t.
if (t >= 0)
{
a = (v-u) /t;
printf("acceleration is: %.2f m/s", a);
} else
printf ("Incorrect time");
/* Program-4 . 8 * /
#include <stdio.h>
void main()
{
int a,b;
printf("Enter value of a: ");
scanf("%d", &a); //get starting velocity
b = a > 50 ? 1 : 2;
printf("Value of b: %d", b);
}
Executing Program-4.8 display the following:
Enter value of a: 51
Value of b: 1
Enter value of a: 45
Value of b: 2
If the input is greater than 50 variable “b” will be assigned “1” and if not it will be assigned “2”.
Conditional operator can be used to implement simple if-else constructs. However use of conditional
operator is not recommended in modern day programming since it may reduce the readability of the
source code.
switch (a)
{
case 1: //if input is 1
printf("\nPersonal Computer Software");
break;
case 2: //if input is 2
printf("\nWeb based Software");
break;
case 3: //if input is 3
printf("\nScientific Software");
break;
case 4: //if input is 4
printf("\nEmbedded Software");
break;
default:
printf("\nIncorrect
input"); }
}
Executing Program-4.9 will display the following:
Menu
- ----------------------------------
1 - Microsoft Word
2 - Yahoo messenger
3 - AutoCAD
4 - Java Games
- ----------------------------------
Enter number of your preference: 1
Answer : 8.00
In certain cases you may need to execute the same statement(s) for several cases of a switch block. In
such cases several cases can be grouped together as follows:
switch (x) {
case 1:
case 2:
case 3:
printf(“Valid input”);
break;
default:
printf(“Invalid input”);
break;
}
5 – Control Structures
A Program is usually not limited to a linear sequence of instructions or conditional structures and it is
sometimes required to execute a statement or a block of statements repeatedly. These repetitive
constructs are called loops or control structures. The C language supports three constructs; namely for,
while and do-while loops. Rest of this chapter introduces these control structures.
}
Execution of program-5.1 displays :
This is a loo
This is a loo
This is a p
loo
This is a p
loo
This is a p
loo
p
In the above example, the variable “counter” starts with an initial value of “1”. The second
expression inside the parenthesis determines the number of repetitions of the loop. It reads as; “as long as
the counter is less than or equal to 5 repeat the statement(s)”. The third expression is the incrimination of
the counter; it is achieved by the ++ operator. You may also decrement the counter depending on the
requirement, but you have to use suitable control expression and an initial value.
In the first round of execution the “counter” is set to “1”. Then the expression “counter <= 5” is
evaluated. Since the current value of the “counter” is “1” expression is evaluated as TRUE. Therefore
the printf function gets executed. Then the “counter” is incremented by the ++ operator and now its
new value becomes “2”. At this point the first round of the loop is completed. Then in the second round
the expression is evaluated again. Since the “counter” is “2” the expression will be TRUE. Therefore the
printf function gets executed for the second time. Then the “counter” is incremented once more and
its new value becomes “3”. This process continues for another 2 rounds. After a total of five rounds the
“counter” becomes “6”. When the expression is evaluated at the beginning of the sixth round the
“counter” is greater than 5 therefore expression becomes FALSE. Then the loop will terminate and the
control is given to rest of the instructions which are outside the loop.
Exercise 5.1 – Write a C program to display all the integers from 100 to 200.
Example 5.1 – Write a program to calculate the sum of all the even numbers up to 100.
First even number is 0 and the last even number is 100. By adding 2 to an even number the next even
number can be found. Therefore the counter should be incremented by 2 in each round. Program-5.2 is
an implementation of the above requirement.
/* Program-5 . 2 * /
#include <stdio.h>
void main()
{
int counter, sum;
sum = 0;
for(counter=0; counter <= 100; (counter += 2)) //increment by 2
{
sum += counter;
}
printf("Total : %d", sum);
}
Exercise 5.2 – Modify Program-5.2 such that it computes the sum of all the odd numbers up to 100.
Exercise 5.3 – Write a program to compute the sum of all integers form 1 to 100. Exercise 5.4 –
Write a program to calculate the factorial of any given positive integer.
Each of the three parts inside the parentheses of the for statement is optional. You may omit any of
them as long as your program contains the necessary statements to take care of the loop execution. Even
the statement(s) inside the loop are optional. You can omit even all the expressions as in the following
example:
for(;;;)
printf("Hello World\n");
This loop is an infinite one (called an infinite loop). It is repeated continuously unless you include a
suitable condition inside the loop block to terminate the execution. If there is no such condition, the only
thing you can do is to abort the program (a program can be aborted by pressing Ctrl+Break).
Example 5.2 – Write a program to compute the sum of all integers between any given two numbers.
In this program both inputs should be given from the keyboard. Therefore at the time of development
both initial value and the final value are not known.
/* Program-5 . 3 * /
#include <stdio.h> void main()
{
int num1, num2, sum; sum=0;
printf("Enter first number: ");
scanf("%d", &num1);
printf("Enter second number: ");
scanf("%d", &num2); //read
}
Execution of Program-5.4 with 5 as the input will display the following:
Enter number of times to repeat: 5
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
In Program-5.4 the number of times to loop, depends on the user input. In such cases use of while loop
is desirable than the fo r loop. In program-5.4 variable “n u m” act as the counter. The conditions inside
the while loop check whether the counter is not equal to zero (n u m != 0) if so it will execute the
printf function. Next we need to make sure that the program loops only 5 times. That is achieved by
decrementing the counter (num--) at each round. If the counter is not decremented the program will
loop forever.
Exercise 5.5 – What would happen if we enter -1 as the number of times to loop in Program-5.4?
Modify Program-5.4 so that it works only for positive integers.
}
Execution of Program-5.5 with some inputs will display the following:
Enter price (0 to end): 10
Enter price (0 to end): 12.5
Enter price (0 to end): 0
99.9
Enter price (0 to end): 9
0
Total : 122.49
Program-5.5 accepts prices of items from the keyboard and then it computes the total. User can enter any
number of prices and the program will add them up. It will terminate only if zero or any negative number
is entered. In order to calculate the total or terminate the program there should be at least one input from
the keyboard. Therefore in this type of a program do-while loop is recommended than the while loop.
Exercise 5.6 – Modify Program-4.8 such that it first displays the menu. Then based on the user selection
it should display the correct message. After displaying the correct message it should again display the
menu. The program should exit when the user enter 0.
In summary, the for loop is recommended for cases where the number of repetitions is known in
advance. The while loop is recommended for cases where the number of repetitions are unknown or
unclear during the development process. The do-while loop is recommended for cases where the loop
to be executed needs to run at least once regardless of the condition. However, each type of loop can be
interchanged with the other two types by including proper control mechanisms.
void main()
{
int n;
for(n=10;n>0;n--)
{
printf("Hello World!\n");
if (n == 5)
{
printf("Countdown aborted!");
break;
}
}
}
Under normal circumstances the Program-5.7 will display the “Hello World!” message 10 times.
Notice that in this example the for loop is written as a decrement rather than an increment. During the
first 5 iterations the program executes normally displaying the message “Hello World!”. Then at the
beginning of the sixth iteration variable “n” becomes “5”. Therefore the if condition which evaluates
whether “n==5” becomes TRUE, so it will execute the printf function and then the break
instruction. At this point the loop will terminate because of the brea k keyword.
Example 5.4 – Write a C program to display the message “Hello World!” 10000 times. The program
should allow users to terminate the program at any time by pressing any key before it displays all the
10000 messages.
/* Program-5 . 8 * /
#include <stdio.h>
#include <conio.h>
void main()
{
int i;
for(i=0;i<=10000;i++) // loop 10000 times
{
printf("Hello World! %d\n",i);
if(kbhit() != 0) // if a key is pressed
{
printf("Loop terminated");
break; //terminate loop
}
}
}
void main()
{
int i;
for(i=-5;i<=5;i++) // loop from -5 to 5
{
if (i == 0) // if 0 skip
continue;
printf("5 divided by %d is: \t %.2f \n", i, (5.0/i));
}
}
In program-5.9, 5 is divided by all the integers from -5 to +5. However a number should not be divided
by 0. In Program-5.9, when “i” is 0 (when the if condition is TRUE) the continue keyword is used to
skip the rest of the iteration which will skip the printf function.
Arrays are a series of elements of the same data type placed consecutively in memory that can be
individually referenced by adding an index to a unique name. Using an array we can store five values of
type int with a single identifier without having to declare five different variables with a different
identifier. Arrays are useful when you store related data items, such as grades received by the students,
sine values of a series of angles, etc. Like any other variable in C an array must be declared before it is
used. The typical declaration of an array is:
data-type array-name[no-of-elements];
Notice that the array name must not be separated from the square brackets containing the index. When
declaring an array, the number of array elements should be constant. As arrays are blocks of static
memory locations of a given size, the compiler must be able to determine exactly how much memory to
allocate at compilation time.
void main()
{
int i,sum;
int marks[ 5] ; //array of 5 elements
float average;
sum=0;
for(i=0;i<5;i++)
{
printf("Enter marks for subject %d: ", i+1);
scanf (" %d", &marks[ i] ) ; //get the marks }
for(i=0;i<=5;i++) //total marks
{ sum +=marks[ i] ;
}
average = sum/5.0; //5.0 indicates a float value
printf("Average : %.2f", average);
}
Execution of Program-6.1 displays the following:
Enter marks for subject 1: 5
Enter marks for subject 2: 3
Enter marks for subject 3: 3
8
Enter marks for subject 4: 6
8
Enter marks for subject 5: 1
6
Average : 64.60 7
The Program-6.1 accepts marks for 5 subjects from the keyboard and stores them in an array named
marks. Then in the second loop it computes total of all marks stored in the array and finally it
computes the average.
The C functions that you have used so far (such as printf and scanf) are built into the C libraries, but
you can also write your own functions. Therefore functions can be classified as built-in and user
defined. A modular program is usually made up of different functions, each one accomplishing a
specific task such as calculating the square root or the factorial. In general a modular program consists of
the m a i n( ) function followed by set of user defined functions as given below:
#include ……
#define …..
Prototypes of functions
int main( ) {
function_1( ) {
function_2( ) {
function_n( ) {
}
The source code contains other elements in addition to the function blocks. It starts with the #include
directive, followed by the #define directive (if any) then followed by the prototypes of functions. The
prototype is a declaration of a function used in the program. Then comes the program building block
which includes the main( ) function and implementation of the user defined functions.
7.1 A Function
A function is a subprogram that can act on data and return a value. Some functions may accept certain
input parameters (such as printf), some may return a value of a certain data type (such as kbhit) and
some may accept as well as return a value (sqrt).
Every C program has at least one function, the m a i n( ). When a program is executed the m a i n( ) is
called automatically. The m a i n( ) may call other functions and some of them might call other
functions.
Each function has a unique name and when the name is encountered while in execution the control of the
program is transferred to the statement(s) within the function. When the function is ended (returns) the
control is resumed to the next statement following the function call.
Well designed functions perform a specific and easily understood task. Complicated tasks should be
broken down into multiple functions and then each can be called in the proper order.
7.2 Function Prototypes
Using functions in your program requires that you first declare the function (the prototype). Later you
can implement the function. The prototype tells the compiler in advance about some characteristics
(name of the function, return type and parameters) of a function. A function prototype takes the form:
type function-name(type argement-1, type argument-2, …..);
The function prototype is a statement that ends with a semicolon. The function name is any legal
identifier followed by the function parenthesis without any space in between. The function “type” is the
data type of the return value. If the function does not return a value, the data type is defined as void.
The arguments (or parameters) come inside the parenthesis, preceded by their types and separated by the
commas. If the function does not any parameters, it is either kept blank or the word void is used inside
the parenthesises. Following are some examples for prototypes:
void exit(int x);
int kbhit( );
double power(double x, double y);
The first function returns no value and it takes an integer argument. Second prototype returns an integer
value and has no inputs. Third function returns a double value and takes two double values.
void main()
{
float radius;
printf("Enter radius: ");
scanf("%f",&radius); //read radius
printf("\nArea : %.2f", area(radius));
printf("\nCircumference : %.2f", circumference(radius));
}
void main()
{
int radius;
printf("Enter radius: ");
scanf("%d",&radius);
area(radius);
area((float)radius); //convert to float
void area(float r)
{
printf("\nFloating point input");
printf ("\nArea is: %.2f" , (pi*r*r) ) ;
}
void area(int r)
{
printf("\nInteger input");
printf ("\nArea is: %.2f" , (pi*r*r) ) ;
}
Execution of Program-7.2 displays:
Enter radius: 1
A variable defined in such a manner is visible to the ma i n function and the “su b_tota l” function.
You can modify its value in either place and read it from another place.
A well written C source code should not have any global variables unless they are specifically required
since an accidental change to a global variable may produce erroneous results.
7.4.2 Default Parameters
For every parameter you declare in a function prototype and declaration the calling function must pass
in a value. The value passed must be of the declared type. Thus if you have a function declared as:
long my_function(int a);
the function must in fact take an integer value as an input. If the function definition differs or if you pass
a value of a wrong data type you will get a compilation error. However when you declare the function
prototype you can define a default value for the parameter as follows:
long my_function(int a = 50);
The default value is used if no input is supplied to the function. Similarly a function with many input
parameters can have a default value for each parameter.
Exercise 7.1 – Predict the output of each pri ntf function in Program-7.3.
/* Program-7 . 3 * /
#include <stdio.h>
void main()
{
int b,c;
a=5;
b=10;
c=15;
printf("\nValue before 1st function a= %d, b= %d c= %d" ,a,b,c);
swap1(b,c);
printf("\nValue after 1st function a= %d, b= %d c= %d" ,a,b,c);
swap2(b);
printf("\nValue after 2nd function a= %d, b= %d c= %d" ,a,b,c);
printf("Test");
void swap2(int x) {
}
8 – Pointers
Pointers are another important feature of the C language. Although it may appear a little confusing for a
novice programmer they are a powerful tool and handy to use once they are mastered. The power of C
compared to most other languages lies with proper use of pointers. Pointers are useful due to following
reasons:
· They enable us to access a variable that is defined outside a function.
· Pointers are more efficient in handling data tables and sometimes even arrays.
· Pointers tend to reduce the length and complexity of a program.
· They increase the execution speed.
· Use of pointers allows easy access to character strings.
Computers use memory to store both instructions and values of variables of a program. The computer’s
memory is a sequential collection of storage cells with the capacity of a single byte. Each of these
memory cells has an address associated with it.
Whenever a variable is declared the system allocates some memory to hold the value of the variable.
Such memory location can be accessed by providing the memory address. Consider the following
example:
int number = 35;
The above expression allocates a memory location to hold the value of variable “nu m be r” that can
hold an integer (4 bytes) and it also initialises the variable. Suppose the address of that memory
location is 2000. Then after executing above expression the memory address 2000 should hold 35.
During execution of the program, the system always associates the name “number” with the memory
address 2000. We may have access to the value “35” by using either the name “n u m be r” or the
address 2000. Since memory addresses are simple numbers, they can also be assigned to some
variables. Such variables that hold memory addresses are called pointers. Therefore a pointer is
nothing but a variable that contains an address which is a location of another variable in memory.
void main()
{
int number = 20;
int *pnt;
pnt = &number;
}
Execution of Program-8.2 displays:
Before swapping a= 5: b= 10
After swapping a= 10: b= 5
void main()
{
char * a;
a = "Hello World";
}
Exaction of Program-8.3 will display:
String: Hello World
First character: H
Starting memory address: 4235496
First character: 72
In Program-8.3 the first printf function displays the string pointed by pointer “a”. The second printf
function display the value pointed by pointer “a” which is the first character of the string. The third
printf function displays the starting memory address of the string which is the value of pointer “a”.
The final pri ntf function displays the ASCII value of the first character in the string.
void main()
{
int marks[ 5] = { 89, 45, 73, 98, 39} ;
printf (" %d\n", marks) ; //memory address pointed by
printf (" %d\n", &marks[ 0] ) ; pointer //memory address of 1st
printf (" %d\n", *marks) ; element //value pointed by pointer
printf (" %d\n", marks[ 0] ); //value of 1st array element
}
9 – Handling Files
The programs that we developed up to now were neither able to produce permanent output nor were they
able to read data inputs other than from the keyboard. Using files you can save your output data
permanently and retrieve them later.
A file in general is a collection of related records, such as student information, marks obtained in an
exam, employee salaries, etc. Each record is a collection of related items called fields, such as “student
name”, “date of birth”, “subjects registered”, etc. The common operations associated with a file are:
· Read from a file (input)
· Write to a file (output)
· Append to a file (write to the end of a file)
· Update a file (modifying any location within the file)
In C language data is transferred to and from a file in three ways:
· Record input/output (one record at a time)
· String input/output (one string at a time)
· Character input/output (one character at a time)
You can assign the output of the function getc to an int or char variable.
Example 9.1 – Write a program to read the file “my file.txt” which has the message:
Hello World!
This is my first file
The following program reads the file “my file.txt” one character at a time and displays it on the screen.
/* Program-9 . 1 * /
#include <stdio.h>
void main()
{
FILE *fp;
char c;
}
Execution of Program-9.1 will display
Hello World!
This is my first file
In Program-9.1 a connection is first established to the file. Then the expression if(fp != NULL)
evaluates whether the connection is successful. If it is not successful the program will display the
message “Error while opening file...” If it is successful it reads the first character from the file. If
the character is not the end of the file (indicated by the End Of File (EOF) mark) it displays the
character. Then the program continues to read the rest of the characters in the file until it finds the EOF
mark. Afterwards the connection to the file is closed using the fclose function.
Reading a String from a File
In real-life applications it is more useful to read one string at a time rather than one character. With
every read, the program has to check for the line feed (LF) character so it can find the end of each
string. Also it must check for the EOF mark which comes at the end of the file . The fgets function
can be used to read a string at a time. The function generally takes the form:
fgets(string, max_characters, file_pointer)
The “string” is a character array (also called a character b u f e r ) and “max_characters” define the
maximum number of characters to read form a line. The function fgets returns a c h a r pointer. It
returns NULL if EOF mark is encountered. One deficiency in fgets is that it can only read to a fixed
character buffer, therefore you need to know in advance the maximum number of characters in a string.
Example 9.2 – Modify Program-9.1 such that it uses the fgets function instead of fgetc function.
Suppose the file does not have more than 100 characters in a line.
/* Program-9 . 2 * /
#include <stdio.h>
void main()
{
FILE *fp;
char buffer[ 100] ; //char array with 100 elements
char * result; // hold the result of the fgets function
fp = fopen("my text.txt", "r"); //open read-only
if (fp != NULL)
{
result = fgets(buffer, 100, fp); //read the 1st string
while(result != NULL) //if not the end of file
{
printf("%s",buffer);
result = fgets(buffer, 100, fp); //read the next string
}
fclose(fp); //close the file
}
else
printf("\nError while opening file");
where c is the character while fp is the file pointer. It returns an int value which indicates the success or
the failure of the function. It returns the i nt value of the character if it is successful, if not it returns EOF
mark.
Example 9.3 – Write a C program to store the message “Introduction C Programming” in a file named
“message.txt”.
Program-9.3 is an implementation of the above requirement. The function putc is used to write
characters in the message to the file. To find the number of characters in the message the strlen
function which returns the number of characters in a string is used. A pointer is used to point to the
string and the pointer is incremented by one memory location at a time.
/* Program-9 . 3 * /
#include <stdio.h>
#include <string.h>
void main()
{
FILE *fp;
int i; //loop counter
char *message;
message = "Introduction C Programming";
}
Writing a String to a File
The advantage of putc is that it allows you to control every byte that you write into the file. However
sometimes you may want to write one string at a time. Two functions, namely fputs and fprintf can be
used for this purpose. The fprintf function is identical to the printf function only difference being
that it writes to a file rather than to the screen. The format of each function is:
fputs(string, file_pointer)
fprintf(file_pointer, “%s”, string)
Exercise 9.1 – Modify Program-9.3 such that it uses the fputs rather than the fputc function to write the
message to the file .
Exercise 9.2 – Develop a simple telephone directory which saves your friends contact information in a
file named directory.txt. The program should have a menu similar to the following:
--------------------------- Menu------------------------
1. Add new friend.
2. Display contact info.
3. Exit
- -----------------------------------------------
Enter menu number:
When you press “1” it should request you to enter following data:
--------------New friend info-------
Name : Saman
Phone-No: 011-2123456
e-Mail : saman@cse.mrt.ac.lk
After adding new contact information it should again display the menu. When you press “2” it should
display all the contact information stored in the directory.txt file as follows:
------------------------ Contact info--------------
Name Tel-No e-Mail
Kamala 077-7123123 kamala@yahoo.com
Kalani 033-4100101 kalani@gmail.com
Saman 011-2123456 k
- ---------------------------- - -----------
Library Functions
The C language is accomplished by a number of library functions that performs various tasks. Following
is a list of commonly used functions. For a more complete list reader should refer to the manual (or help)
of the version of C compiler that is being used.
H.1 Character Manipulation Functions
Function Header file Prototype description
isalnum ctype.h int isalnum(int character) Determines if the character is alphanumeric. If
true return nonzero value, else 0.
isalpha ctype.h int isalpha(int character) Determines if the character is alphabetic. If true
return nonzero value, else 0.
isascii ctype.h int isascii(int character) Determines if the character is an ASCII
character. If true return nonzero value, else 0.
isdigit ctype.h int isdigit(int character) Determines if the character is a decimal digit. If
true return nonzero value, else 0.
islower ctype.h int islower(int character) Determines if the character is a lowercase. If
true return nonzero value, else 0.
ispunct ctype.h int ispunct(int character) Determines if the character is a punctuation
character. If true return nonzero value, else 0.
isspace ctype.h int isspace(int character) Determines if the character is a whitespace. If
true return nonzero value, else 0.
isupper ctype.h int isupper(int character) Determines if the character is a uppercase. If
true return nonzero value, else 0.
isxdigit ctype.h int isdigit(int character) Determines if the character is a hexadecimal
digit. If true return nonzero value, else 0.
toascii ctype.h int toascii(int character) Convert value of argument to ASCII.
tolower ctype.h int tolower(int character) Convert a character to lowercase.
toupper ctype.h int toupper(int character) Convert a character to uppercase.