You are on page 1of 402

5/21/2014 Version-1.

2 1
C

Programming


5/21/2014 Version-1.2 2
Slides Prepared By:
Vikas karanth
and
Leelavati
5/21/2014 Version-1.2 3
Objectives
What is programming

Types of Programming Languages

Need of Compilers and Translators

History of C

Program Development Cycle

Compiling C Programs

Running C Programs
5/21/2014 Version-1.2 4
What is a Programming?
The art of writing instructions for a computer to solve a
specific task is known as programming.

The output of programming is a well-defined set of
instructions. This is called a program.

Software is a program or collection of programs.

Software can be developed by computer languages.

5/21/2014 Version-1.2 5
Classification of Computer Languages
Programming Languages
Low Level Languages
High Level Languages
Machine
Language
Assembly
Language
Modular
Object Oriented
5/21/2014 Version-1.2 6
Classification of LLLs
Machine Language
Programming is done at
machine level
Computer consists of 2
words 0 and 1.
Machine dependent
Can be directly typed and
executed
No Translator program is
required
Difficult to
remember,understand,
modify and debug errors.

Assembly Language
Uses Symbolic instructions
Uses symbolic words in this
language are referred to as
mnemonics
E.g. ADD for Addition
SUB for Subtraction
ST Z to store the result
Instructions are English like,
the computer does not
understand the instructions
So the translators are
required to convert these
instructions to machine
language.


5/21/2014 Version-1.2 7
High Level Languages
HLLs are English like.
Elements of these languages are
alphabets,digits,punctuations and other special
symbols.
Instructions are machine dependent.
The programmer can easily understands the
program but the computer does not.
Translators are required to translate this
program into computer readable form .
The Compiler and Interpreter are 2
translator programs that are used to translate
the HLL into machine language.
Source
Program
Translator
Compiler Interpreter
Machine Code
5/21/2014 Version-1.2 8
Advantages of High-level languages over low-level ones:
Readability: A good high-level language will allow programs
to be written in English description of the underlying
algorithms. If care is taken, the coding may be done in a way
that is essentially self-documenting, a highly desirable
property

Portability: High-level languages, being essentially machine
independent, hold out the promise of being used to develop
portable software.

Structure and object orientation: There is general agreement
that the structured programming movement of the 1960s
and the object-oriented movement of the 1990s have
resulted in great improvement in the quality and reliability of
code.
5/21/2014 Version-1.2 9
Generality: Most high-level languages allow the
writing of a wide variety of programs, thus relieving
the programmer of the need to become expert in
many diverse languages.

Brevity: Programs expressed in high-level languages
are often considerably shorter (in terms of their
number of source lines) than their low-level
equivalents.

Error checking: Being human, a programmer is likely
to make many mistakes in the development of a
computer program. Many high-level languages - or at
least their implementations - can, and often do,
enforce a great deal of error checking both at
compile-time and at run-time.
5/21/2014 Version-1.2 10
Difference between Compiler and Interpreter

Compilers
It takes entire HLL program
as input and translate in into
M/C Language

All errors that occur in the
program are listed and
displayed.
Debugging is faster.
Requires more memory
Costlier


Interpreter
It takes one statement of a
high level language
program as input and
translates it into M/C
language and executes it.
Errors that occur only in
the statement being taken
for translation are
displayed
Debugging is slower
Requires less memory
Cheaper
5/21/2014 Version-1.2 11
Classification of HLLs
1. General Purpose HLL
are used in almost all fields such as
teaching,training,business,art,science etc.
Eg. BASIC(Beginers All purpose Symbolic
Instruction Code),Pascal,C.

2. Specific purpose HLL
are restricted to a particular field.
Eg.
COBOL,FORTRAN,C++,PROLOG,JAVA,C#
5/21/2014 Version-1.2 12
COMPILERS

Translates-Source language to Target language.
Source
program
COMPILER
Target
program
Error messages
5/21/2014 Version-1.2 13
Basics of a Typical C Environment
Phases of C Programs:
1. Edit
2. Preprocess
3. Compile
4. Link
5. Load
6. Execute

Loader

Primary
Memory

Program is created in
the editor and stored
on disk.

Preprocessor program
processes the code.

Loader puts program
in memory.

CPU takes each
instruction and
executes it, possibly
storing new data
values as the program
executes.

Compiler

Compiler creates
object code and stores
it on disk.

Linker links the object
code with the libraries,
creates a.out and
stores it on disk

Editor

Preprocessor

Linker



CPU

Primary
Memory

.
.
.

.
.
.

.
.
.

.
.
.

Disk

Disk

Disk

Disk

Disk





5/21/2014 Version-1.2 14
Phases of compiler:


Error handler
Symbol table
manager
Target program
Source program
Lexical analyzer
Syntax analyzer
Semantic analyzer
Intermediate code
generator
Code optimizer
Code generator
5/21/2014 Version-1.2 15
Lexical analyses
The first phase, called the lexical analyzer, or
scanner,which separates characters of the source
language in to groups that logically belong together;
these groups are called tokens.

The usual tokens are keywords, such as if, while, break,
identifiers, such as X or NUM, operator symbols such as
< = or +, and punctuation symbols such as
parentheses or commas.

The output of the lexical analyzer is a stream of
tokens, which is passed to the next phase, the syntax
analyzer, or parser.
5/21/2014 Version-1.2 16
The syntax analyzer groups tokens together in to
syntactic structures.

For examples, the three tokens representing A+B might
grouped into a syntactic structure called an expression.
Expressions might further be combined to form
statements.

The intermediate code generator uses the structure
produced by the syntax analyzer to create a stream of
simple instructions.

Many styles of intermediate code are possible. One
common style uses instructions with one operator and a
small number of operands.

The primary difference between intermediate code and
assembly code is that the intermediate code need not
specify the registers to be used for each operation.
5/21/2014 Version-1.2 17
Code optimization is an optional phase designed to improve
the intermediate code so that the ultimate object program
runs faster and or takes less space.

The final phase, code generation, produces the object code by
deciding on the memory locations for data, selecting code to
access each datum, and selecting the registers in which each
computation is to be done.

That table management or book keeping, portion of the
compiler keeps the track of the names used by the program
and records the essential information about each, such as its
type (integer, float, etc). That data structure used to record
this information is called symbol table.

The error handler is invoked when a flaw in the source
program is deducted. It must warn the programmer by issuing
a diagnostic, and adjust the information being passed from
phase to phase, so that each phase can proceed. Both table
management and error handling routines interact with all
phases of the compiler.
5/21/2014 Version-1.2 18
Cs memory map
Uninitialized data
segment(bss)
Initialized data
segment

Heap
Stack
Text segment

5/21/2014 Version-1.2 19
Text segment : Includes the executable code.

Stack segment: contains the program stack , which
includes the return address, parameters and local
variables of the functions being executed.

Heap Segment: contains memory allocated dynamically.

Initialized data segments: contains the initialized data
i.e, the static variables and the global variables whose
initial values are stored in the executable file.

Uninitialized data segments: contains the uninitialized
data i.e, all global variables whose initial values are
not stored in the executable file.
5/21/2014 Version-1.2 20
Libraries
Each high level source code file is transformed through
several steps in to an object file, which contains the
machine code of the assembly language instructions
corresponding to the high level instructions.

An object file can not be executed, since it doenot
contain the linear address that corresponds to each
reference such as functions in libraries or other source
code files of the same program.

The assigning, or resolution, of such address is
performed by the linker, which collects all the object
files of the program and constructs the executable file.

The linker also analyses the librarys functions used by
the program and use them in to the executable file.
5/21/2014 Version-1.2 21
All executable files in traditional UNIX systems were based on
static libraries.

This means that executable file produced by the linker
includes not only the code of the original program but also the
code of the library functions.

Modern UNIX system use shared libraries. The executable file
doenot contain the library object code, but only a reference to
the library name.

When the program is loaded in memory for execution, a
program called program interpreter (ld.so) takes care of
analyzing the library names in the executable file, by locating
the library in the systems directory tree. A process can also
load additional shared libraries at run time by using the
dlopen ( ) library function.

This is done by memory mapping.
5/21/2014 Version-1.2 22
Dynamic Linking and Loading
Dynamic linking defers much of the linking process until
a program starts running. It provides a variety of
benefits that are hard to get otherwise:
Dynamically linked shared libraries are easier to
create than static linked shared libraries.

Dynamically linked shared libraries are easier to
update than static linked shared libraries.

The semantics of dynamically linked shared libraries
can be much closer to those of unshared libraries.

Dynamic linking permits a program to load and
unload routines at runtime, a facility that can
otherwise be very difficult to provide.
5/21/2014 Version-1.2 23
Dynamic Linking and Loading
There are a few disadvantages, of course.

The runtime performance costs of dynamic linking
are substantial compared to those of static
linking, since a large part of the linking process
has to be redone every time a program runs.

Every dynamically linked symbol used in a
program has to be looked up in a symbol table
and resolved.

Dynamic libraries are also larger than static
libraries, since the dynamic ones have to include
symbol tables.

5/21/2014 Version-1.2 24
ELF dynamic linking
Sun Microsystems' SunOS introduced
dynamic shared libraries to UNIX in the
late 1980s.

ELF was clearly an improvement over
the previous object formats, and by
the late 1990s it had become the
standard for UNIX and UNIX like
systems including Linux and BSD
derivatives.
5/21/2014 Version-1.2 25

5/21/2014 Version-1.2 26
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.
5/21/2014 Version-1.2 27
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.
5/21/2014 Version-1.2 28
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.
5/21/2014 Version-1.2 29
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.
5/21/2014 Version-1.2 30
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.
5/21/2014 Version-1.2 31
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.
5/21/2014 Version-1.2 32
Why Use C?
C is a powerful and flexible language. C is used for projects as
diverse as operating systems, word processors, graphics,
spreadsheets, and even compilers for other languages.

C is a portable language. Portable means that a C program
written for one computer system (an IBM PC) can be compiled
and run on another system(a DEC VAX system) with little or
no modification. Portability is enhanced by ANSI standard for
C, the set of rules for C compilers.

C is modular. C code can(and should) be written in routines
called functions. These functions can be reused in other
applications or programs. By passing pieces of information to
the functions, one can create useful, reusable code.

First Program
5/21/2014 Version-1.2 33
C Program Structure
Documentation Section
Link Section
Definition Section
Global Declaration Section
main() Function Section
{
Declaration Part
Executable Part
}
Sub Program Section
Function 1
Function 2
- (User defined Functions)
-
Function n

5/21/2014 Version-1.2 34
Variables , constants
Operators in C
5/21/2014 Version-1.2 35
Objectives
Constant and Variable Types
Variables
Variable Names
Constants
Expressions and Operators
Assignment Statement
Arithmetic operators
Relational Operators
Logical Connectors
5/21/2014 Version-1.2 36
C Tokens
5/21/2014 Version-1.2 37
C Tokens
Keywords Operators
Identifiers Special Symbols
Constants Strings
5/21/2014 Version-1.2 38
Key Words defined by 89 standred
while static If do
Volatile Sizeof Goto Default
Void Signed For Continue
Unsigned Short Float Const
Union Return Extern Char
Typedef Register Enum Case
Switch Long Else Break
Struct Int Double Auto
5/21/2014 Version-1.2 39
Key Words defined by 99 standard
Inline _Complex Restrict _Imaginary _Bool
5/21/2014 Version-1.2 40
Cs memory map
Program Code
Global variables
Heap
Stack

5/21/2014 Version-1.2 41
Variables (identifiers)
A variable is a named data storage location in the computer's memory.
Variable Names
The name can contain letters, digits, and the underscore character (_).

The first character of the name must be a letter. The underscore is also a legal first
character, but its use is not recommended.

Case matters (that is, upper- and lowercase letters). Thus, the names count and
count refer to two different variables.

C keywords can't be used as variable names. A keyword is a word that is part of the
C language.

For many compilers, a C variable name can be up to 31 characters long.
(It can actually be longer than that, but the compiler looks at only the first
31 characters of the name.)
5/21/2014 Version-1.2 42
Many naming conventions are used for variable names created from
multiple words.

One style: interest_rate. Using an underscore to separate words in a
variable name makes it easy to interpret.

The second style is called camel notation. Instead of using spaces,
the first letter of each word is capitalized. Instead of interest_rate, the
variable would be named InterestRate

Numeric Variable Types
C's numeric variables fall into the following two main categories:

Integer variables hold values that have no fractional part (that is, whole numbers
only). (signed and unsigned values)

Floating-point variables hold values that have a fractional part (that is,
real numbers).

5/21/2014 Version-1.2 43
Variable Type Keyword Bytes
Required
Range
Character char 1 -128 to 127
-32768 to 32767
2,147,483,648 to 2,147,438,647
Short integer short 2 -32768 to 32767
Long integer long 4 -2,147,483,648 to 2,147,438,647
Unsigned character unsigned char 1 0 to 255
Unsigned integer unsigned int 2 0 to 65535
Unsigned short integer unsigned short 2 0 to 65535
Unsigned long integer unsigned long 4 0 to 4,294,967,295
Single-precision float 4 1.2E-38 to
floating-point
3.4E38
1
Double-precision double 8 2.2E-308 to
floating-point
1.8E308
2
2
Approximate range; precision = 19 digits.
Integer int 2 or 4
1
Approximate range; precision = 7 digits.
C's numeric data types.
5/21/2014 Version-1.2 44
Data type sizes
# include <stdio.h>
Main()
{
printf(size of integer is %d\n,sizeof(int));
printf(size of float is %d\n,sizeof(float));
printf(size of char is %d\n,sizeof(char));
printf(size of long is %d\n,sizeof(long));
printf(size of short is %d\n,sizeof(short));
printf(size of double is %d\n,sizeof(double));
printf(size of integer is %d\n,sizeof(long double));
}
5/21/2014 Version-1.2 45
Variable Declarations
Before using a variable in a C program, it must
be declared
A variable declaration has the following form:

typename varname; //typename specifies the type of variable
// varname is the variable name

e.g..
int count, number, start; /* three integer variables */
float percent, total; /* two float variables */


5/21/2014 Version-1.2 46
The typedef Keyword
The typedef keyword is used to create a new
name for an existing data type

typedef int integer; //Creates integer as
a synonym for int
integer count;

that typedef doesn't create a new data type;
it only lets the usage of a different name for
a predefined data type
5/21/2014 Version-1.2 47
Initializing Numeric Variables
If the value of the variableisnt defined. It might be zero, or
it might be some random garbage value. Before using a
variable, always initialize it to a known value.

int count; /* Set aside storage space for count */
count = 0; /* Store 0 in count */

Be careful not to initialize a variable with a value outside the allowed
range. Here are two examples of out-of-range initializations:
int weight = 10000000000;
unsigned char value = 2500;

The C compiler doesnt catch such errors. The program might compile
and link, but unexpected results might be obtained when the program
is made to run.

5/21/2014 Version-1.2 48
Constants
A constant is a data storage location used by the
program. Unlike a variable, the value stored in a
constant can't be changed during program execution

C has two types of constants
1. Literal Constants
A literal constant is a value that is typed directly into the
source code wherever it is needed.
count = 20; tax_rate = 0.28;
Decimal constants can contain the digits 0 through 9
and a leading minus or plus sign.
Octal constants can contain the digits 0 through 7 and a
leading minus or plus sign.
Hexadecimal constants can contain the digits 0
through 9, the letters A through F, and a leading
minus or plus sign

5/21/2014 Version-1.2 49
Constants
2. Symbolic Constants
A symbolic constant is a constant that is represented
by a name (symbol) in the program. Like a literal
constant, a symbolic constant can't change.
C has two methods for defining a symbolic constant:
the #define directive and the const keyword.

#define CONSTNAME literal
This creates a constant named CONSTNAME with the
value of literal. literal represents a literal constant
e.g.. #define PI 3.14159 /* a constant for PI is
defined. */
Defining Constants with the const Keyword
const int count = 100;
const float pi = 3.14159;
const long debt = 12000000;




5/21/2014 Version-1.2 50
Statements, Expressions, and Operators
Statements
A statement is a complete direction instructing the
computer to carry out some task.
e.g. x = 2 + 3;
The term white space refers to spaces, tabs, and
blank lines in the source code.

is equivalent to this statement:
x = 2 + 3;
It is also equivalent to this:
x =
2
+
3;
5/21/2014 Version-1.2 51
Statements, Expressions, and Operators
printf("Hello,\
world!");

Null Statements
If a semicolon is placed by itself on a line,a null statement
is created. A statement that doesn't perform any
action.This is perfectly legal in C.

Compound Statements
A compound statement, also called a block, is a group of
two or more C statements enclosed in braces.
{
printf("Hello, ");
printf("world!");
}
5/21/2014 Version-1.2 52
Statements, Expressions, and Operators
Simple Expressions
The simplest C expression consists of a single
item: a simple variable, literal constant, or
symbolic constant.
E.g. PI,12.5,rate,-1.25

Complex Expressions
Complex expressions consist of simpler
expressions connected by operators.
E.g. 1.25 / 8 + 5 * rate + rate * rate / cost

Operators

5/21/2014 Version-1.2 53
Statements, Expressions, and Operators
Operators
An operator is a symbol that instructs C to
perform some operation, or action, on one or
more operands. An operand is something that
an operator acts on. In C, all operands are
expressions.
The Assignment Operator
The assignment operator is the equal sign (=).
x=y; it means, "assign the value of y to x.
Mathematical Operators
1. Unary Mathematical Operators
2. Binary Mathematical Operators
5/21/2014 Version-1.2 54
Statements, Expressions, and Operators





++x, x++ Increments the operand by one ++ Increment
--y, y-- Decrement the operand by one -- Decrement
Examples Action Symbol Operator
1. Unary Mathematical Operators
5/21/2014 Version-1.2 55
main()
{
int m, i =5;
m = i++ + ++i;
printf("Ist %d\n",m);//5 + 5 = 10

i = 5;
m = i++ + i++;
printf("Ist %d\n",m);//6 + 6 = 12

i = 5;
m = i++ + ++i + i++;
printf("Ist %d\n",m);//6 + 6 + 6 = 18

i = 5;
m = i++ + ++i + ++i; //6 + 6 + 7 = 19
printf("Ist %d\n",m);
getchar();
}
5/21/2014 Version-1.2 56
Binary Mathematical Operators
.
x%y Gives the remainder when the
first operand is divided by the
second operand
% Modulus
x/y Divides the first operand by the
second operand
/ Division
x*y Multiplies two operands * Multiplication
x-y Subtracts the second operand
from the first operand
- Subtraction
x+y Adds two operands + Addition
Example Action Symbo
l
Operator
5/21/2014 Version-1.2 57
Order of Subexpression Evaluation
. DO use parentheses to make the order of expression
evaluation clear.
DON'T overload an expression. It is often more clear to
break an expression into two or more statements. This
is especially true when using the unary operators (--)
or (++).
3 + -
2 * / %
1 ++ --
Relative Precedence Operators
5/21/2014 Version-1.2 58
A Program to find area of Triangle
main()
{
float base,height,area;
printf("Enter the base and height of the
triangle\n");
scanf("%f %f",&base,&height);
area = 1 / 2.0 * base * height;
printf("The area of the triangle is
%f\n",area);
}
Go Back
5/21/2014 Version-1.2 59
Swap numbers without temporary variable
main()
{
int num1,num2;
printf("Enter any 2 numbers :");
scanf("%d %d",&num1,&num2);
printf("numbers before swaping\n ");
printf("num1 = %d \t num2 = %d\n",num1,num2);
num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2;
printf("numbers after swaping \n");
printf("num1 = %d \t num2 = %d\n",num1,num2);
}
5/21/2014 Version-1.2 60
Relational Operators
.
x<=y

Is operand 1 less than or equal to
operand 2?
<=

Less than or
equal to
x!=y Is operand 1 not equal to operand 2? != Not equal to
x>=y Is operand 1 greater than or equal to
operand 2?
>= Greater than
or equal to
x<y Is operand 1 less than operand 2? < Less than
x>y Is operand 1 greater than operand 2? > Greater than
x==y Is operand 1 equal to operand 2? == Equal
Example Question Asked Symbol Operator
5/21/2014 Version-1.2 61
Logical Operators
C's logical operators let to combine two
or more relational expressions into a
single expression that evaluates to
either true or false.
False (0) if exp1 is true; true (1) if
exp1 is false
(!exp1) ! NOT
True (1) if either exp1 or exp2 is
true; false (0) only if both are false
(exp1 || exp2 ) || OR
True (1) only if both exp1 and
exp2 are true; false (0) otherwise
(exp1 && exp2) && AND
What It Evaluates To Example Symbo
l
Operat
or
5/21/2014 Version-1.2 62
Compound Assignment
Operators
C's compound assignment operators provide a
shorthand method for combining a binary mathematical
operation with an assignment operation
e.g.. x = x + 5;
using shorthand operator we can write x +=5;
x = x + y / 8 x += y / 8
y = y % 3 y %= 3
a = a / b a /= b
y = y - z + 1 y -= z + 1
x = x * y x *= y
It Is Equivalent To This When Written as...
5/21/2014 Version-1.2 63
The Conditional Operator
The conditional operator is C's only ternary operator, meaning that
it takes three operands. Its syntax is
exp1 ? exp2 : exp3;
If exp1 evaluates to true (that is, nonzero), the entire
expression evaluates to the value of exp2. If exp1 evaluates to
false (that is, zero), the entire expression evaluates as the
value of exp3.
1. assigns the value 1 to x if y is true and assigns 100 to x if y
is false
e.g. x = y ? 1 : 100;

2. to make z equal to the larger of x and y, one could write
z = (x > y) ? x : y;


5/21/2014 Version-1.2 64
Max 3 using ternary operator
main()
{
int num1,num2,num3,max;
printf("Enter any 3 numbers :");
scanf("%d %d %d",&num1,&num2,&num3);

max=((num1>num2)&(num1>num3)?num1:(nu
m2>num3)?num2:num3);
printf("The greatest of three numbers is
%d\n",max);
}
5/21/2014 Version-1.2 65
The Comma Operator
The comma is frequently used in C as a simple
punctuation mark, serving to separate variable
declarations, function arguments, and so on

Separating two sub expressions with a comma can form an
expression. The result is as follows:

Both expressions are evaluated, with the left expression
being evaluated first.
e.g. i=(j=3 , j+2);

here first value 3 is assigned to j and then the
expression j+2
is evaluated giving 5
5/21/2014 Version-1.2 66
Precedence and Order of Evaluation
right to left = += -= *= /= %= &= ^= |= <<= >>=
right to left ?:
left to right && , ||
left to right & , ^ , |
left to right == !=
left to right < <= > >=
left to right << >>
left to right + -
left to right * / %
right to left ! ~ ++ -- +(u) -(u) *(u) sizeof()
left to right () [] -> .
Associativity Operators
5/21/2014 Version-1.2 67
The if Statement
Statements in a C program normally execute from top to
bottom, in the same order as they appear in source code
file. A program control statement modifies the order of
statement execution.

In its basic form, the if statement evaluates an expression and directs
program execution depending on the result of that evaluation.

The form of an if statement is as follows:

if (expression)
statement;

If expression evaluates to true, statement is executed.

If expression evaluates to false, statement is not executed.
5/21/2014 Version-1.2 68
The if Statement
a block is a group of two or more statements enclosed in braces.
if (expression)
{
statement1;
statement2;
/* additional code goes here */
statementn;
}

An if statement can optionally include an else clause. The
else
clause is included as follows:
if (expression)
statement1;
else
statement2;
If expression evaluates to true, statement1 is executed. If
expression evaluates to false, statement2 is executed

5/21/2014 Version-1.2 69
If statements in different format
The if Statement
Form 1 Form 2
if( expression ) if(expression)
statement1; statement1;
next_statement; else{
statement2;
next statement;
}
Form 3
if( expression1 )
statement1;
else if( expression2 )
statement2;
else
statement3;
next_statement; E.g. Programs
5/21/2014 Version-1.2 70
A program to find max of 2 numbers
main()
{
int num1,num2;
printf("\n Enter any two numbers");
scanf("%d %d",&num1,&num2);
if(num1 > num2)
printf("%d is greater than %d\n",num1,num2);
else
printf("%d is greater than %d\n",num2,num1);
}
5/21/2014 Version-1.2 71
Find Max of 3 numbers
main()
{
int num1,num2,num3,max;
printf("Enter any 3 numbers :");
scanf("%d%d%d",&num1,&num2,&num3);
if(num1>num2)
if(num1>num3)
max = num1;
else
max = num3;
else if(num2> num3)
max = num2;
else
max = num3;
printf("The greatest of three numbers is %d\n",max);
}
5/21/2014 Version-1.2 72
The switch Statement
C's most flexible program control statement is the switch
statement, which lets the program to execute different
statements based on an expression that can have more than
two values.
switch (expression)
{
case template_1: statement(s);
case template_2: statement(s);
-----
case template_n: statement(s);
default: statement(s);
}
The switch statement allows for multiple branches from a
single expression. It's more efficient and easier to follow than
a multileveled if statement.
E.g.Program
5/21/2014 Version-1.2 73
Exiting the Program
A C program normally terminates when execution reaches the
closing brace of the main() function. However, a program can be
terminated at any time by calling the library function exit().

The exit() Function
The exit() function terminates program execution and returns
control to the operating system. This function takes a single
type int argument that is passed back to the operating
system to indicate the program's success or failure.
The syntax of the exit() function is
exit(status);
If status has a value of 0, it indicates that the program
terminated normally. A value of 1 indicates that the program
terminated with some sort of error. The return value is
usually ignored.
To use the exit() function, a program must include the header
file stdlib.h.
5/21/2014 Version-1.2 74
Program to find roots of quadratic equation
#include<ctype.h>
# include <math.h>
#include<stdio.h>
main()
{
float a,b,c,dino,disc,x1,x2,xr,xi,x;

printf(\n ENTER THE value FOR THE 1 NUMBERS:");
scanf("%f",&a);
printf(\n ENTER THE value FOR THE 2 NUMBERS:");
scanf("%f",&b);
printf("ENTER THE value FOR THE 3 NUMBERS:");
scanf("%f",&c);
disc=b*b-4*a*c;
5/21/2014 Version-1.2 75
Program to find roots of quadratic equation
if (disc>0)
{
printf("THE ROOTS ARE REAL AND DISTINCT:-\n");
dino=2*a;
x1=(-b+sqrt(disc))/dino;
x2=(-b-sqrt(disc))/dino;
printf("\n");
printf("THE FIRST ROOT: %f\n",x1);
printf("\n");
printf("THE SECOND ROOT: %f\n",x2);
}
5/21/2014 Version-1.2 76
Program to find roots of quadratic equation
else if(disc<0)
{
printf("THE ROOTS ARE COMPLEX:-\n");
printf("\n");
dino=2*a;
xr=-b/dino;
xi=sqrt(abs(disc))/dino;
printf("THE FIRST COMPLEX ROOT: %f\n",xr);
printf("\n");
printf("THE SECOND COMPLEX ROOT: i%f\n",xi);
}
5/21/2014 Version-1.2 77
Program to find roots of quadratic equation
else
{
printf("THE ROOTS ARE COMPLEX:-\n");
x=-b/(2*a);
printf("\n");
printf("ROOTS ARE: %f%f\n",x,x);
}

}
5/21/2014 Version-1.2 78
Company C Aptitude Questions
1) What is the output of the following question
(Wipro)

main()
{
int result=0 ,temp, n=7623;
while(n){
temp=n%10;
result =result * 10+ temp;
n=n/10;
}
printf("%d\n",result);
}
5/21/2014 Version-1.2 79
2) What is the output of the following question (Wipro)

If A>B then
F=F(G);
else B>C then
G=G(F);

in this , for 75% times A>B and 25% times B>C there
are 10000 instructions ,then the ratio of F to G
[a] 7500:2500 [b] 7500:625 [c] 7500:625

Ans :[a]
5/21/2014 Version-1.2 80
3)What is the output ? (IBM)
int i=10;
printf("%d%d%d",i,i++,++i);
ans: compiler dependent

4) What is the output ? (IBM)

printf("Enter two values a and b:"):
scanf("%d%d",a,b);
printf("%d+%d=%d",a,b,a+b);
ans:core dumped
5/21/2014 Version-1.2 81
5) What is the output ? (IBM)
main()
{
int I;
for(i=0;i<20;i++) {
switch(i){
case 0:i+=5;
case 1:i+=2;
case 5:i+=5;
default : i+=4;
break;}
printf("%d,",i);
}
}
a)0,5,9,13,17
b)5,9,13,17
c)12,17,22
d)16,21


Ans : 16, 21
5/21/2014 Version-1.2 82
6) A>B, B>C, C=D, D>E, then which is greatest (Wipro)
?

7) The C language terminator is (Tcs)
(a) semicolon
(b) colon
(c) period
(d) exclamation mark

8) What is false about the following -- A compound statement is
(TCS)
(a) A set of simple statements
(b) Demarcated on either side by curly brackets
(c) Can be used in place of simple statement
(d)* A C function is not a compound statement.
5/21/2014 Version-1.2 83
9. Main must be executed as (TCS)
(a)* The first function in the program
(b) Second function in the program
(c) Last function in the program
(d) Any where in the program

10. Which of the following about automatic variables within a
function is not correct ?
(a) Its type must be declared before using the
variable
(b) They are local
(c) They are not initialised to zero
(d)* They are global

5/21/2014 Version-1.2 84
11. Which of the following about the C comments is incorrect ?
(a) C comments can go over multiple lines
(b) Comments can start any where in the line
(c) A line can contain comments with out any
language
statements
(d) Comments can occur within comments

12. What is the value of y in the following code?
x=7;
y=0;
if (x=6) y=7;
else y=1;
(a) 7 (b) 0
(c) 1 (d) 6

5/21/2014 Version-1.2 85
13) What is y value of the code if input x=10 (TCS)
y=5;
if (x==10) ;
else if(x==9) ;
else y=8;
(a)9 (b)8
(c)*5 (d)7

14) The operator for exponential is
(a) **
(b) ^
(c) %
(d) not available
5/21/2014 Version-1.2 86
15) cond 1?cond 2?cond 3?:exp 1:exp 2:exp 3:exp 4;
is equivalent to which of the following?
(a) if (cond 1) exp 1;
else if (cond 2) exp 2;
else if (cond 3) exp 3;
else exp 4;

(b) if (cond 1)
if cond 2
if cond 3
exp 1;
else exp 2;
else exp 3;
else exp 4;
(c) if cond 1 && cond 2 && cond 3
exp 1 |exp 2|exp 3|exp 4;
(d) if cond 3
exp 1;
else if cond 2 exp 2;
else if cond 3 exp 3;
else exp 4;
5/21/2014 Version-1.2 87
Objectives
The loop
The do while loop
The for loop
The break Statement
The continue Statement
The goto Statement
Ending Loops Early
The switch Statement
Exiting the Program
The exit() Function


5/21/2014 Version-1.2 88
Loops
A C programming construct that executes a block of
one or more statements a certain number of times.

It is sometimes called the for loop because program
execution typically loops through the statement more
than once.

There are 3 loops in C programming

1. For loop
2. while loop
3. Do while loop
5/21/2014 Version-1.2 89
The for loop
The for statement is a C programming construct that
executes a block of one or more statements a certain number
of times.
for ( initial; condition; increment )
statement;
1. The expression initial is evaluated. initial is usually an
assignment statement that sets a variable to a particular
value.
2. The expression condition is evaluated. condition is
typically a relational expression.
3. If condition evaluates to false (that is, as zero), the for
statement terminates, and execution passes to the first
statement following statement.
4. If condition evaluates to true (that is, as nonzero), the C
statement(s) in statement are executed.
5. The expression increment is evaluated, and execution
returns to step 2.
E.g. Program (Multiplication Table )
5/21/2014 Version-1.2 90
To generate multiplication table
main()
{
int num,counter;
printf("Enter any number :");
scanf("%d",&num);
for(counter=1;counter<=10;counter++
)
printf("%d x %d =
%d\n",num,counter,num*counter);
}
5/21/2014 Version-1.2 91
program to generate even and odd number
main()
{
int counter;
printf("printing even numbers in 0 to 100\n\n");
for(counter=0;counter<=100;counter+=2)
printf("%4d",counter);

printf("\nprinting odd numbers in 1 to 100");
printf("\n");

for(counter=1;counter<=100;counter += 2)
printf("%4d",counter);
printf("\n");

}
5/21/2014 Version-1.2 92
A program to print fibonacci series
main()
{
int
firstnum=0,secondnum=1,resultnum=1,counter,num;
printf("Enter any number :");
scanf("%d",&num);
for(counter=0;counter<num;counter++) {
printf(" %d",resultnum);
resultnum=firstnum+secondnum;
firstnum=secondnum;
secondnum=resultnum;
}
}
5/21/2014 Version-1.2 93
Factorial of the number
#include<stdio.h>
main()
{
int num,fact=1,i;

printf("ENTER any number:");
scanf("%d",&num);

for (i=num; i>0; i--)
fact=fact*i;

printf("THE factorial of %d IS : %d",num,fact);
}
5/21/2014 Version-1.2 94
Prime numbers between 1 to 100
#include <stdio.h>
#include <math.h>
main()
{
int m,n,i,j,flag=1;
printf("enter 2 numbers\n");
scanf("%d%d",&m,&n);
for(i=m;i<=n;i++) {
flag = 1;
5/21/2014 Version-1.2 95
Prime numbers between 1 to 100
for(j=2;j<=sqrt(i);j++) {
if(i%j==0) {
flag=0;
break;
}
}
if(flag==1)
printf("prime no: %d\n",i);
}
printf("\n");
}
5/21/2014 Version-1.2 96
The while loop
The while statement, also called the while loop,
executes a block of statements as long as a specified
condition is true.

Syntax : while (condition)
statement

1. The expression condition is evaluated.
2. If condition evaluates to false (that is, zero), the while
statement terminates, and execution passes to the first
statement following statement.
3. If condition evaluates to true (that is, nonzero), the C
statement(s) in statement are executed.
4. Execution returns to step 1
5/21/2014 Version-1.2 97
A program to find number of vowels
main()
{
char ch;
int counter=0;
printf("\n Enter any String ");
while((ch=getchar()) !='\n') {
switch(ch) {
case 'a': case 'A':
case 'e': case 'E':
case 'i': case 'I':
case 'o': case 'O':
case 'u': case 'U':
counter++; break;
}
}
printf("number of vowels %d",counter);
}
5/21/2014 Version-1.2 98
The do...while Loop
the do...while loop, which executes a block of statements as long as
a specified condition is true. The do...while loop tests the condition
at the end of the loop rather than at the beginning, as is done by
the for loop and the while loop.

do
statements
while(condition);

1. The statements in statement are executed.

2. condition is evaluated. If it's true, execution returns to step 1. If it's
false, the loop terminates.

The statements associated with a do...while loop are always
executed at least once. This is because the test condition is
evaluated at the end, instead of the beginning, of the loop.

5/21/2014 Version-1.2 99
A program to reverse a number
#include<stdio.h>
main()
{
int num,rev,r;
char rep='y';
do {
system("clear");
printf(\n ENTER ANY number:");
scanf("%d",&num);
printf("THE reverse OF THE NUMBER i.e '%d' IS:
",num);
rev=0;
5/21/2014 Version-1.2 100
A program to reverse a number
while(num!=0) {
r=(num % 10);
num=(num / 10);
rev=rev*10+r;
}
printf("%d\n",rev);
printf("Do you wish to continue [y/n] or [Y/N]:")
_fpurge(stdin);
scanf("%c",&rep);
}
while(rep=='y' || rep=='Y');
printf("Press any key return back to the
program...........");
}
5/21/2014 Version-1.2 101
Nested Loops
The term nested loop refers to a loop that is contained
within another loop.. C places no limitations on the
nesting of loops, except that each inner loop must be
enclosed completely in the outer loop; overlapping
loops are not allowed.

Good indenting style makes code with nested loops
easier to read. Each level of loop should be indented
one step further than the last level. This clearly labels
the code associated with each loop.
5/21/2014 Version-1.2 102
Ending loops early
In all three loops, termination or exit of the loop occurs only when a
certain condition occurs. To exert more control over loop execution.
The break and continue statements provide this control.

The break Statement

break is used inside a loop or switch statement. It causes the control
of a program to skip past the end of the current loop (for, while, or
do...while) or switch statement. No further iterations of the loop
execute;
The following is an example:
for (count = 0; count < 10; count++)
if ( count == 5 )
break;
5/21/2014 Version-1.2 103
The continue Statement
Like the break statement, the continue statement can be
placed only in the body of a for loop, a while loop, or a
do...while loop. When a continue statement executes, the
next iteration of the enclosing loop begins immediately. The
statements between the continue statement and the end of
the loop aren't executed.

E.g.int x;
printf("Printing only the even numbers from 1 to 10\n");
for( x = 1; x <= 10; x++ )
{
if( x % 2 != 0 ) /* See if the number is NOT even
*/
continue; /* Get next instance x */
printf( "\n%d", x );
}
5/21/2014 Version-1.2 104
The goto Statement
The goto statement is one of C's unconditional jump, or branching,
statements. When program execution reaches a goto statement,
execution immediately jumps, or branches, to the location specified
by the goto statement.

This statement is unconditional because execution always branches
when a goto statement is encountered; the branch doesn't depend on
any program conditions (unlike if statements, for example).

A goto statement and its target must be in the same function, but
they can be in different blocks.
syntax goto location;

location is a label statement that identifies the program location
where execution is to branch. A label statement consists of an
identifier followed by a colon and a C statement:

location: a C statement;
5/21/2014 Version-1.2 105
Infinite Loops (ODD Loops)

An infinite loop is one that, if left to its own devices, would run
forever. It can be a for loop, a while loop, or a do...while loop.
For example,
while (1)
{ /* additional code goes here */}
An infinite loop is created. The condition that the while tests is
the constant 1, which is always true and can't be changed by
the program.

The break statement is used to exit a loop. Without the break
statement, an infinite loop would be useless.

An infinite for loop or an infinite do...while loop, can also be
done as follows:
for (;;) { /* additional code goes here */}

do { /* additional code goes here */} while (1);
5/21/2014 Version-1.2 106
Input and Output
5/21/2014 Version-1.2 107
Objectives
Input and Output
The Standard Input Output File
Character Input / Output
getchar
putchar
Formatted Input / Output
printf
scanf
Whole Lines of Input and Output
gets
puts
5/21/2014 Version-1.2 108
Fundamentals of Input and Output
To display some information on the
screen or to get some data from the
keyboard we need input and output
functions

Classification of Input /Output functions
printf() , scanf()
Formatted I/O
Character I/O
getchar(), putchar()
String I/O
gets(),puts()
Unformatted I/O
I/O
5/21/2014 Version-1.2 109
Formatted I/O
The printf() Function

The printf() function, part of the standard C
library, is perhaps the most versatile way for a
program to display data on-screen.

The printf() Format Strings
A printf() format string specifies how the
output is formatted.

Literal text is displayed exactly as entered in
the format string.
5/21/2014 Version-1.2 110
Formatted I/O
An escape sequence provides special formatting control.
An escape sequence consists of a backslash (\) followed
by a single character

A conversion specifier consists of the percent sign (%)
followed by a single character. In the example, the
conversion specifier is %d.

The %d tells printf() to interpret the variable x as a
signed decimal integer.

When using printf(),need to include the standard
input/output header file, stdio.h
5/21/2014 Version-1.2 111
Unformatted Character I/O
The character input functions read input from a stream one character
at a time.

The getchar() Function
The function getchar() obtains the character from the stream stdin.
It provides buffered character input with echo, and its prototype is

int getchar(void);

The putchar() function

The C library's character output functions send a single character to
a stream. The function putchar() sends its output to stdout (normally
the screen).

The prototype for putchar(), which is located in STDIO.H, is as
follows

int putchar(int c);
5/21/2014 Version-1.2 112
Whole Lines of Input and Output
Inputting Strings Using the gets() Function

The gets() function gets a string from the keyboard.
When gets() is called, it reads all characters typed at the
keyboard up to the first newline character (which is
generated by pressing Enter). This function discards the
newline, adds a null character, and gives the string to
the calling program.

If there is a problem getting the string, gets() returns
null.

Displaying Strings Using the puts() Function

The programs display strings on-screen more often than
they display single characters. The library function puts()
displays strings.
5/21/2014 Version-1.2 113
Displaying Messages with puts()
The puts() function can also be used to
display text messages on-screen, but it
can't display numeric variables. puts()
takes a single string as its argument
and displays it, automatically adding a
new line at the end

Any program that uses puts() should
include the header file stdio.h. Note
that stdio.h should be included only
once in a program.
5/21/2014 Version-1.2 114
Formatted Input / Output
To input / output mixed data types we need format specifiers
Conversion Specifiers
The format string must contain one conversion specifier for
each printed variable.
pointer Pointer type %p
unsigned long Unsigned long decimal
integer
%lu
unsigned int, unsigned
short
Unsigned decimal integer %u
char arrays Character string %s
float, double Decimal floating-point number %f
long Signed long decimal integer %ld
int, short Signed decimal integer %d
char Single character %c
Types Converted Meaning Specifier
5/21/2014 Version-1.2 115
Formatted Input/Output
The format string must contain one conversion specifier for
each printed variable.
printf(%d + %d = %d ,a,b,a+b);

scanf() uses a format string to describe the format of the
input. The format string utilizes the same conversion
specifiers as the printf() function.

scanf() is a function that uses a conversion specifier in a given
format-string to place values into variable arguments.

The arguments should be the addresses of the variables
rather than the actual variables themselves.

For numeric variables, it is possible to pass the address by
putting the address-of operator (&) at the beginning of the
variable name. When using scanf(),include the stdio.h header
file.

5/21/2014 Version-1.2 116
Functions
5/21/2014 Version-1.2 117
Objective
What a function is and what its
parts are
About the advantages of structured
programming with functions
How to create a function
How to declare local variables in a
function
How to return a value from a
function to the program
How to pass arguments to a
function
Recursive functions


5/21/2014 Version-1.2 118
Functions: The Basics
Functions are those, which break large computing tasks
into smaller ones .A function is a self-contained block of
statements that perform a coherent task of some kind.

A function is defined as a name given to an independent
section of C code that performs a specific task

Each function has a unique name. By using that name in
another part of the program, it is possible to execute the
statements contained in the function. This is known as
calling the function. A function can be called from within
another function.

A function can return a value to the calling program.
When program calls a function, the statements it
contains are executed. If necessary, these statements
can pass information back to the calling program.
5/21/2014 Version-1.2 119
How a Function Works
Any C program contains at least one function it must be
main(). There is no limit on the number of functions in a C
program. Always execution begins with main().

A function will not be executed until the function is called by
another part of the program. When a function is called, the
program can send the function information in the form of one
or more arguments.

An argument is a mechanism used to convey information to
the function . The statements in the function then execute,
performing whatever task each was designed to do

When the function's statements have finished, execution
passes back to the same location in the program that called
the function. Functions can send information back to the
program in the form of a return value. The arguments are
sometimes called as parameter.
5/21/2014 Version-1.2 120
Function definition
Function Prototype

return_type function_name( arg-type name-1,...,arg-type name-n);

A function prototype provides the compiler with a description of a
function that will be defined at a later point in the program.

Function Definition

return_type function_name( arg-type name-1,...,arg-type name-n)
{
/* statements; */
}

A function definition is the actual function. The definition contains the code that
will be executed.
5/21/2014 Version-1.2 121
Writing a Function
The first step in writing a function is that to know what the function
has to do.

The Function Header
The first line of every function is the function header, which has three
components, each serving a specific function.

1. The Function Return Type
The function return type specifies the data type that the function
returns to the calling program. The return type can be any of C's data
types: char, int, long, float, or double. It is also defined that function
doesn't return a value by using a return type of void.

2. The Function Name
Naming a function is fully depend on the user, but it should follow
the rules for C variable names. A function name must be unique

3. The Parameter List
Many functions use arguments, which are values passed to the
function when it's called.
5/21/2014 Version-1.2 122
Arguments / Parameters
A parameter is an entry
in a function header;
it serves as a "placeholder
for an argument.

A function's parameters are
fixed; they do not change
during program execution.

The Function Body
The function body is enclosed in braces, and it
immediately follows the function header. It's here
that the real work is done.
An argument is an actual
value passed to the
function by the calling
program.

Each time a function is
called, it can be passed
different arguments.
In C, a function must be
passed the same number
and type of arguments
each time it's called, but
the argument values can
be different.
5/21/2014 Version-1.2 123
Variables declaration in function
It is possible to declare variables within the body of a
function. Variables declared in a function are called
local variables. The term local means that the variables
are private to that particular function and are distinct
from other variables of the same name declared
elsewhere in the program.

Function Statements
There is essentially no limitation on the statements that
can be included within a function. The only thing should
not be done inside a function is define another function.
It is possible to use all other C statements, including
loops, if statements, and assignment statements. Can
call library functions and other user-defined functions.
5/21/2014 Version-1.2 124
Function header
Function length
C places no length restriction on functions, but as a
matter of practicality, it is advisable to keep functions
relatively short.

Returning a Value
To return a value from a function, return keyword is
used, followed by a C expression.

When execution reaches a return statement, the
expression is evaluated, and execution passes the value
back to the calling program.
5/21/2014 Version-1.2 125
Function Prototype
The prototype for a function is identical to the function
header, with a semicolon added at the end. Like the
function header, the function prototype includes
information about the function's return type, name, and
parameters.

The prototype's job is to tell the compiler about the
function's return type, name, and parameters. With this
information, the compiler can check every time the
source code calls the function and verify that it is
passing the correct number and type of arguments to
the function and using the return value correctly. If
there's a mismatch, the compiler generates an error
message.

They should be placed before the start of main() or
before the first function is defined.
5/21/2014 Version-1.2 126
Passing Arguments to a Function
To pass arguments to a function, listing them in parentheses
following the function name is a must. The number of arguments and
the type of each argument should match the parameters in the
function header and prototype.

For example, if a function is defined to take two type int arguments,
It is mandatory to pass exactly two int arguments--no more, no less-
-and no other type.

If the function takes multiple arguments, the arguments listed in the
function call are assigned to the function parameters in order: the
first argument to the first parameter, the second argument to the
second parameter, and so on.

Each argument can be any valid C expression: a constant, a variable,
a mathematical or logical expression, or even another function (one
with a return value).
5/21/2014 Version-1.2 127
Here is the function power and a main program to exercise
it, so you can see the whole structure at once.

int power(int m, int n); /* test power function */

main() {
int i;
for (i = 0; i < 10; ++i)
printf("%d %d %d\n", i, power(2,i), power(-3,i));
return 0;
} /* power: raise base to n-th power; n >= 0 */

int power(int base, int n)
{
int i, p = 1;
for (i = 1; i <= n; ++i) p = p * base;
return p;
}
5/21/2014 Version-1.2 128
Calling Functions
There are two ways to call a function

Any function can be called by simply using its name and argument list alone in
a statement is called as call by value, as in the following example. If the
function has no return value, then it is void function.

void swap (10 , 20) ;

functions that have a return value. Because these functions evaluate
to a value (that is, their return value), they are valid C expressions
and can be used anywhere a C expression can be used.

For example :
int power(int base, int n)
{
int i, p = 1;
for (i = 1; i <= n; ++i) p = p * base;
return p;
}
5/21/2014 Version-1.2 129
# include <stdio.h>
void swap(int, int); //function prototype

main()
{
int p,q;
printf("Enter two integers\n");
scanf("%d%d",&p,&q);
printf("\np = %d,q = %d\n",p,q);
swap(p,q); //function invocation
printf("\np = %d,q = %d\n",p,q);
}

void swap(int x, int y) //function definition
{
int temp = x;
x = y;
y = temp;
}
5/21/2014 Version-1.2 130
The second method of calling a function by
address
# include <stdio.h>
void swap(int *, int *); //function prototype

main()
{
int p,q;
printf("Enter two integers\n");
scanf("%d%d",&p,&q);
printf("\np = %d,q = %d\n",p,q);
swap(&p,&q); //function invocation by sending
an address
printf("\np = %d,q = %d\n",p,q);
}

void swap(int *x, int *y) //function definition
{
int temp = *x;
*x = *y;
*y = temp;
}
5/21/2014 Version-1.2 131
Recursion
The term recursion refers to a situation in which a
function calls itself either directly or indirectly. Indirect
recursion occurs when one function calls another
function that then calls the first function. C allows
recursive functions, and they can be useful in some
situations.

For Example:
main()
{
puts(I will be printed till stack overflows);
main();
}
5/21/2014 Version-1.2 132
/* PROGRAM TO FIND THE factorial OF THE NUMBER recursivly */
# include <stdio.h>

int factorial(int);

main()
{
int num;
printf("Enter a number \n");
scanf("%d",&num);
printf("%d\n",factorial(num));
}
int factorial(int n)
{
if(n == 0)
return 1;
return (n * factorial(n - 1));
}
5/21/2014 Version-1.2 133
1) What is the value of Zap if n = 6 (Wipro)
int zap(int n)
{
int Zap;
if(n<=1) Zap=1;
else Zap=zap(n-3)+zap(n-1);
}
Ans : 9

2) Write one statement equivalent to the following two
statements (IBM)
x=sqr(a);
return(x);
Choose from one of the alternatives
(a) return(sqr(a));
(b) printf("sqr(a)");
(c) return(a*a*a);
(d) printf("%d",sqr(a));
5/21/2014 Version-1.2 134
3) What is returned (TCS)
conv(int t){
int u;
u=5/9 * (t-32);
return(u);
}
(a) 15 (b) 0
(c) 16.1 (d) 29

4) What is returned (TCS)
func(int i)
{
if(i%2) return 0;
else return 1;
}
main()
{
int i=3;
i=func(i);
i=func(i);
printf("%d",i);
}
(a) 3 (b) 1
(c) 0 (d) 2
5/21/2014 Version-1.2 135
5) main (){ } (TCS)
int a;
f1(){}
f2(){}

which of the functions is int a available for?

a. all of them
b. only f2
c. only f1
d. f1 and f2 only
5/21/2014 Version-1.2 136
6) C allows
a) only call by value
b) only call by reference
c) both


7) What is the output of this program?
#include<stdio.h>
int my(int va)
{
if(va==1)
return (1);
else return (va+my(va-1));
}
void main(void)
{
int i=6;
printf("%d",my(i));
}
5/21/2014 Version-1.2 137
Storage Class Specifies
5/21/2014 Version-1.2 138
Storage Class Specifies
There are four storage class specifiers
supported by C:
extern
static
register
Auto

These specifiers tell the compiler how to store
the subsequent variable. The general form of
a declaration that uses one is shown here.

storage_specifier type var_name;
5/21/2014 Version-1.2 139
Typical memory arrangement
Reserved memory
text
Initialized data
Uninitialized data
(bss)
Heap
Stack
Command-line
arguments
And environment
variables
5/21/2014 Version-1.2 140
Local Variables
Variables that are declared inside a function are called local variables. In some
C/C++ literature, these variables are referred to as automatic variables.

Local variables may be referenced only by statements that are inside the block
in which the variables are declared.

That is, a local variable is created upon entry into its block and destroyed
upon exit.

The most common code block in which local variables are declared is the
function.
example, consider the following two functions:
void func1(void)
{
int x;
x = 10;
}
void func2(void)
{
int x;
x = -199;
}
5/21/2014 Version-1.2 141
Global Variables
Unlike local variables, global variables are known throughout
the program and may be used by any piece of code. Also, they
will hold their value throughout the program's execution. You
create global variables by declaring them outside of any
function.
Any expression may access them, regardless of what block of
code that expression is in.

#include <stdio.h>
int count; /* count is global */
void func1(void);
void func2(void);

int main(void)
{
count = 100;
func1();
return 0;
}
5/21/2014 Version-1.2 142
void func1(void)
{
int temp;
temp = count;
func2();
printf("count is %d", count); /* will print 100 */
}

void func2(void)
{
int count;
for(count=1; count<10; count++)
putchar('.');
}
5/21/2014 Version-1.2 143
volatile
The modifier volatile tells the compiler that a variable's value
may be changed in ways not explicitly specified by the
program. For example, a global variable's address may be
passed to the operating system's clock routine and used to
hold the real time of the system. In this situation, the
contents of the variable are altered without any explicit
assignment statements in the program.

A variable should be declared volatile whenever its value can
be changed by something beyond the control of the program
in which it appears, such as a concurrently executing thread

Volatile, can appear only once in a declaration with any type
specifier; however, they cannot appear after the first comma
in a multiple item declaration. For example, the following
declarations are legal :
5/21/2014 Version-1.2 144
/* Let T denotes some data type */
typedef volatile T i; volatile T i; T volatile i ;
And the following declaration is illegal
T i, volatile vi ;

Syntax
Keyword volatile can be placed before or after the data type in the
variable definition. For example following declaration are identical:
Volatile T a =3;T volatile a=3; The declaration declares and
initializes an object with type volatile T whose value will be always
read from memory.

Pointer declaration

volatile T * ptr;
T volatile * ptr; Ptr is a a pointer to a volatile T:
volatile pointer to a volatile variable int volatile * volatile ptr;
5/21/2014 Version-1.2 145
volatile can be applied to derived types such as an array type
,in that case, the element is qualified, not the array type.

When applied to struct types entire contents of the struct
become volatile. You can apply the volatile qualifier to the
individual members of the struct.

Type qualifiers are relevant only when accessing identifiers as
l-values in expressions. volatile does not affects the range of
values or arithmetic properties of the object.. To declare the
item pointed to by the pointer as volatile, use a declaration of
the form:

volatile T *vptr;

To declare the value of the pointer - that is, the actual
address stored in the pointer - as volatile, use a declaration
of the form:

T* volatile ptrv;
5/21/2014 Version-1.2 146
Use of volatile

An object that is a memory-mapped I/O port

An object variable that is shared between multiple
concurrent processes.

An object that is modified by an interrupt service
routine.

An automatic object declared in a function that
calls setjmp and whose value is-changed between
the call to setjmp and a corresponding call to
longjmp .

5/21/2014 Version-1.2 147
# An object that is shared between multiple concurrent processes
if two threads/tasks concurrently assign distinct values
to the same shared non-volatile variable, a subsequent
use of that variable may obtain a value that is not equal
to either of the assigned values, but some
implementation-dependent mixture of the two values.
so a global variable references by multiple thread
programmers must declare shared variable as volatile.

the compiler may use a register to store the num
variable in the main thread , so the change to the value
by the second thread are ignored . The volatile modifier
is a away of telling the compiler that no optimization
applied to the variable its value be not placed in
register and value may change outside influence during
evaluation.
5/21/2014 Version-1.2 148
volatile int num ;
void* foo(){
while(1) {
++num ;
sleep(1000);
}
}

main(){
int p ;
void *targ =NULL ;
thread_t id ;
num = 0;
p = thr_create((void*)NULL , 0,foo,targ,0,&id);
if(!p) printf(" can not create thread ");
while(1) {
printf("%d" , num ) ;
}
}
5/21/2014 Version-1.2 149
# An automatic object declared in a function that calls setjmp and whose
value is-changed between the call to setjmp and a corresponding call to
longjmp
static jmp_buf buf ;
main( )
{
volatile int b;
b =3 ;
if(setjmp(buf)!=0) {
printf("%d ", b) ;
exit(0);
}
b=5;
longjmp(buf , 1) ;
}
5/21/2014 Version-1.2 150
volatile variable isn't affected by the
optimization. So value of b is after the
longjump is the last value variable
assigned. Without volatile b may or
may not be restored to its last value
when the longjmp occurs.
5/21/2014 Version-1.2 151
# An object modified by an interrupt service routine
Interrupt service routines often set variables that are tested in main
line code. One problem that arises as soon as you use interrupt is
that interrupt routines need to communicate with rest of the code .A
interrupt may update a variable num that is used in main line of
code .An incorrect implementation of this might be:
static long int num ;
void interrupt update(void)
{
++num ;
}
main()
{
long val ;
val = num ;
while(val !=num)
val = num ;
return val ;
}
5/21/2014 Version-1.2 152
When compilation system execute while statement, the
optimizer in compiler may notice that it read the value
num once already and that value is still in the register.

Instead of re reading the value from memory, compiler
may produce code to use the (possibly messed up)
value in the register defeating purpose of original C
program.

Some compiler may optimize entire while loop
assuming that since the value of num was just assigned
to val , the two must be equal and condition in while
statement will therefore always be false .
5/21/2014 Version-1.2 153
To avoid this ,you have to declare num to be volatile that
warns compilers that certain variables may change because of
interrupt routines.

static volatile long int num ;

With volatile keyword in the declaration the compiler knows
that the value of num must b read from memory every time it
is referenced.
5/21/2014 Version-1.2 154
extern
C/C++ allows separate modules of a large program to
be separately compiled and linked together, there
must be some way of telling all the files about the
global variables required by the program.

Although C technically allows you to define a global
variable more than once, it is not good practice (and
may cause problems when linking). More importantly,
in C++, you may define a global variable only once.

extern lets the compiler know what the types and
names are for these global variables without actually
creating storage for them again. When the linker links
the two modules, all references to the external
variables are resolved.
5/21/2014 Version-1.2 155
5/21/2014 Version-1.2 156
static Variables
static variables are permanent variables within their
own function or file. Unlike global variables, they are
not known outside their function or file, but they
maintain their values between calls.

This feature makes them useful when you write
generalized functions and function libraries that other
programmers may use.

static has different effects upon local variables and
global variables.

static Local Variables When you apply the static
modifier to a local variable, the compiler creates
permanent storage for it, much as it creates storage for
a global variable.
5/21/2014 Version-1.2 157
static Variables
The key difference between a static local variable and a
global variable is that the static local variable remains
known only to the block in which it is declared.

In simple terms, a static local variable is a local variable
that retains its value between function calls.

Applying the specifier static to a global variable
instructs the compiler to create a global variable that is
known only to the file in which you declared it.

This means that even though the variable is global,
routines in other files may have no knowledge of it or
alter its contents directly, keeping it free from side
effects. For the few situations
5/21/2014 Version-1.2 158
where a local static cannot do the job,
you can create a small file that
contains only the functions that need
the global static variable, separately
compile that file, and use it without
fear of side effects.
5/21/2014 Version-1.2 159
void fun(void);
main()
{
fun();
fun();
fun();
fun();
}
void fun(void)
{
static int i = 0;
printf("I is %d\n",i++);
}
5/21/2014 Version-1.2 160
static global Variables
//app.c
void fun(void);
void fun1 (void);

static int i = 0;
main()
{
fun();
fun();
fun1();
fun1();
}

void fun(void)
{ printf("I is
%d\n",i++); }

// Lib.c
void fun1(void)
{
printf("I is
%d\n",i++);
}

Linker error
5/21/2014 Version-1.2 161
register Variables
The register storage specifier originally applied only to
variables of type int, char, or pointer types. However, in
Standard C, register's definition has been broadened so
that it applies to any type of variable.

Originally, the register specifier requested that the
compiler keep the value of a variable in a register of the
CPU rather than in memory, where normal variables are
stored.

This meant that operations on a register variable could
occur much faster than on a normal variable because
the register variable was actually held in the CPU and
did not require a memory access to determine or
modify its value.
5/21/2014 Version-1.2 162
int int_pwr(register int m, register int e)
{
register int temp;
temp = 1;
for(; e; e - -) temp = temp * m;
return temp;
}
In this example, e, m, and temp are declared as register
variables because they are all used within the loop.

The fact that register variables are optimized for speed
makes them ideal for control of or use in loops.

In C, you cannot find the address of a register variable
using the & operator
5/21/2014 Version-1.2 163

5/21/2014 Version-1.2 164
1) Consider the following C code
main(){
int i=3,x;
while(i>0){
x=func(i);
i--;
}
int func(int n){
static sum=0;
sum=sum+n;
return(sum);
}

The final value of x is
(a) 6 (b) 8
(c) 1 (d) 3
5/21/2014 Version-1.2 165
1. #include<stdio.h>
Int main(void)
{
int x=4;
int a=2;
int b=4;
int c=8;
if(x==b) x=a;
else x=b;
if(x!=b) c=c+b;
else c=c+a;
printf("c=%d\n",c);
}
2. where does printf write its output

3.Write syntax of 'auto'. What it means?
5/21/2014 Version-1.2 166
4. Which is correct syntax?
unsigned long
double float
integer
struct int

5.Which is correct statement with printf to print, 30 character ,4
decimalvalue double value
%-30.4f
%-30.4e
%#30.4f
%4.30e
%-4.30f

6. maximum decimal number in a byte is ?

7. What the stdio.h contains?

5/21/2014 Version-1.2 167
8. What is the output of this program?
#include<stdio.h>
void main(void)
{
printf("2");
while(3)
printf("3");
printf("4");
}

9. What is the output of this program?
#include<stdio.h>
void main(void)
{
int v=2;
switch(v) {
case 1:printf("0");
case 2:printf("1");
case 3:printf("2");
default :printf("3");
break;
}
}
5/21/2014 Version-1.2 168
10. What is the output of this program?
#include<stdio.h>
void main(void)
{
int x=1/2;
if(x) printf("%d",x);
}
11) main()
{
extern int a;
a=10;
printf("%d",a);
}
5/21/2014 Version-1.2 169
Arrays
5/21/2014 Version-1.2 170
Objective
Why Arrays?
What Is an Array?
Single-Dimensional Arrays
Naming and Declaring Arrays
Initializing Arrays
Multidimensional Arrays
Initializing Multidimensional
Arrays
Maximum Array Size
5/21/2014 Version-1.2 171
Arrays
An array is a collection of data storage locations, each having
the same data type and the same name. Each storage
location in an array is called an array element.

Single-Dimensional Arrays
A single-dimensional array has only a single subscript. A
subscript is a number in brackets that follows an array's
name. This number can identify the number of individual
elements in the array.

Declaration of array is as follows :
float expenses[12];

The array is named expenses, and it contains 12 elements.
Each of the 12 elements is the exact equivalent of a single
float variable.
All of C's data types can be used for arrays .
5/21/2014 Version-1.2 172
Arrays
All of C's data types can be used for arrays

C array elements are always numbered starting at 0, so the 12
elements of expenses are numbered 0 through 11.

When an array is declared, the compiler sets aside a block of
memory large enough to hold the entire array. Individual array
elements can be stored in sequential memory locations.

Individual elements of the array are accessed by using the array
name followed by the element subscript enclosed in square brackets.

e.g. expenses[1]=34.90;
expenses[10] = expenses[11];

When using arrays, keep the element numbering scheme in mind: In
an array of n elements, the allowable subscripts range from 0 to n-1.
5/21/2014 Version-1.2 173
Naming and Declaring Arrays
An array name must be unique.

It can't be used for another array or for any other identifier
(variable, constant, and so on).

array declarations follow the same form as declarations of
non array variables, except that the number of elements in
the array must be enclosed in square brackets immediately
following the array name.

When an array is declared, one can specify the number of
elements with a literal constant (as was done in the earlier
examples) or with a symbolic constant
#define MONTHS 12
int array[MONTHS]; //is equivalent to below statement:
int array[12];
5/21/2014 Version-1.2 174
Initializing Single Dimensional Array
int array[4] = { 100, 200, 300, 400 };

If the array size is omitted, the compiler creates an array just
large enough to hold the initialization values. Thus, the
following statement would have exactly the same effect as the
previous array declaration statement:

int array[] = { 100, 200, 300, 400 };

It can be however, include too few initialization values, as in
this example:
int array[10] = { 1, 2, 3 };

If an array element is not explicitly initialized, it is not sure
that what value it holds when the program runs. If too many
initializers are included (more initializers than array elements),
the compiler detects an error.
5/21/2014 Version-1.2 175
A program to read and display the elements
#include<stdio.h>

main()
{
int element[10],ctr;
printf("\n Reading the elements\n");
for(ctr=0;ctr<10;ctr++){
printf("\n element %d is :\t",ctr+1);
scanf("%d",&element[ctr]);
}

printf("\n Printing the elements\n");
for(ctr=0;ctr<10;ctr++)
printf("%8d",element[ctr]);
}
5/21/2014 Version-1.2 176
Multidimensional Arrays
A multidimensional array has more than one subscript. A two-
dimensional array has two subscripts; a three-dimensional
array has three subscripts, and so on. There is no limit to the
number of dimensions a C array can have.

For example, a program that plays checkers can be written.
The checkerboard contains 64 squares arranged in eight rows
and eight columns. This program could represent the board
as a two-dimensional array, as follows:

int checker[8][8];

The resulting array has 64 elements: checker[0][0],
checker[0][1], checker[0][2]...checker[7][6], checker[7][7].

Similarly, a three-dimensional array could be thought of as a
cube. All arrays, no matter how many dimensions they have,
are stored sequentially in memory
5/21/2014 Version-1.2 177
Initializing Multidimensional
Arrays
Multidimensional arrays can also be initialized.

The list of initialization values is assigned to array elements in
order, with the last array subscript changing first.

For example:

int array[4][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

results as array[0][0] is equal to 1
array[0][1] is equal to 2
array[0][2] is equal to 3 and so on.
5/21/2014 Version-1.2 178
Initializing Multidimensional
Arrays
results as array[0][0] is equal to 1
array[0][1] is equal to 2
array[0][2] is equal to 3 and so on.

The following initialization is equivalent to the one just given:

int array[4][3] = { { 1, 2, 3 } , { 4, 5, 6 } ,{ 7, 8, 9 } , { 10,
11, 12 } };
Remember, a comma must separate initialization values even
when there is a brace between them. Also, be sure to use
braces in pairs a closing brace for every opening brace or the
compiler becomes confused.

E.g.Program
5/21/2014 Version-1.2 179
Adding matrix elements
#include<stdio.h>
main()
{
int m1[2][2],m2[2][2],m3[2][2];
int i,j,r,c;

printf("Enter matrix size\n");
scanf("%d%d",&r,&c);

printf("enter the elements into matrix m1\n");
for(i=0;i<c;i++)
for(j=0;j<c;j++)
scanf("%d",&m1[i][j]);
5/21/2014 Version-1.2 180
Adding matrix elements
printf("enter the elements into matrix m2\n");
for(i=0;i<r;i++)
for(j=0;j<c;j++)
scanf("%d",&m2[i][j]);

for(i=0;i<r;i++)
for(j=0;j<c;j++)
m3[i][j]=m1[i][j]+m2[i][j];

printf("Resultant matrix is ............\n");
for(i=0;i<r;i++){
for(j=0;j<c;j++)
printf("%d ",m3[i][j]);
}
}
5/21/2014 Version-1.2 181
PROGRAM TO MULTIPLY THE TWO MATRIX
#include<stdio.h>
#include<math.h>
main()
{
int a[10][10],b[10][10],c[10][10];
int row1,row2,col1,col2;
int i,j,k;
printf("ENTER THE ROW AND COLUMN ORDER FOR THE
MATRIX A :\n");
scanf("%d%d",&row1,&col1);
printf("ENTER THE ROW AND COLUMN ORDER FOR THE
MATRIX B :\n");
scanf("%d%d",&row2,&col2);
5/21/2014 Version-1.2 182
PROGRAM TO MULTIPLY THE TWO MATRIX
if ((row1 == row2) && (col1 == col2))
{
printf("ENTER THE %d ELEMENTS INTO %d * %d MATRIX A :\n,
row1*col2,row1,col1);
for (i=0; i<row1; i++)
for (j=0; j<col1; j++)
scanf("%d", &a[i][j]);
printf("MATRIX A \n");
for (i=0; i<row1; i++)
{
for (j=0; j<col1; j++)
printf("%d\t",a[i][j]);
printf("\n");
}
5/21/2014 Version-1.2 183
PROGRAM TO MULTIPLY THE TWO MATRIX
printf("ENTER THE %d ELEMENTS INTO %d * %d MATRIX B
:\n",row1*col2,row1,col1);
for (i=0; i<row2; i++)
for (j=0; j<col2; j++)
scanf("%d", &b[i][j]);

printf("MATRIX B \n");

for (i=0; i<row2; i++)
{
for (j=0; j<col2; j++)
printf("%d\t", b[i][j]);
printf("\n");
}
5/21/2014 Version-1.2 184
PROGRAM TO MULTIPLY THE TWO MATRIX
for (i=0; i<row1; i++)
for(j=0; j<col1; j++){
c[i][j]=0;
for (k=0; k<col2; k++)
c[i][j] = (c[i][j] + (a[i][k] * b[k][j]));
} printf("Resultant Matrix is\n");
for(i=0; i<row1; i++){
for(j=0; j<col2; j++)
printf("%d\t", c[i][j]);
printf("\n");
}
}else
printf("THE PRODUCT OF TWO MATRIX IS NOT POSSIBLE
\n");
}
5/21/2014 Version-1.2 185
THE TRANSPOSE OF THE MATRIX
#include<stdio.h>
main()
{
int a[10][10];
int row,col;
int i,j;
printf("ENTER THE ROW AND COLUMN ORDER FOR THE MATRIX
:\n");
scanf("%d%d",&row,&col);
if (row == col)
{
printf("ENTER MATRIX A :\n");
for (i=0; i<row; i++)
for (j=0; j<col; j++)
scanf("%d",&a[i][j]);

5/21/2014 Version-1.2 186
THE TRANSPOSE OF THE MATRIX
for (i=0; i<row; i++) {
for (j=0; j<col; j++)
printf("%d\t",a[i][j]);
printf("\n");
}
printf(" transpose OF THE MATRIX IS .......... \n");
for (i=0; i<row; i++) {
for (j=0; j<col; j++)
printf("%d\t",a[j][i]);
printf("\n");
}
}
}
5/21/2014 Version-1.2 187
THE NORM AND TRACE OF THE MATRIX
main()
{
int *a,i,j,n,trace=0;
float norm=0.0;
printf("ENTER THE ORDER OF THE MATRIX :");
scanf("%d",&n);
for (i=0; i<n; i++)
for (j=0; j<n; j++) {
scanf("%d",&a[i][j]);
norm=norm+a[i][j]*a[i][j];
}

5/21/2014 Version-1.2 188
THE NORM AND TRACE OF THE MATRIX
for(i=0; i<n; i++) trace += a[i][i];

for (i=0; i<n; i++) {
for (j=0; j<n; j++)
printf("%d\t",a[i][j]);
printf("\n");
}

printf("THE NORM OF THE MATRIX IS :%lf \n",norm);
printf("THE TRACE OF THE MATRIX IS:%d \n",trace);

}
5/21/2014 Version-1.2 189
Maximum Array Size
The size of an array in bytes depends on the number of
elements it has, as well as each element's size. Element
size depends on the data type of the array and
computer. These are the data type sizes for many PCs.

To calculate the storage space required for an array,
multiply the number of elements in the array by the
element size. For example, a 500-element array of type
float requires storage space of 500 * 4 = 2000 bytes.

one can determine storage space within a program by
using C's sizeof() operator; sizeof() is a unary operator,
not a function. It takes as its argument a variable name
or the name of a data type and returns the size, in
bytes, of its argument.

5/21/2014 Version-1.2 190
Selection sort
#include<stdio.h>

void selection(int [],int );

main()
{
int n,a[10],i;

printf("enter limit of an array");
scanf(" %d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);

selection(a,n);
}
5/21/2014 Version-1.2 191
Selection sort
void selection (int a[],int n)
{
int i,j,temp;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(a[i]<a[j]){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
for(i = 0;i < n;i ++)
printf("\n%d",a[i]);
}
5/21/2014 Version-1.2 192
Understanding Pointer

5/21/2014 Version-1.2 193
Objectives
What Is a Pointer
Declaring Pointers
Initializing Pointers
Pointers and Variable Types
Pointers and Arrays
Pointer Arithmetic
Incrementing Pointers
Other Pointer Manipulations
Passing Arrays to Functions
5/21/2014 Version-1.2 194
What Is a Pointer ?
To understand pointers, a basic knowledge of how the computer
stores information in memory is needed.

A PC's RAM consists of many thousands of sequential storage
locations, and each location is identified by a unique address. The
memory addresses in a given computer range from 0 to a maximum
value that depends on the amount of memory installed.

When declaring a variable in a C program, the compiler sets aside a
memory location with a unique address to store that variable. The
compiler associates that address with the variable's name. When the
program uses the variable name, it automatically accesses the
proper memory location. The location's address is used, but it is
hidden.

To summarize, a pointer is a variable that contains the address of
another variable. Now here are some details of using pointers in the
C programs.

5/21/2014 Version-1.2 195
Declaring Pointers
A pointer is a numeric variable and, like all variables,
must be declared before it can be used.

A pointer declaration takes the following form:

typename *ptrname;

Example

char *ch1, *ch2;
float *value, percent;
5/21/2014 Version-1.2 196
Initializing Pointers
Until a pointer holds the address of a variable, it isn't useful.

the program must put it there by using the address-of operator, the
ampersand (&). When placed before the name of a variable, the
address-of operator returns the address of the variable. Therefore,
initialize a pointer with a statement of the form

pointer = &variable;

5/21/2014 Version-1.2 197
Pointers and Variable Types
The address of a variable is actually the
address of the first (lowest) byte it occupies.

int vint = 12252;
char vchar = 90;
float vfloat = 1200.156004;

int *p_vint;
char *p_vchar;
float *p_vfloat;
5/21/2014 Version-1.2 198
Pointers and Variable Types

p_vint = &vint;
p_vchar = &vchar;
p_vfloat = &vfloat;
Each pointer is holds the address of the first byte of the
variable.
5/21/2014 Version-1.2 199
# include <stdio.h>
main()
{
int x = 5;
int *p = &x;
printf("x=%d\n",x);
printf("p=%u\n",p);
printf("&x=%u\n",&x);
printf("*p=%d\n",*p);
printf("&p=%u\n",&p);
printf("It is address of x *&p=%u\n",*&p);
}
5/21/2014 Version-1.2 200
void pointers
Pointers defined to be of a specific data type cannot hold the address
of some other type of variable.

To assign the address of an integer variable to a pointer of type
float. This problem can overcome by using a general purpose pointer
type called void pointer.

E.g. Void *v_ptr;

Pointers defined in this manner do not have any type associated with
them and can hold the address of any type of variable.

Pointers to void cannot be directly dereferenced like other pointer
variables using the indirection operator. Prior to dereferencing a
pointer to void, it must be suitably typecast to the required data
type.

Syntax : *((data type *))pointervariable;
5/21/2014 Version-1.2 201
E.g. void pointer

main()
{
int i1=100;
float f1=200.5;
void *vptr ;
vptr = &i1;
printf(" i1 contains %d",*((int
*)vptr));
}

5/21/2014 Version-1.2 202
Pointers and Arrays
An array name without brackets is a pointer to the
array's first element. Thus, if declared an array data[],
data is the address of the first array element.

Using the expression &data[0] to obtain the address of
the array's first element is allowed. In C, the
relationship (data == &data[0]) is true.

The name of an array is a pointer to the array.
Remember that this is a pointer constant; it can't be
changed and remains fixed for the duration of program
execution.
5/21/2014 Version-1.2 203
Pointers and Arrays
The declaration int a[10]; defines an array of size 10,
that is, a block of 10 consecutive objects named a[0],
a[1], ...,a[9].

The notation a[i] refers to the i-th element of the array.
If pa is a pointer to an integer, declared as ,

int *pa; then the assignment
pa = &a[0];

sets pa to point to element zero of a; that is,

pa contains the address of a[0].
5/21/2014 Version-1.2 204
Pointers and Arrays
a[i] -> is internally evaluated as :
Base address + index *
sizeof(data_type);
Thus a[5] :
By considering base address(2000)
which is evaluated as
2000 + 5 * 4 = 2020 -> cof(2020)
Example :

5/21/2014 Version-1.2 205
Pointers and Arrays
#include <stdio.h>
int my_array[] = {1,23,17,4,-5,100};

int *ptr;
int main(void)
{
int i; ptr = &my_array[0]; /* point our pointer to the
first element of the array */
printf("\n\n");
for (i = 0; i < 6; i++) {
printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A
*/
printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */
}
return 0;
}
5/21/2014 Version-1.2 206
Pointers and Arrays
main()
{
int num[10],i,j,t;
int *p=num;
printf("enter elements into the array\n");
for(i=0;i<5;i++)
scanf("%d",p+i);

for(i=0;i<5;i++)
for(j=0;j<5-1;j++) {
5/21/2014 Version-1.2 207
Pointers and Arrays
if (*(p+j) > *(p+(j+1)))
{
t=*(p+j);
*(p+j)=*(p+(j+1));
*(p+(j+1))=t;
}
}
puts("printing ...............\n");
for(i=0;i<5;i++)
printf("%d\n",*(p+i));
}
5/21/2014 Version-1.2 208
Pointer Arithmetic
There is a pointer to the first array element; the pointer must
increment by an amount equal to the size of the data type
stored in the array.
If ip points to the integer x, then *ip can occur in any context
where x could,
so *ip = *ip + 10; increments *ip by 10.
The unary operators * and & bind more tightly than
arithmetic operators, so the assignment y = *ip + 1 takes
whatever ip points at, adds 1, and assigns the result to y,
while *ip += 1 increments what ip points to,
as do ++*ip and (*ip)++
The parentheses are necessary in this last example; without
them, the expression would increment ip instead of what it
points to, because unary operators like * and ++ associate
right to left.
5/21/2014 Version-1.2 209
Other Pointer Manipulations
The only other pointer arithmetic operation is called
differencing, which refers to subtracting two pointers. If two
pointers are pointing to different elements of the same array,
subtract them and find out how far apart they are.
ptr1 - ptr2

Pointer comparisons are valid only between pointers that
point to the same array. Under these circumstances, the
relational operators ==, !=, >, <, >=, and <= work properly.

Lower array elements (that is, those having a lower
subscript) always have a lower address than higher array
elements. Thus, if ptr1 and ptr2 point to elements of the
same array, the comparison
5/21/2014 Version-1.2 210
Other Pointer Manipulations
ptr1 < ptr2

is true if ptr1 points to an earlier member of the array
than ptr2 does.
This covers all allowed pointer operations. Many
arithmetic operations that can be performed with regular
variables, such as multiplication and division, don't make
sense with pointers. The C compiler doesn't allow them.
For example, if ptr is a pointer, the statement

ptr *= 2;
generates an error message.
5/21/2014 Version-1.2 211
Pointers and Strings
C permits two alternate ways of achieving the same thing.
First, one might write:

char my_string[40] = {'T', 'e', 'd', '\0',}; But this also takes
more typing than is convenient. So, C permits:

char my_string[40] = "Ted"; When the double quotes are
used, instead of the single quotes as was done in the
previous examples, the nul character ( '\0' ) is automatically
appended to the end of the string.

#include <stdio.h>
char strA[80] = "A string to be used for demonstration
purposes";
char strB[80];
int main(void) {
5/21/2014 Version-1.2 212
Pointers and Strings
int main(void)
{
char *pA; /* a pointer to type character */
char *pB; /* another pointer to type character */
puts(strA); /* show string A */
pA = strA; /* point pA at string A */
puts(pA); /* show what pA is pointing to */
pB = strB; /* point pB at string B */
putchar('\n'); /* move down one line on the screen */
while(*pA != '\0') /* line A (see text) */
{
*pB++ = *pA++; /* line B (see text) */
}
*pB = '\0'; /* line C (see text) */
puts(strB); /* show strB on screen */
return 0;
}
5/21/2014 Version-1.2 213
Pointers and function arguments
Since C passes arguments to functions by value, there is no
direct way for the called function to alter a variable in the
calling function.
In the swap(a, b); function call by value , swap cant affect
the argument a and b in the routine that called it.
The way to obtain the desired effect is for the calling program
to pass pointer to the values to be changed :
Swap (&a, &b);
Since the operator & produces the address of a variable, &a is
a pointer to a.
Thus the function looks like:
void swap(int *px, int *py)
{
int temp = *px;
*px = *py;
*py = temp
}
5/21/2014 Version-1.2 214
Pointers and functions
When an array name is passed to a function, the location of the
initial element. Within the called function, this argument is a local
variable, and so an array name parameter is a pointer, that is, a
variable containing an address.
Here is a function xstrlen(), which computes the length of a string.

Main()
{
char str[25] = hello world;
printf(%d\n,xstrlen(str));
}

/* xstrlen: return length of string s */
int xstrlen(char *s)
{
int n;
for (n = 0; *s != '\0', s++)
n++;
return n;
}
5/21/2014 Version-1.2 215
We will illustrate more aspects of pointers and arrays by
studying versions of two useful functions adapted from the
standard library.

The first function is strcpy(s,t), which copies the string t to
the string s. It would be nice just to say s=t but this copies
the pointer, not the characters. To copy the characters, we
need a loop.

The array version first:
/* strcpy: copy t to s; array subscript version */
void strcpy(char *s, char *t)
{
int i;
i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
5/21/2014 Version-1.2 216
For contrast, here is a version of strcpy with pointers:
/* strcpy: copy t to s; pointer version */
void strcpy(char *s, char *t)
{
int i; i = 0;
while ((*s = *t) != '\0') {
s++; t++;
}
}
/* strcpy: copy t to s; pointer version 2 */
void strcpy(char *s, char *t)
{
while ((*s++ = *t++) != '\0') ;
}
As the final abbreviation, observe that a comparison against '\0' is
redundant, since the question is merely whether the expression is
zero. So the function would likely be written as

/* strcpy: copy t to s; pointer version 3 */
void strcpy(char *s, char *t) {
while (*s++ = *t++) ;
}
5/21/2014 Version-1.2 217
The second routine that we will examine is strcmp(s,t), which
compares the character strings s and t, and returns negative, zero or
positive if s is lexicographically less than, equal to, or greater than t.
The value is obtained by subtracting the characters at the first
position where s and t disagree.
/* strcmp: return <0 if s<t, 0 if s==t, >0 if s>t */
int strcmp(char *s, char *t)
{
int i;
for (i = 0; s[i] == t[i]; i++)
if (s[i] == '\0')
return 0;
return s[i] - t[i];
}

The pointer version of strcmp:
int strcmp(char *s, char *t)
{
for ( ; *s == *t; s++, t++)
if (*s == '\0')
return 0;
return *s - *t;
}
5/21/2014 Version-1.2 218
Initialization of Pointer Arrays
Consider the problem of writing a function month_name(n), which
returns a pointer to a character string containing the name of the n-th
month. This is an ideal application for an internal static array.
month_name contains a private array of character strings, and returns
a pointer to the proper one when called. This section shows how that
array of names is initialized. The syntax is similar to previous
initializations:

/* month_name: return name of n-th month */

// Function returning pointer

char *month_name(int n)
{
static char *name[] = { "Illegal month", "January", "February",
"March", "April", "May", "June", "July",
"August", "September", "October",
"November", "December" };
return (n < 1 || n > 12) ? name[0] : name[n];
}
5/21/2014 Version-1.2 219
Array of pointers
Although we have phrased this discussion in terms of
integers, by far the most frequent use of arrays of
pointers is to store character strings of diverse lengths,
as in the function month_name. Compare the
declaration and picture for an array of pointers:

char *name[] = { "Illegal month", "Jan", "Feb", "Mar"
};

with those for a two-dimensional array:

char aname[][15] = { "Illegal month", "Jan", "Feb",
"Mar" };
5/21/2014 Version-1.2 220
malloc
5/21/2014 Version-1.2 221
void *malloc(size_t size)

malloc returns a pointer to space(memory) for an
object of size size, or NULL if the request cannot
be satisfied. The space is uninitialized.

Calls to malloc and free may occur in any
order; malloc calls upon the operating
system to obtain more memory as
necessary.

Rather than allocating from a compiled-in
fixed-size array, malloc will request space
from the operating system as needed.
5/21/2014 Version-1.2 222
Rather than allocating from a compiled-in fixed-size
array, malloc will request space from the operating
system as needed.

Since other activities in the program may also request
space without calling this allocator, the space that
malloc manages may not be contiguous.

Thus its free storage is kept as a list of free blocks.
Each block contains a size, a pointer to the next block,
and the space itself.

The blocks are kept in order of increasing storage
address, and the last block (highest address) points to
the first.
5/21/2014 Version-1.2 223
A Storage Allocator




5/21/2014 Version-1.2 224
A Storage Allocator
When a request is made, the free list is scanned until a
big-enough block is found. This algorithm is called
``first fit,'' by contrast with ``best fit,'' which looks for
the smallest block that will satisfy the request.

If the block is exactly the size requested it is unlinked
from the list and returned to the user. If the block is too
big, it is split, and the proper amount is returned to the
user while the residue remains on the free list.

If no big-enough block is found, another large chunk is
obtained by the operating system and linked into the
free list.
5/21/2014 Version-1.2 225
A Storage Allocator
Freeing also causes a search of the free list, to find the proper place to
insert the block being freed. If the block being freed is adjacent to a
free block on either side, it is coalesced with it into a single bigger
block, so storage does not become too fragmented.

Determining the adjacency is easy because the free list is maintained
in order of decreasing address.

typedef long Align; /* for alignment to long boundary */
union header { /* block header */
struct {
union header *ptr; /* next block if on free list */
unsigned size; /* size of this block */
} s;
Align x; /* force alignment of blocks */
};

typedef union header Header;
5/21/2014 Version-1.2 226
A Storage Allocator
The Align field is never used; it
just forces each header to be
aligned on a worst-case
boundary.

In malloc, the requested size in
characters is rounded up to the
proper number of header-sized
units; the block that will be
allocated contains one more
unit, for the header itself, and
this is the value recorded in the
size field of the header.

The pointer returned by malloc
points at the free space, not at
the header itself. The user can
do anything with the space
requested, but if anything is
written outside of the allocated
space the list is likely to be
scrambled.

5/21/2014 Version-1.2 227
/* Program to illustrate malloc */

#include<stdio.h>
#define MAX 1000
unsigned int nmax;
unsigned int *nums;
main()
{
unsigned int ctr, n;
void print_nums(unsigned int);
printf("Enter Max no. you want to input");
if(scanf("%d",&nmax)!=1)
exit(1);
if(nmax <1 || nmax > MAX) {
fprintf(stderr,"Enter nmax properly");
exit(2);
}
5/21/2014 Version-1.2 228
nums= (unsigned int *)malloc(nmax * sizeof (unsigned
int));
ctr=0;
while(ctr<nmax) {
printf("Enter %dth number", ctr);
if(scanf("%d",nums+ctr)!=1)break;
ctr++;
}
n=ctr;
print_nums(n);
free(nums); //Freeing allocated memory
exit(0);
} //closing main
5/21/2014 Version-1.2 229
void print_nums(unsigned int N)
{
unsigned int i ; i=0;
while(i<N)
{
printf("%dth Number is
%d\n",i,*(nums+i));
i++;
}
}//closing function print_nums
5/21/2014 Version-1.2 230
realloc
5/21/2014 Version-1.2 231
realloc
void *realloc(void *p, size_t size)
realloc changes the size of the object pointed to
by p to size. The contents will be unchanged up to
the minimum of the old and new sizes.

If the new size is larger, the new space is
uninitialized. realloc returns a pointer to the new
space, or NULL if the request cannot be satisfied,
in which case *p is unchanged.

realloc(void * p, NULL);

Is as good as calling free() function.
5/21/2014 Version-1.2 232
/* Program to illustrate realloc function */
#include<stdio.h>
int *nums;
main()
{
int next, n=0;
void print_nums(unsigned int );
nums=(int *)malloc(sizeof(int));

while(1){
printf("Enter %dth number\n",n+1);
if(scanf("%d",nums+n)!=1) break;
nums=(int *)realloc(nums,(++n+1)*sizeof *nums);
}

print_nums(n);
free(nums);
exit(0);
}
5/21/2014 Version-1.2 233
void print_nums(unsigned int N)
{
unsigned int i ; i=0;
while(i<N) {
printf("Number is %d\n",
*(nums+i));
i++;
}
}//closing function print_nums

5/21/2014 Version-1.2 234
Passing Arrays to Functions
This relationship comes into play when an array has to
be passed as an argument to a function. The only way
to pass an array to a function is by means of a pointer.

If a function is written which takes an array as an
argument, a function that can handle arrays of different
sizes.

How does the function know the size of the array whose
address it was passed? Remember, the value passed to
a function is a pointer to the first array element. It
could be the first of 10 elements or the first of 10,000.
There are two methods of letting a function know an
array's size.
5/21/2014 Version-1.2 235
It can identify the last array element by
storing a special value there. As the function
processes the array, it looks for that value in
each element.

When the value is found, the end of the
array has been reached.

The other method is more flexible and
straightforward. Pass the function the array
size as an argument. This can be a simple
type int argument.

Thus, the function is passed two arguments:
a pointer to the first array element, and an
integer specifying the number of elements in
the array.
5/21/2014 Version-1.2 236
Using Calloc
5/21/2014 Version-1.2 237
void *calloc(size_t nobj, size_t size)

calloc returns a pointer to space for an
array of nobj objects, each of size size, or
NULL if the request cannot be satisfied.
The space is initialized to zero bytes.

5/21/2014 Version-1.2 238
/* using calloc allocating memory. sorting using selection sort
algorithm
in descending order. Passing pointer to a function */
#include<stdio.h>
void selection(int *,int );
main()
{
int n, i;
int *p ;

printf("enter limit of an array");
scanf("%d",&n);
p=(int *) calloc(n,sizeof(n));
for(i=0;i<n;i++)
scanf("%d",(p+i));
selection(p,n);
}
5/21/2014 Version-1.2 239
void selection (int *p,int n)
{
int i,j,temp;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(*(p+i)<*(p+j)) {
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
}
for(i = 0;i < n;i ++)
printf("\n%d",*(p+i));
}

5/21/2014 Version-1.2 240
Command-line Arguments
In environments that support C, there is a way to pass
command-line arguments or parameters to a program
when it begins executing.

When main is called, it is called with two arguments.
The first (conventionally called argc, for argument
count) is the number of command-line arguments the
program was invoked with; the second (argv, for
argument vector) is a pointer to an array of character
strings that contain the arguments, one per string. We
customarily use multiple levels of pointers to
manipulate these character strings.
5/21/2014 Version-1.2 241
The simplest illustration is the program echo, which
echoes its command-line arguments on a single line,
separated by blanks. That is, the command
echo hello, world
prints the output,
hello, world

By convention, argv[0] is the name by which the
program was invoked, so argc is at least 1. If argc is 1,
there are no command-line arguments after the
program name. In the example above, argc is 3, and
argv[0], argv[1], and argv[2] are "echo", "hello,", and
"world" respectively. The first optional argument is
argv[1] and the last is argv[argc-1]; additionally, the
standard requires that argv[argc] be a null pointer.
5/21/2014 Version-1.2 242
The first version of echo treats argv as an
array of character pointers:

#include <stdio.h> /* echo command-line
arguments; 1st version */ main(int argc,
char *argv[])
{
int i;
for (i = 1; i < argc; i++)
printf("%s%s", argv[i], (i < argc-1) ? " "
: "");
printf("\n");
return 0;
}
5/21/2014 Version-1.2 243
Pointers and double dimensional Arrays
5/21/2014 Version-1.2 244

0 1 2 3 4 5

0
1
2
3
4
5
p
p+1
*(p+4+3)
p pointer to first row
p+i pointer to ith row
*(p+i) pointer to first element in the ith row
*(p+i)+j pointer to jth eleement in the ith row
*(*(p+i)+j) value stored in the cell
5/21/2014 Version-1.2 245
main()
{
int *a[5], *b[5] , *c[5], i , j;
for(i = 0; i < 5;i++)
{
a[i] = (int *) malloc(sizeof(int)*5);
b[i] = (int *) malloc(sizeof(int)*5);
c[i] = (int *) malloc(sizeof(int)*5);
}
puts("Enter elements to mat1\n");
for(i = 0; i < 2;i++)
for(j = 0; j < 2;j++)
scanf("%d",*(a+i)+j);
for(i = 0; i < 2;i++)
for(j = 0; j < 2;j++)
scanf("%d",*(b+i)+j);
5/21/2014 Version-1.2 246
for(i = 0; i < 2;i++)
for(j = 0; j < 2;j++)
*(*(c+i)+j) = *(*(a+i)+j) + *(*(b+i)+j);
for(i = 0; i < 2;i++) {
for(j = 0; j < 2;j++)
printf("%d\t",*(*(c+i)+j));
puts("\n");
}
for(i = 0; i < rows; i++){
free(a[i]);
free(b[i]);
free(c[i]);
}
}
5/21/2014 Version-1.2 247
Program to add matrices using double pointers
main()
{
int **a, **b, **c;
int i, j, rows, cols;
printf("Enter the Number of Rows for the Matrices :
\n");
scanf("%d",&rows);
a = (int **)malloc(rows * sizeof(int *));
b = (int **)malloc(rows * sizeof(int *));
c = (int **)malloc(rows * sizeof(int *));

printf("Enter the Number of Columns for the Matrices
: \n");
scanf("%d",&cols);
5/21/2014 Version-1.2 248
for(i = 0; i < rows ; i++){
*(a+i) = (int *)malloc(cols *
sizeof(int));
*(b+i) = (int *)malloc(cols *
sizeof(int));
*(c+i) = (int *)malloc(cols *
sizeof(int));
}
printf("Enter the Elements for the first
matrix : \n");

for(i = 0; i < rows; i++){
for (j = 0; j < cols; j++){
scanf("%d", (*(a+i)+j));
}
}
5/21/2014 Version-1.2 249
printf("Enter the Elements for the Second matrix : \n");
for(i = 0; i < rows ; i++){
for(j = 0; j < cols ; j++){
scanf("%d",(*(b+i)+j));
}
}
printf("\n");
for(i = 0; i < rows; i++){
for(j = 0 ; j < cols; j++){
c[i][j] = a[i][j] + b[i][j];
printf("%d\t", c[i][j]);
} printf("\n");
}
5/21/2014 Version-1.2 250
for(i = 0; i < rows; i++){
free(a[i]);
free(b[i]);
free(c[i]);
}
free(a);
free(b);
free(c);
}
5/21/2014 Version-1.2 251
/* Matrix addition using double pointers and functions */
void _matrix_get_alloc(int ***p,int rows,int cols);
void _matrix_enter_elements(int **p,int rows,int cols);
void _matrix_addition_result(int **p,int **q,int **r, int
rows,int cols);
void _matrix_display(int **r, int rows,int cols);

main()
{
int **a, **b, **c;
int i, j, rows, cols;

printf("Enter the Number of rows : ");
scanf("%d",&rows);
printf("Enter the Number of Columns : ");
scanf("%d", &cols);
_matrix_get_alloc(&a, rows, cols); //address of pointer
_matrix_get_alloc(&b, rows, cols);
_matrix_get_alloc(&c, rows, cols);
5/21/2014 Version-1.2 252
_matrix_enter_elements(a, rows, cols);
_matrix_enter_elements(b, rows, cols);
_matrix_addition_result(a, b, c, rows, cols);
_matrix_display(c, rows, cols);
}

void _matrix_get_alloc(int ***p, int rows, int cols){
int i;
*p = (int **)malloc(rows * sizeof(int *));
for(i = 0; i < rows ; i++){
*(*p+i) = (int *)malloc(cols * sizeof(int));
}
}
5/21/2014 Version-1.2 253

void _matrix_enter_elements(int **p,int rows,int cols){
int i ,j;
printf("Enter the Elements for the matrix %c : \n", p);
for(i = 0; i < rows; i++){
for (j = 0; j < cols; j++){
scanf("%d",(*(p+i)+j));
}
}
}

void _matrix_addition_result(int **p,int **q,int **r, int rows,int
cols){
int i, j;
printf("\n");
for(i = 0; i < rows; i++)
for(j = 0 ; j < cols; j++)
r[i][j] = p[i][j] + q[i][j];
}
5/21/2014 Version-1.2 254
void _matrix_display(int **r, int rows,int cols)
{
int i, j;
printf("\n");
for(i = 0; i < rows; i++){
for(j = 0 ; j < cols; j++)
printf("%d\t", r[i][j]);
printf("\n");
}
}

5/21/2014 Version-1.2 255
Pointer constant
const int *p;
int const *p;
defines p as a pointer to a constant
integer

Constant Pointer
int * const p;
defines a constant pointer to an integer

5/21/2014 Version-1.2 256
Pointer constant
main()
{
const char *p;
p = (char *) malloc(100);
puts("Enetr a string");
gets(p);

strcat(p,"This is appended"); //This is wrong
modifying pointer constant
puts(p);
free(p);
}
5/21/2014 Version-1.2 257
Constant Pointer
main()
{
char * const p = (char *) malloc(100);
puts("Enetr a string");
gets(p);
free(p);

p = (char *) malloc(100); // This is error since p is
constant
strcpy(p,"This is copied");
puts(p);
free(p);
}
5/21/2014 Version-1.2 258
Pointers to functions
A Pointer to a function can be defined to
hold the starting address of a function, and
the same can be used to invoke a function,.

It is also possible to pass address of different
functions at different times thus making the
function more flexible and abstract

Declaring pointer to a function
Syntax:
returntype (* ptrtofn)(arguments if any);
5/21/2014 Version-1.2 259
Once a pointer a function is defined, it matches with the
rturn type and the argument list stated in the definition
of the pointer to a function.
For example
int (*anyfn)(int,int)

Now the variable anyfn can point to any function that takes
two integer arguments and returns a single integer
value.
For example

int min(int a,int b)
int max(int i,int j)
int add(int x,int y)
5/21/2014 Version-1.2 260
Address of a function

The address of a function can be obtained by just
specifying the name of the function without the trailing
parenthesis.

anyfn=min;

Invoking a function using pointers

Syntax
(*ptrtofn)(arguments if any);
(ptrtofn)(arguments if any);

5/21/2014 Version-1.2 261
Example:
long fact(long int num)
{
if(num==0)
return 1;
else
return num * fact(num-1);
}
main()
{
long int n, f1;
long int(*ptrfact)(long int);
ptrfact=fact;
printf("Enter the number whose factorial has to be found\n");
scanf("%ld",&n);
f1=(*ptrfact)(n);
printf("The factorial of %ld is %ld\n",n,f1);

printf("The factorial of %ld is %ld\n",n+1,ptrfact(n+1));
}
5/21/2014 Version-1.2 262
Pointers to functions
//Sending function as a parameter to function
main()
{
int m,n,high,low;
int (*ptrf)(int,int);
printf("Enter 2 integers\n");
scanf("%d %d",&m,&n);
high=select(large,m,n);
ptrf=small;
low=select(ptrf,m,n);
printf("large=%d\n",high);
printf("small=%d\n",low);
fflush(stdin);
getchar();
}
5/21/2014 Version-1.2 263
Pointers to functions
int small (int a, int b)
{
return a<b?a:b;
}

int large (int a, int b)
{
return a>b?a:b;
}

int select(int (*fn)(int,int),int x,int y)
{
int value=fn(x,y);
return value;
}
5/21/2014 Version-1.2 264
Complicated Declarations
C is sometimes castigated for the syntax of its
declarations, particularly ones that involve pointers to
functions.

The syntax is an attempt to make the declaration and
the use agree; it works well for simple cases, but it can
be confusing for the harder ones, because declarations
cannot be read left to right, and because parentheses
are over-used.

The difference between

int *f(); /* f: function returning pointer to int*/ and
int (*pf)(); /* pf: pointer to function returning int */
5/21/2014 Version-1.2 265
char **argv //argv; pointer to char

int (*daytab)[13] // daytab; pointer to array[13] of int

int *daytab[13] // daytab; array[13] of pointer to int

void *comp() //comp: function returning pointer to void

void (*comp)() // comp: pointer to function returning

void char (*(*x())[])() // x: function returning pointer to
array[] of pointer to function returning char

char (*(*x[3])())[5] //x: array[3] of pointer to function
returning pointer to array[5] of char
5/21/2014 Version-1.2 266
Miscellaneous programs
5/21/2014 Version-1.2 267
bubble_1.c
int arr[10] = { 3,6,1,2,3,8,4,1,7,2};

void bubble(int a[], int N);
int main(void)
{
int i;
putchar('\n');
for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
bubble(arr,10); putchar('\n');

for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
return 0;
}
5/21/2014 Version-1.2 268
void bubble(int a[], int N)
{
int i, j, t;
for (i = N-1; i >= 0; i--) {
for (j = 1; j <= i; j++) {
if (a[j-1] > a[j]) {
t = a[j-1];
a[j-1] = a[j];
a[j] = t;
}
}
}
}

Here our function is designed to sort an array of integers.
What we want to do now is see if we can convert this
code so we can use any data type, i.e. not be restricted
to integers.
5/21/2014 Version-1.2 269
bubble_2.c
int arr[10] = { 3,6,1,2,3,8,4,1,7,2};

void bubble(int *p, int N);
int compare(int *m, int *n);

int main(void)
{
int i;
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
bubble(arr,10);
putchar('\n');
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
5/21/2014 Version-1.2 270
void bubble(int *p, int N)
{
int i, j, t;
for (i = N-1; i >= 0; i--)
for (j = 1; j <= i; j++)
if (compare(&p[j-1], &p[j])) {
t = p[j-1];
p[j-1] = p[j];
p[j] = t;
}
}
int compare(int *m, int *n) { return (*m > *n);}

If our goal is to make our sort routine data type
independent, one way of doing this is to use pointers to
type void to point to the data instead of using the
integer data type.
5/21/2014 Version-1.2 271
bubble_2.c
int arr[10] = { 3,6,1,2,3,8,4,1,7,2};
void bubble(int *p, int N);
int compare(void *m, void *n);

int main(void)
{
int i;
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
bubble(arr,10);
putchar('\n');

for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
5/21/2014 Version-1.2 272
void bubble(int *p, int N)
{
int i, j, t;
for (i = N-1; i >= 0; i--)
for (j = 1; j <= i; j++)
if (compare((void *)&p[j-1], (void *)&p[j])) {
t = p[j-1];
p[j-1] = p[j];
p[j] = t;
}
}
int compare(void *m, void *n)
{
int *m1, *n1;
m1 = (int *)m;
n1 = (int *)n;
return (*m1 > *n1);
}
5/21/2014 Version-1.2 273
since what is being passed to bubble() is still a pointer to an
array of integers, we had to cast these pointers to void
pointers when we passed them as parameters in our call to
compare().

We now address the problem of what we pass to bubble().
We want to make the first parameter of that function a void
pointer also.

But, that means that within bubble() we need to do
something about the variable t, which is currently an integer.
Also, where we use t = p[j-1]; the type of p[j-1] needs to
be known in order to know how many bytes to copy to the
variable t (or whatever we replace t with).

#include <stdio.h>
#include <string.h>

long arr[10] = { 3,6,1,2,3,8,4,1,7,2};

void bubble(void *p, size_t width, int N);
int compare(void *m, void *n)
5/21/2014 Version-1.2 274
int main(void)
{
int i;
for (i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
bubble(arr, sizeof(long), 10);
for (i = 0; i < 10; i++) {
printf("%ld ", arr[i]);
}
return 0;
}
5/21/2014 Version-1.2 275
void bubble(void *p, size_t width, int N)
{
int i, j;
unsigned char buf[4];
unsigned char *bp = p;

for (i = N-1; i >= 0; i--)
for (j = 1; j <= i; j++)
if (compare((void *)(bp + width*(j-1)), (void *)(bp +
j*width))) {
/* t = p[j-1]; */
memcpy(buf, bp + width*(j-1), width);
/* p[j-1] = p[j]; */
memcpy(bp + width*(j-1), bp + j*width , width);
/* p[j] = t; */
memcpy(bp + j*width, buf, width);
}
}
5/21/2014 Version-1.2 276
int compare(void *m, void *n)
{
long *m1, *n1;
m1 = (long *)m;
n1 = (long *)n;
return (*m1 > *n1);
}
5/21/2014 Version-1.2 277
to sort strings instead of long integers, Of course we
have to change the comparison function since the means
by which strings are compared is different from that by
which long integers are compared.

In bubble() compare has to be rewritten as ,
#define MAX_BUF 256
char arr2[5][20] = { "Mickey Mouse",

"Donald Duck",
"Minnie Mouse",
"Goofy",
"Ted Jensen" };

void bubble(void *p, int width, int N);
int compare(void *m, void *n);
5/21/2014 Version-1.2 278
int main(void)
{
int i;
putchar('\n');

for (i = 0; i < 5; i++) {
printf("%s\n", arr2[i]);
}
bubble(arr2, 20, 5);
putchar('\n\n');

for (i = 0; i < 5; i++) {
printf("%s\n", arr2[i]);
}

return 0;
}
5/21/2014 Version-1.2 279
void bubble(void *p, int width, int N)
{
int i, j, k;
unsigned char buf[MAX_BUF];
unsigned char *bp = p;

for (i = N-1; i >= 0; i--)
for (j = 1; j <= i; j++)
k = compare((void *)(bp + width*(j-1)), (void *)(bp +
j*width));
if (k > 0) {
memcpy(buf, bp + width*(j-1), width);
memcpy(bp + width*(j-1), bp + j*width , width);
memcpy(bp + j*width, buf, width);
}
}

int compare(void *m, void *n)
{
char *m1 = m;
char *n1 = n;
return (strcmp(m1,n1));
}
5/21/2014 Version-1.2 280
Structures
5/21/2014 Version-1.2 281
Objectives
Defining and declaring structure
Accessing Structure Members
Netsted structure
Array of structures
Structures and pointers

5/21/2014 Version-1.2 282
Defining and declaring structure
Many programming tasks are simplified by the C data
constructs called structures. A structure is a data storage
method designed by the programmer.

A structure is a collection of one or more variables grouped
under a single name for easy manipulation. The variables in a
structure, unlike those in an array, can be of different
variable types

struct coord { int x; int y;};

The struct keyword, which identifies the beginning of a
structure definition, must be followed immediately by the
structure name, or tag .
5/21/2014 Version-1.2 283
Defining and declaring structure
The following statement declare two
instances of type coord:

struct coord {
int x;
int y;
};
struct coord first, second;

5/21/2014 Version-1.2 284
Initializing Structures
Like other C variable types, structures can be initialized
when they're declared. This procedure is similar to that
for initializing arrays. The structure declaration is
followed by an equal sign and a list of initialization
values separated by commas and enclosed in braces. For
example, look at the following statements:

struct sale {
char customer[20];
char item[20];
float amount;
} mysale = { "Acme Industries",Hard Disk,3000.00 };
5/21/2014 Version-1.2 285
Initializing Structures
When these statements are executed, they perform the
following actions:

1. Define a structure type named sale .

2. Declare an instance of structure type sale named mysale .

3. Initialize the structure member mysale.customer to the string "Acme
Industries"

4. Initialize the structure member mysale.item to the string Hard Disk.

5. Initialize the structure member mysale.amount to the value 3000.00 .
5/21/2014 Version-1.2 286
Accessing Structure Members
Structure members are accessed using the structure
member operator ., also called the dot operator,
between the structure name and the member name.
For example,
first.x = 50;first.y = 100;
printf ("%d,%d", second.x, second.y);

to copy information between structures of the same
type with a simple equation statement.

first = second; is equivalent to this statement:
first.x = second.x; first.y = second.y;
5/21/2014 Version-1.2 287
Nested structure
We can nest one or more structures, as shown below.
struct rectangle {
struct coord {
int x;
int y;
}topleft;

struct coord {
int x;
int y;
} bottomrt;
} MyRectangle;
5/21/2014 Version-1.2 288
Nested structure
In this example Rectangle structure has two
data members, which are the object of struct
coord, MyRectangle is an object of Rectangle
structure.

MyRectangle object can be initialized as:

MyRectangle.topleft.x = 10;
MyRectangle.topleft.y = 20;
MyRectangle.bottomrt.x = 40;
MyRectangle.bottomrt.x = 50;
5/21/2014 Version-1.2 289
Structure as a structures
member
struct rectangle {
struct coord topleft;
struct coord bottomrt;
} mybox;

Thus, the above expression refers to the x member of the
topleft member of the type rectangle structure named mybox.
To define a rectangle with coordinates (0,10), (100,200), is as
follows.

mybox.topleft.x = 0;
mybox.topleft.y = 10;
mybox.bottomrt.x = 100;
mybox.bottomrt.y = 200;
5/21/2014 Version-1.2 290
Initializing structure members
For a structure that contains structures as members, list the
initialization values in order. They are placed in the structure
members in the order in which the members are listed in the
structure definition. Here's an example that expands on the
previous one:

struct customer {
char firm[20];
char contact[25];
};
struct sale {
struct customer buyer;
char item[20];
float amount;
} mysale = { { "Acme Industries", "Sachin"}, Hard
Disk",3000.00 };
5/21/2014 Version-1.2 291
Initializing structure members
These statements perform the following initializations:

1. The structure member mysale.buyer.firm is initialized to the
string "Acme Industries" .

2. The structure member mysale.buyer.contact is initialized to
the string Sachin" .

3. The structure member mysale.item is initialized to the string
Hard Disk".

4. The structure member mysale.amount is initialized to the
amount 3000.00.
5/21/2014 Version-1.2 292
Structures and arrays
A structure can be defined which contains one or more arrays
as members. The array can be of any C data type (int, char,
and so on). For example, the statements

struct data{
int x[4];
char y[10];
};

Then structure named record of type data can be declared as
follows:
struct data record; Individual elements of arrays that are
structure members, can be accessed using a combination of
the member operator and array subscripts:
record.x[2] = 100;
record.y[1] = `x';
5/21/2014 Version-1.2 293
Arrays of Structures
Usually a program needs to work with more than one instance
of the data. For example, consider a program to maintain a list
of phone numbers, a structure can be defined to hold each
person's name and number:

struct entry{
char fname[10];
char lname[12];
char phone[8];
};

A phone list must hold many entries, however, so a single
instance of the entry structure isn't of much use. What is in
need is an array of structures of type entry. After the structure
has been defined, an array can be declared as follows:

struct entry list[1000];
5/21/2014 Version-1.2 294
Structures and arrays
To assign the data in one array element to another array
element, it could be written as;
list[1] = list[5];

This statement assigns to each member of the structure
list[1] the values contained in the corresponding
members of list[5]. Data can be moved between
individual structure members.

The statement

strcpy(list[1].phone, list[5].phone);
5/21/2014 Version-1.2 295
Structures and arrays
Copies the string in list[5].phone to list[1].phone. (The
strcpy() library function copies one string to another
string.) Data can also be moved between individual
elements of the structure member arrays:

list[5].phone[1] = list[2].phone[3];

This statement moves the second character of list[5]'s
phone number to the fourth position in list[2]'s phone
number. (Don't forget that subscripts start at offset 0.)
5/21/2014 Version-1.2 296
Arrays of structures.
Let us see how to initialize arrays of structures. The
initialization data that is input is applied, in order, to the
structures in the array. For example, to declare an array of
structures of type sale and initialize the first two array
elements (that is, the first two structures), it could be written
as

struct customer {
char firm[20];
char contact[25];
};
struct sale {
struct customer buyer;
char item[20];
float amount;
};

5/21/2014 Version-1.2 297
Arrays of structures.
struct sale Rec[100] = {
{{ "Acme Industries", Sachin"}, Hard Disk",3000.00 }
{{ "Wilson & Co.", "Anil"}, "computer", 29000.00 }
};
struct elec
{
char name[20];
char add1[20];
char add2[20];
float previous, float current, float unit;
float due, float total;
}rec[10];

main()
{
int i;
int num;
printf("enter number of records\n");
scanf("%d",&num);
5/21/2014 Version-1.2 298
Arrays of structures.
for(i=0;i<num;i++)
{
printf("enter name\n");
scanf("%s",rec[i].name);
printf("enter address\n");
scanf("%s",rec[i].add1);
printf("enter address2\n");
scanf("%s",rec[i].add2);
printf("enter previous reading\n");
scanf("%f",&rec[i].previous);
printf("enter current reading\n");
scanf("%f",&rec[i].current);
printf("enter amount due\n");
scanf("%f",&rec[i].due);
rec[i].unit=rec[i].current-rec[i].previous;
5/21/2014 Version-1.2 299
Arrays of structures.
if(rec[i].unit<100)
rec[i].total=rec[i].unit*2.00+rec[i].due;

if(rec[i].unit>100 && rec[i].unit<150)

rec[i].total=rec[i].unit*3.00+rec[i].due;

printf("custmers name=%s\n",rec[i].name);
printf("address=%s\n",rec[i].add1);
printf("address=%s\n",rec[i].add2);
printf("previous reading=%f\n",rec[i].previous);
printf("current reading=%f\n",rec[i].current);
printf("total amount due=%f\n",rec[i].total);
}

}

5/21/2014 Version-1.2 300
Arrays of structures.
struct stud
{
char name[25];
char rno[10];
int marks[5];
int total;
float avg;
}rec[10];
main()
{
int i,j;
for(i=0;i<2;i++) {

5/21/2014 Version-1.2 301
Arrays of structures.
printf("enter student's name\n");
scanf("%s",rec[i].name);
printf("enter roll number\n");
scanf("%s",rec[i].rno);
printf("enter marks obtained in 5 subjects\n");
for(j=0;j<5;j++)
scanf("%d",&rec[i].marks[j]);
rec[i].total=0;
for(j=0;j<5;j++)
rec[i].total=rec[i].total+rec[i].marks[j];
rec[i].avg=(rec[i].total)/5;
}
for(i=0;i<2;i++) {
printf("name=%s\n",rec[i].name);
printf("roll number=%s\n",rec[i].rno);
printf("total marks obtained in 5
subjects=%d\n",rec[i].total);
printf("average marks=%f\n",rec[i].avg);
}
}
5/21/2014 Version-1.2 302
Arrays of structures.
struct date{
int dd;
int mm;
int yy;
};

struct emp{
char name[10];
struct date dob;
float bsal;
};
5/21/2014 Version-1.2 303
main()
{
int i ;
struct emp *rec;
rec=(struct emp *) malloc(3*sizeof(struct emp ));
for(i = 0; i < 3; i++){
printf("Enter name, date of birth, bsal");

scanf("%s%d%d%d%f",rec[i].name,&rec[i].dob.dd,&rec[i].do
b.mm,&rec[i].dob.yy,&rec[i].bsal);
}
for(i = 0; i < 3; i++)

printf("%s\t%d\t%d\t%d\t%f\n",rec[i].name,rec[i].dob.dd,
rec[i].dob.mm,rec[i].dob.yy,rec[i].bsal);
}

5/21/2014 Version-1.2 304
Dos and Donts
DON'T forget the structure instance name and member
operator (.) when using a structure's members.

DON'T confuse a structure's tag with its instances!
The tag is used to declare the structure's template, or
format. The instance is a variable declared using the tag.

DON'T forget the struct keyword when declaring an
instance from a previously defined structure.

DO declare structure instances with the same scope
rules as other variables.
5/21/2014 Version-1.2 305
Pointers as Structure Members
Pointer members are declared in the same manner as
pointers that aren't members of structures--that is, by using
the indirection operator (*).

struct data {
int *value;
int *rate;
} first;

These statements define and declare a structure whose two
members are both pointers to type int.
Initializing pointer variables
first.value = &cost;
first.rate = &interest;
5/21/2014 Version-1.2 306
Pointers as Structure Members
Same thing can be done with pointers to type char that are
structure members:

struct msg {
char *p1;
char *p2;
} myptrs;

myptrs.p1 = "good morning ";
myptrs.p2 = "By us";

What's the difference between using an array of type char as a
structure member and using a pointer to type char?

It is If a structure defined contains an array of type char,
every instance of that structure type contains storage space
for an array of the specified size. Furthermore, the specified
size is limited; a larger string can't be stored in the structure.
5/21/2014 Version-1.2 307
struct emp{
char name[10];
int *age;
};

main()
{
int i ;
struct emp *rec;
rec=(struct emp *) malloc(3*sizeof(struct emp ));
for(i = 0; i < 3; i++)
(rec+i)->age=(int *) malloc(sizeof(int));
for(i = 0; i < 3; i++)
scanf("%s %d",(rec+i) ->name,&(rec+i) -
>age);
for(i = 0; i < 3; i++)
printf("%s\t%d\n",(rec+i)->name,(rec+i)-
>age);
}
5/21/2014 Version-1.2 308
Sending structure to function

5/21/2014 Version-1.2 309
Unions
Unions are similar to structures.

A union is declared and used in the same
ways that a structure is.

A union differs from a structure in that only
one of its members can be used at a time.

The reason for this is simple. All the
members of a union occupy the same area of
memory.
5/21/2014 Version-1.2 310
Defining, Declaring, and Initializing Unions
Unions are defined and declared in the same fashion as
structures. The only difference in the declarations is that
the keyword union is used instead of struct. To define a
simple union of a char variable and an integer variable,

union shared {
char c;
int i;
};

This union, shared, can be used to create instances of a
union that can hold either a character value c or an
integer value i. This is an OR condition. Unlike a
structure that would hold both values, the union can
hold only one value at a time.
5/21/2014 Version-1.2 311
Accessing Union Members
Individual union members can be used; in the same way the
structure members are used--by using the member operator
(.). However, there is an important difference in accessing
union members.

Only one union member should be accessed at a time.
Because a union stores its members on top of each other, it's
important to access only one member at a time.

/* Declare a union and instance together */
union generic_type_tag {
char c;
int i;
float f;
double d;
} generic;
5/21/2014 Version-1.2 312
Dos and Donts
DON'T try to initialize more than the first union
member.

DO remember which union member is being used. If
a member of one type is stored and then a different type
is tried to use, unpredictable results are got.

DON'T forget that the size of a union is equal to its
largest member.

DO note that unions are an advanced C topic.
5/21/2014 Version-1.2 313
typedef and Structures
A typedef keyword can be used to create a synonym for
a structure or union type. For example, the following
statements define coord as a synonym for the indicated
structure:

typedef struct {
int x;
int y;
} coord;

Then instances of this structure can be declared using the
coord identifier:

coord topleft, bottomright;
5/21/2014 Version-1.2 314
File handling in C

5/21/2014 Version-1.2 315
Objectives

5/21/2014 Version-1.2 316
Standard I/O Library
When we open a stream, the standard I/O function fopen
returns to a pointer to a FILE object. This object is normally
a structure that contains all the information required by the
standard I/O library.

To reference the stream we pass its FILE pointer as an
argument to each standard I/O function.

Opening a stream
In case of success it returns pointer to FILE , for failure it
returns NULL.

The first argument is relative / absolute filename.
#include <stdio.h>
FILE *fopen(const char * pathname,const char * type);
5/21/2014 Version-1.2 317
mode Meaning
r Opens the file for reading. If the file doesn't exist, fopen() returns NULL.
w Opens the file for writing. If a file of the specified name doesn't exist, it is created.
If a file of the specified name does exist, it is deleted without warning, and a new,
empty file is created.
a Opens the file for appending. If a file of the specified name doesn't exist, it is
created. If the file does exist, new data is appended to the end of the file.
r+ Opens the file for reading and writing. If a file of the specified name doesn't exist,
it is created. If the file does exist, new data is added to the beginning of the file,
overwriting existing data.
w+ Opens the file for reading and writing. If a file of the specified name doesn't exist,
it is created. If the file does exist, it is overwritten.
a+ Opens a file for reading and appending. If a file of the specified name doesn't exist,
it is created. If the file does exist, new data is appended to the end of the file.

5/21/2014 Version-1.2 318
Closing a file
An open stream is called by closing fclose.

Any buffered output data is flushed before the file is
closed..

Any input data that may be buffered is discarded.

When process terminates normally , either by calling the
exit function directly, or by returning from main function,
all standard I/O streams with un return buffered data
are flushed, and all open standard I/O streams are
closed.
#include<stdio.h>
Int fclose(FILE * fp)
returns : 0 of OK, EOF on error;

5/21/2014 Version-1.2 319
Reading and writing a stream
Once we open a stream we can choose among 3 different
types of unformatted I/O.

1. Character at-a-time I/O: We can read or write one
character at a time, with the standard I/O functions handling
all the buffering.

Line-at-a-time I/O. We can read and write a line at a time,
we use fgets and fputs. Each line is terminated with a new
line character, and we have to specify the maximum line
length that we can handle when we call fgets.

Direct I/O. This type of I/O is supported by the fread and
fwrite functions. For each I/O operation we read or write
some number of objects, where each object is of a specified
size.
#include<stdio.h>
Int getc(FILE *fp);
Int fgetc(FILE *fp); returns next character if OK,
EOF on end of file or error
5/21/2014 Version-1.2 320
Program to read from file and display contents on the screen
main(int argc, char *argv[])
{
FILE *fp;
char ch;
if(argc!= 2){
printf("usage: a.out <file name>\n");
exit(1);
}
if((fp=fopen(argv[1],"r")) == NULL){
printf("Can't open a file");
exit(2);
}
do{
ch = getc(fp);
putchar(ch);
}while(ch!=EOF); //EOF is ctrl D
fclose(fp);
}
5/21/2014 Version-1.2 321
Key to disk program
main(int argc, char *argv[])
{
FILE *fp;
char ch;
if(argc!= 2){
printf("usage: a.out <file name>\n");
exit(1);
}
if((fp=fopen(argv[1],"w")) == NULL){
printf("Can't open a file");
exit(2);
}
do{
putc(ch=getchar(),fp);
}while(ch!=EOF); //EOF is ctrl D
fclose(fp);
}
5/21/2014 Version-1.2 322
Line Input and Output
The standard library provides an input and output routine
fgets.

char *fgets(char *line, int maxline, FILE *fp)

fgets reads the next input line (including the newline) from
file fp into the character array line; at most maxline-1
characters will be read. The resulting line is terminated with
'\0'.

For output, the function fputs writes a string (which need not
contain a newline) to a file:

int fputs(char *line, FILE *fp)

It returns EOF if an error occurs, and non-negative otherwise.
5/21/2014 Version-1.2 323
rewind( )
The rewind() function resets the file
position indicator to the beginning of
the file specified as its argument.

That is, it "rewinds" the file. Its
prototype is

void rewind(FILE *fp);

where fp is a valid file pointer.
5/21/2014 Version-1.2 324
Program to illustrate usage of fgets and rewind functions
main()
{
char str[80];
FILE *fp;
if((fp = fopen("Test","w+")) == NULL){
printf("Can't open a file\n");
exit(1);
}
do{
printf("Enter a string, <CR> to quit >");
gets(str);
strcat(str,"\n"); //add newline at the end of string
fputs(str,fp);
} while(*str!='\n');

rewind(fp); //Bring file pointer to the begining

while(!feof(fp)){ //Check for not end of file
fgets(str, 79,fp); // Read from file
printf(str);
}
}
5/21/2014 Version-1.2 325
Program to illustrate usage of fputs functions
main()
{
char str[80];
FILE *fp;
if((fp = fopen("Test","w")) == NULL){ //open a file
with Write mode
printf("Can't open a file\n");
exit(1);
}
do{
printf("Enter a string, <CR> to quit >");
gets(str);
strcat(str,"\n"); //add a new line
fputs(str,fp);
} while(*str!='\n');
}
5/21/2014 Version-1.2 326
feof() function
The function feof(FILE *) is analogous
to ferror; it returns non-zero if end of
file has occurred on the specified file.

int feof(FILE *fp)

We have generally not worried about
exit status in our small illustrative
programs, but any serious program
should take care to return sensible,
useful status values.
5/21/2014 Version-1.2 327
ferror( )
The ferror() function determines
whether a file operation has produced
an error. The ferror() function has this
prototype:

int ferror(FILE *fp);

where fp is a valid file pointer. It
returns true if an error has occurred
during the last file operation;
otherwise, it returns false. Because
each file operation sets the error
condition, ferror() should be called
immediately after each file operation;
otherwise, an error may be lost.
5/21/2014 Version-1.2 328
The program substitutes spaces for tabs
in a text file and supplies error checking.
#define TAB_SIZE 8
#define IN 0
#define OUT 1
void err(int e);
main(int argc, char *argv[])
{
FILE *in, *out;
int tab, i;
char ch;
if(argc!=3) {
printf("usage: detab <in> <out>\n");
exit(1);
}
if((in = fopen(argv[1], "rb"))==NULL) {
printf("Cannot open %s.\n", argv[1]);
exit(1);
}
5/21/2014 Version-1.2 329
if((out = fopen(argv[2], "wb"))==NULL) {
printf("Cannot open %s.\n", argv[1]);
exit(1);
}
tab = 0;
do {
ch = getc(in);
if(ferror(in))
err(IN); /* if tab found, output appropriate number of spaces */
if(ch=='\t') {
for(i=tab; i<8; i++) {
putc(' ', out);
if(ferror(out)) err(OUT);
}
tab = 0;
}
else {
putc(ch, out);
if(ferror(out)) err(OUT);
5/21/2014 Version-1.2 330
tab++;
if(tab==TAB_SIZE) tab = 0;
if(ch=='\n' || ch=='\r') tab = 0;
}
while(!feof(in));
fclose(in);
fclose(out);
return 0;
}

void err(int e)
{
if(e==IN) printf("Error on input.\n");
else printf("Error on output.\n");
exit(1);
}
5/21/2014 Version-1.2 331
Erasing Files
The remove() function erases the
specified file. Its prototype is

int remove(const char *filename);

It returns zero if successful; otherwise,
it returns a nonzero value.
5/21/2014 Version-1.2 332
main(int argc, char *argv[])
{
char str[80];
if(argc!=2) {
printf("usage: xerase <filename>\n");
exit(1); }
printf("Erase %s? (Y/N): ", argv[1]);
gets(str);
if(toupper(*str)=='Y')
if(remove(argv[1])) {
printf("Cannot erase file.\n");
exit(1);
}
return 0;
}
5/21/2014 Version-1.2 333
fread( ) and fwrite( )
These functions allow the reading and writing of blocks of any type
of data.

Syntax :

size_t fread(void *buffer, size_t num_bytes, size_t count, FILE *fp);

size_t fwrite(const void *buffer, size_t num_bytes, size_t count, FILE
*fp);

For fread() , buffer is a pointer to a region of memory that will
receive the data from the file.

For fwrite() , buffer is a pointer to the information that will be
written to the file.

The value of count determines how many items are read or written,
with each item being num_bytes in length. Finally, fp is a file pointer
to a previously opened stream.
5/21/2014 Version-1.2 334
The fread() function returns the number of items read. This value
may be less than count if the end of the file is reached or an error
occurs.

The fwrite() function returns the number of items written. This value
will equal count unless an error occurs.

One of the most useful applications of fread() and fwrite() involves
reading and writing user-defined data types, especially structures.

For example, given this structure:

struct struct_type {
float balance;
char name[80];
} cust;
the following statement writes the contents of cust to the file pointed
to by fp.
fwrite(&cust, sizeof(struct struct_type), 1, fp);
5/21/2014 Version-1.2 335
fseek( )
Fseek() is mainly used in random-
access I/O
Syntax :
int fseek(FILE *fp, size_t offset, int origin);

Here, fp is a file pointer returned by a
call to fopen(), offset is the number of
bytes from origin that will become the
new current position, and origin is one
of the following macros:

Beginning of file : SEEK_SET
Current position : SEEK_CUR
End of file : SEEK_END
5/21/2014 Version-1.2 336
int main(int argc, char *argv[])
{
FILE *fp;
if(argc!=3) {
printf("Usage: SEEK filename byte\n");
exit(1);
}
if((fp = fopen(argv[1], "rb"))==NULL) {
printf("Cannot open file.\n");
exit(2);
}
if(fseek(fp, atol(argv[2]), SEEK_SET)) {
printf("Seek error.\n");
exit(1);
}
printf("Byte at %ld is %c.\n", atol(argv[2]), getc(fp));
fclose(fp);
return 0;
}
5/21/2014 Version-1.2 337
Ftell()
ftell() is used to determine the current
location of a file.

ftell(FILE *fp);

It returns the location of the current
position of the file associated with fp.
If a failure occurs, it returns 1.
5/21/2014 Version-1.2 338
fprintf( ) and fscanf( )
In addition to the basic I/O functions C
includes fprintf() and fscanf() .

These functions behave exactly like
printf() and scanf() except that they
operate with files.

int fprintf(FILE *fp, const char
*control_string,. . .);
int fscanf(FILE *fp, const char
*control_string,. . .);

5/21/2014 Version-1.2 339
/* Writing to file using fprintf */

main()
{
FILE *fp;
char name[30];
int d,m,y;
fp=fopen("stud.dat","w+");
if(fp==NULL)
perror("can't open the file\n");
scanf("%s",name);
scanf("%d%d%d",&d,&m,&y);
if(feof(fp)) {
printf("the file contains no data\n");
exit(0);
}
fprintf(fp,"%s %d %d %d",name,d,m,y);
printf("name is: %s\n",name);
printf("DOB is :%d//%d//%d\n",d,m,y);

fclose(fp);
}
5/21/2014 Version-1.2 340
/* Reading from file using fscanf */
main()
{
FILE *fp;
char name[30];
int d,m,y;
fp=fopen("stud.dat","r+");
if(fp==NULL)
perror("can't open the file\n");
if(feof(fp)) { //Check for end of file
printf("the file contains no data\n");
exit(0);
}
while(!feof(fp)) {
fscanf(fp,"%s %d %d %d",name,&d,&m,&y); // Reading from file
printf("name is: %s\n",name);
printf("DOB is :%d/%d/%d\n",d,m,y);
}

fclose(fp);
puts("OK BOSS I'AM EXITING\n");
}
5/21/2014 Version-1.2 341

5/21/2014 Version-1.2 342

5/21/2014 Version-1.2 343

5/21/2014 Version-1.2 344
C Streams
Before beginning our discussion of the
C file systems, it is necessary to know
the difference between the terms
streams and files.
Streams : The C file system is
designed to work with a wide variety of
devices, including terminals, disk
drives. Even though each device is
very different, the file system
transforms each into a logical device
called a stream. Thre are two types of
streams.
Text stream
Binary streams
Text stream: it is sequence of characters.
Standard C allows a text stream to be
organized into lines terminated by a new
line character.
In a text stream certain character
translations may occur as required by the
host environment.
5/21/2014 Version-1.2 345
Binary stream
A file is disassociated from a specific
stream with a close operation.
Each stream that is associated with a file
as a file control structure of type FILE.
The File pointer: is a common thread that
unites the C I/O system.
A file pointer is a pointer to a structure of
type FILE. It points to information that
defines various thing about the file
including it s name, status and current
position of the file.

5/21/2014 Version-1.2 346
Characters and Strings
5/21/2014 Version-1.2 347
Objectives
Array of characters

Difference between characters and
strings

Strings and pointers

Dynamic memory allocation
functions and strings

String handling functions

String to number conversion

Character test functions
5/21/2014 Version-1.2 348
The character data type
C uses the char data type to hold characters.

A character is a single letter, numeral, punctuation mark, or other
such symbol.

There is no direct way to store characters.

However, a numeric code exists for each character. This is called the
ASCII code or the ASCII character set. (ASCII stands for American
Standard Code for Information Interchange.)

The code assigns values between 0 and 255 for upper and lowercase
letters, numeric digits, punctuation marks, and other symbols.

E.g. When a character is stored the a in a type char variable,
actually the value 97 is stored. 97 is the ASCII code for the letter a.
5/21/2014 Version-1.2 349
Using Character Variables
Like other variables, chars must be
declared before using them, and can be
initialized at the time of declaration.
Here are some examples:
char a, b, c; /* Declare three
uninitialized char variables */
char code = `x'; /* Declare the char
variable code and store x there*/
code = `!'; /* Store ! in the
variable named code */
To create literal character constants,
enclose a single character in single
quotation marks. The compiler
automatically translates literal
character constants into the
corresponding ASCII codes, and the
numeric code value is assigned to the
variable.
The function printf() can be used to
print both characters and numbers. The
format string %c instructs printf() to
print a character, whereas %d instructs
it to print a decimal integer.
5/21/2014 Version-1.2 350
Using Strings
A string is any sequence of characters.
Strings are used to hold text data,
which is comprised of letters,
numerals, punctuation marks, and
other symbols

Variables of type char can hold only a
single character, so they have limited
usefulness. Also there was a need a
way to store strings, which are
sequences of characters. A person's
name and address are examples of
strings. Although there is no special
data type for strings, C handles this
type of information with arrays of
characters.
To hold a string of six characters, for
example, an array of type char with
seven elements needs to be declared


5/21/2014 Version-1.2 351
Arrays of Characters
To hold a string of six characters, for
example, an array of type char with
seven elements needs to be declared.
Arrays of type char are declared like
arrays of other data types.
E.g. char string[8];
It's a 8-element array, so why can it
hold only seven characters?
In C, a string is defined as a sequence
of characters ending with the null
character, a special character
represented by \0.
Although it's represented by two
characters (backslash and zero), the
null character is interpreted as a single
character and has the ASCII value of
0.

5/21/2014 Version-1.2 352
Initializing Character Arrays
Like other C data types, character
arrays can be initialized when they are
declared.
E.g. char string[8] = { `V', `s', `q',
`u', `a', `r', `e', `\0' };

It's more convenient, however, to use
a literal string, which is a sequence of
characters enclosed in double quotes:
char string[8] = Vsquare";
When using a literal string in the
program, the compiler automatically
adds the terminating null character at
the end of the string.

char string[] =Vsquare;
If not specified the number of
subscripts when an array is declared,
the compiler calculates the size of the
array.Compiler creates and initializes
an eight-element array.

5/21/2014 Version-1.2 353
Strings and Pointers
strings are stored in arrays of type
char, with the end of the string (which
might not occupy the entire array)
marked by the null character.
Because the end of the string is
marked, all one need in order to define
a given string is something that points
to its beginning.
We know now that the name of an
array is a pointer to the first element
of the array.
Therefore, for a string that's stored in
an array, only the array name is
needed in order to access it.
5/21/2014 Version-1.2 354
Allocating String Space at Compilation
char *message;
This statement declares a pointer to a
variable of type char named message.
It doesn't point to anything now.
char *message = "Great Caesar\'s
Ghost!";
When this statement executes, the
string Great Caesar's Ghost! (with a
terminating null character) is stored
somewhere in memory, and the pointer
message is initialized to point to the
first character of the string.
*message and message[] also are
equivalent;
they both mean "a pointer to."
char message[] = "Great Caesar\'s
Ghost!";
5/21/2014 Version-1.2 355
String handling functions
String Length and Storage
A string is a sequence of characters,
with its beginning indicated by a
pointer and its end marked by the null
character \0. At times, the length of a
string (the number of characters
between the start and the end of the
string) has to be known.
This length is obtained with the library
function strlen(). Its prototype, in
string.h, is:
size_t strlen(char *str);
The size_t return type is defined in
string.h as unsigned, so the function
strlen() returns an unsigned integer.
5/21/2014 Version-1.2 356
Copying Strings
The C library has three functions for
copying strings. The string-copying
functions are strcpy(), strncpy(), and
strdup(). All of the string-copying
functions require the header file
string.h.
1. The strcpy() Function
The library function strcpy() copies an
entire string to another memory
location. Its prototype is as follows:
char *strcpy( char *destination, char
*source ); The function strcpy() copies
the string (including the terminating
null character \0) pointed to by source
to the location pointed to by
destination. The return value is a
pointer to the new string, destination.



5/21/2014 Version-1.2 357
Copying strings
2. The strncpy() Function
The strncpy() function is similar to
strcpy(), except that strncpy() allows to
specify how many characters to copy.
Its prototype is:

char *strncpy(char *destination, char
*source, size_t n);
The arguments destination and source
are pointers to the destination and
source strings. The function copies, at
most, the first n characters of source to
destination.
If source is shorter than n characters,
enough null characters are added to the
end of source to make a total of n
characters copied to destination.
If source is longer than n characters,
no terminating \0 is added to
destination. The function's return value
is destination.
5/21/2014 Version-1.2 358
Concatenating Strings
Concatenation means to join two
strings--to tack one string onto the end
of another. The C standard library
contains two string concatenation
functions--strcat() and strncat()--both
of which require the header file
string.h.
1. The strcat() Function
The prototype of strcat() is:
char *strcat(char *str1, char *str2);
The function appends a copy of str2
onto the end of str1, moving the
terminating null character to the end of
the new string.
Enough space can be allocated for str1
to hold the resulting string.
The return value of strcat() is a
pointer to str1.

5/21/2014 Version-1.2 359
Concatenating Strings
2. The strncat() Function
it lets us specify how many characters
of the source string are appended to
the end of the destination string.

The prototype is
char *strncat(char *str1, char *str2,
size_t n);
If str2 contains more than n characters,
the first n characters are appended to
the end of str1.
If str2 contains fewer than n
characters, all of str2 is appended to
the end of str1.
In either case, a terminating null
character is added at the end of the
resulting string.
The function returns a pointer to str1.


5/21/2014 Version-1.2 360
Comparing Strings
Strings are compared to determine
whether they are equal or unequal. If
they are unequal, one string is
"greater than" or "less than" the other.
Determinations of "greater" and "less"
are made with the ASCII codes of the
characters.
The function strcmp() compares two
strings character by character. Its
prototype is
int strcmp(char *str1, char *str2);
The arguments str1 and str2 are
pointers to the strings being
compared. The function's return values
are given in Table.
Table : The values returned by
strcmp().


Str1 is equal to str2 0
Str1 is greater than str2 >0
Str1 is less than str2 <0
Meaning Return Value
5/21/2014 Version-1.2 361
Comparing Partial Strings
The library function strncmp()
compares a specified number of
characters of one string to another
string. Its prototype is:

int strncmp(char *str1, char *str2,
size_t n);

The function strncmp() compares n
characters of str2 to str1. The
comparison proceeds until n characters
have been compared or the end of str1
has been reached. The method of
comparison and return values are the
same as for strcmp(). The comparison
is case-sensitive.
5/21/2014 Version-1.2 362
Searching Strings
The C library contains a number of
functions that search strings. There are
six string-searching functions, all of
which require the header file string.h.

The strchr() Function
The strchr() function finds the first
occurrence of a specified character in a
string. The prototype is:
char *strchr(char *str, int ch);
The function strchr() searches str from
left to right until the character ch is
found or the terminating null character
is found. If ch is found, a pointer to it
is returned. If not, NULL is returned.


5/21/2014 Version-1.2 363
Searching Strings
The strrchr() Function

The library function strrchr() is identical
to strchr(), except that it searches a
string for the last occurrence of a
specified character in a string. Its
prototype is:

char *strrchr(char *str, int ch);

The function strrchr() returns a pointer to
the last occurrence of ch in str and NULL
if it finds no match.


5/21/2014 Version-1.2 364
Searching Strings
The strcspn() Function
The library function strcspn() searches
one string for the first occurrence of
any of the characters in a second
string. Its prototype is:
size_t strcspn(char *str1, char
*str2);

The function strcspn() starts searching
at the first character of str1, looking for
any of the individual characters
contained in str2.
The function doesn't look for the string
str2, but only the characters it
contains.
If the function finds a match, it returns
the offset from the beginning of str1,
where the matching character is
located. If it finds no match, strcspn()
returns the value of strlen(str1). This
indicates that the first match was the
null character terminating the string.

5/21/2014 Version-1.2 365
Searching Strings
The strspn() Function
Its prototype is:
size_t strspn(char *str1, char
*str2);

The function strspn() searches str1,
comparing it character by character
with the characters contained in str2.
It returns the position of the first
character in str1 that doesn't match a
character in str2.
In other words, strspn() returns the
length of the initial segment of str1
that consists entirely of characters
found in str2. The return is 0 if no
characters match.
5/21/2014 Version-1.2 366
Searching Strings
The strpbrk() Function
The library function strpbrk() is similar
to strcspn(), searching one string for
the first occurrence of any character
contained in another string. It differs in
that it doesn't include the terminating
null characters in the search.
The function prototype is:
char *strpbrk(char *str1, char
*str2);

The function strpbrk() returns a
pointer to the first character in str1
that matches any of the characters in
str2. If it doesn't find a match, the
function returns NULL

5/21/2014 Version-1.2 367
Searching Strings
The strstr() Function

This function searches for the first
occurrence of one string within another,
and it searches for the entire string, not
for individual characters within the string.
Its prototype is:

char *strstr(char *str1, char *str2);
The function strstr() returns a pointer to
the first occurrence of str2 within str1.
If it finds no match, the function returns
NULL. If the length of str2 is 0, the
function returns str1.
When strstr() finds a match, offset of
str2 can be obtained within str1 by
pointer subtraction. The matching
procedure that strstr() uses is case-
sensitive.

5/21/2014 Version-1.2 368
String-to-Number Conversions
Sometimes there is a need to convert
the string representation of a number
to an actual numeric variable.
For example, the string "123" can be
converted to a type int variable with
the value 123.
Three functions can be used to convert
a string to a number.
their prototypes are in stdlib.h


5/21/2014 Version-1.2 369
String-to-Number Conversions
The atoi() Function
The library function atoi() converts a
string to an integer.
The prototype is:
int atoi(char *ptr);
The function atoi() converts the string
pointed to by ptr to an integer. Besides
digits, the string can contain leading
white space and a + or -- sign.
Conversion starts at the beginning of
the string and proceeds until an
unconvertible character (for example,
a letter or punctuation mark) is
encountered.
The resulting integer is returned to the
calling program. If it finds no
convertible characters, atoi() returns
0.
5/21/2014 Version-1.2 370
String-to-Number Conversions
The atol() Function
The library function atol() works exactly
like atoi(), except that it returns a type
long.
The function prototype is:
long atol(char *ptr);
Returns same value as return value of int
but long instead of a type int.


5/21/2014 Version-1.2 371
String-to-Number Conversions
The atof() Function
The function atof() converts a string to
a type double.
The prototype is:
double atof(char *str);
The argument str points to the string to
be converted.
This string can contain leading white
space and a + or -- character. The
number can contain the digits 0 through
9, the decimal point, and the exponent
indicator E or e.
If there are no convertible characters,
atof() returns 0.
5/21/2014 Version-1.2 372
Character Test Functions
The header file ctype.h contains the
prototypes for a number of functions
that test characters, returning TRUE or
FALSE depending on whether the
character meets a certain condition.

The isxxxx() functions are actually
macros, defined in ctype.h
The isxxxx() macros all have the same
prototype:

int isxxxx(int ch);

ch is the character being tested. The
return value is TRUE (nonzero) if the
condition is met or FALSE (zero) if it
isn't.


5/21/2014 Version-1.2 373
Character Test Functions
.
Returns TRUE if ch is a hexadecimal digit (0 through 9, a through f, A
through F).
isxdigit()
Returns TRUE if ch is an uppercase letter. isupper()
Returns TRUE if ch is a white space character (space, tab, vertical tab,
line feed, form feed, or carriage return).
isspace()
Returns TRUE if ch is a punctuation character. ispunct()
Returns TRUE if ch is a printing character (including a space). isprint()
Returns TRUE if ch is a lowercase letter. islower()
Returns TRUE if ch is a printing character (other than a space). isgraph()
Returns TRUE if ch is a digit. isdigit()
Returns TRUE if ch is a control character. iscntrl()
Returns TRUE if ch is a standard ASCII character (between 0 and 127). isascii()
Returns TRUE if ch is a letter. isalpha()
Returns TRUE if ch is a letter or a digit. isalnum()
Action Macro
5/21/2014 Version-1.2 374
Dynamic memory allocation
and deallocation
5/21/2014 Version-1.2 375
Objectives
Type Conversions
Automatic Type Conversions
Explicit Conversions Using
Typecasts
Allocating Memory Storage Space
The malloc() Function
The calloc() Function
The realloc() Function
The free() Function
Manipulating Memory Blocks
The memcpy() Function
The memmove() Function
Bit Fields in Structures
5/21/2014 Version-1.2 376
Type Conversions
All of C's data objects have a specific
type. A numeric variable can be an int
or a float, a pointer can be a pointer to
a double or char, and so on. Programs
often require that different types be
combined in expressions and
statements.
Sometimes C automatically handles
the different types, so no need to be
concerned.
Other times, data types must be
explicitly converted to another to avoid
erroneous results.

Automatic Type Conversions
the C compiler performs automatic
type conversions automatically without
needing to do anything. However,
should be aware of what's going on so
that one can understand how C
evaluates expressions.
5/21/2014 Version-1.2 377
Type Promotion in Expressions
When a C expression is evaluated, the
resulting value has a particular data
type. If all the components in the
expression have the same type, the
resulting type is that type as well.
For example, if x and y are both type
int, the following expression is
type int also:
x + y

What if the components of an
expression have different types? In that
case, the expression has the same type
as its most comprehensive component.
an expression containing an int and a
char evaluates to type int, an
expression containing a long and a float
evaluates to type float, and so on.
5/21/2014 Version-1.2 378
Type Promotion in Expressions
Within expressions, individual operands
are promoted as necessary to match
the associated operands in the
expression. Operands are promoted, in
pairs, for each binary operator in the
expression. Of course, promotion isn't
needed if both operands are the same
type. If they aren't, promotion follows
these rules:
If either operand is a double, the other
operand is promoted to type double.
If either operand is a float, the other
operand is promoted to type float.
If either operand is a long, the other
operand is converted to type long.
For example, if x is an int and y is a
float, evaluating the expression x/y
causes x to be promoted to type float
before the expression is evaluated
5/21/2014 Version-1.2 379
Conversion by Assignment
Promotions also occur with the
assignment operator. The expression
on the right side of an assignment
statement is always promoted to the
type of the data object on the left side
of the assignment operator.
If f is a type float and i is a type int, i
is promoted to type float in this
assignment statement:
f = i;
In contrast, the assignment statement
i = f;
causes f to be demoted to type int. Its
fractional part is lost on assignment to
i
5/21/2014 Version-1.2 380
Explicit Conversions Using Typecasts
A typecast uses the cast operator to
explicitly control type conversions in a
program.
A typecast consists of a type name, in
parentheses, before an expression.
Casts can be performed on arithmetic
expressions and pointers.
The result is that the expression is
converted to the type specified by the
cast.
Casting Arithmetic Expressions
Casting an arithmetic expression tells
the compiler to represent the value of
the expression in a certain way.
However, a cast is under programmers
control, not the compiler's.
For example, if i is a type int, the
expression
(float)i Casts i to type float. In other
words, the program makes an internal
copy of the value of i in floating-point
format.
5/21/2014 Version-1.2 381
Casting Pointers
A type void pointer is a generic pointer;
it can point to anything. Before a void
pointer is used, one must cast it to the
proper type.
Note that, no need to cast a pointer in
order to assign a value to it or to
compare it with NULL.
However, must cast it before de-
referencing it or performing pointer
arithmetic with it.
5/21/2014 Version-1.2 382
Allocating Memory Storage
Space
The C library contains functions for
allocating memory storage space at
runtime, a process called dynamic
memory allocation.
Explicitly allocating memory in the
program source code by declaring
variables, structures, and arrays is
called as static memory allocation.
5/21/2014 Version-1.2 383
The malloc() Function
The malloc() function isn't limited to allocating memory for strings,
of course; it can allocate space for any storage need. This function
allocates memory by the byte.
void *malloc(size_t num);

The calloc() Function
The calloc() function also allocates memory. Rather than allocating a
group of bytes as malloc() does, calloc() allocates a group of objects.
The function prototype is
void *calloc(size_t num, size_t size);
The argument num is the number of objects to allocate, and size is
the size (in bytes) of each object. If allocation is successful, all the
allocated memory is cleared (set to 0), and the function returns a
pointer to the first byte. If allocation fails or if either num or size is
0, the function returns NULL.
5/21/2014 Version-1.2 384
The realloc() Function
The realloc() function changes the size
of a block of memory that was
previously allocated with malloc() or
calloc().
The function prototype is
void *realloc(void *ptr, size_t size);
The ptr argument is a pointer to the
original block of memory. The new
size, in bytes, is specified by size.
If sufficient space exists to expand the
memory block pointed to by ptr, the
additional memory is allocated and the
function returns ptr.
If sufficient space does not exist to
expand the current block in its current
location, a new block of the size for size
is allocated, and existing data is copied
from the old block to the beginning of
the new block. The old block is freed,
and the function returns a pointer to
the new block.

5/21/2014 Version-1.2 385
The free() Function
When memory is allocated with either
malloc() or calloc(), it is taken from the
dynamic memory pool that is available
to the program. This pool is sometimes
called the heap, and it is finite.
When the program finishes using a
particular block of dynamically allocated
memory, one should deallocate, or free,
the memory to make it available for
future use.
To free memory that was allocated
dynamically, use free(). Its prototype is
void free(void *ptr);
The free() function releases the
memory pointed to by ptr. This
memory must have been allocated with
malloc(), calloc(), or realloc(). If ptr is
NULL, free() does nothing.
5/21/2014 Version-1.2 386
Manipulating Memory Blocks
The C library also contains functions
that can be used to manipulate blocks
of memory--setting all bytes in a block
to a specified value, and copying and
moving information from one location
to another.

The memset() Function
To set all the bytes in a block of
memory to a particular value, use
memset().
The function prototype is
void * memset(void *dest, int c, size_t
count);
The argument dest points to the block
of memory. c is the value to set, and
count is the number of bytes, starting
at dest, to be set. Note that while c is
a type int, it is treated as a type char.
In other words, only the low-order
byte is used, and can specify values of
c only in the range 0 through 255
5/21/2014 Version-1.2 387
The memcpy() Function
memcpy() copies bytes of data
between memory blocks, sometimes
called buffers. This function doesn't
care about the type of data being
copied--it simply makes an exact byte-
for-byte copy.
The function prototype is
void *memcpy(void *dest, void *src,
size_t count);
The arguments dest and src point to
the destination and source memory
blocks, respectively. count specifies the
number of bytes to be copied. The
return value is dest.
5/21/2014 Version-1.2 388
The memmove() Function
copying a specified number of bytes
from one memory block to another. It's
more flexible, however, because it can
handle overlapping memory blocks
properly.
Because memmove() can do everything
memcpy() can do with the added
flexibility of dealing with overlapping
blocks, rarely, if ever, should have a
reason to use memcpy().
The prototype is
void *memmove(void *dest, void *src,
size_t count);

dest and src point to the destination
and source memory blocks, and count
specifies the number of bytes to be
copied. The return value is dest.
5/21/2014 Version-1.2 389
Bit Fields in Structures
The final bit-related topic is the use of
bit fields in structures. By using bit
fields, one can accomplish even
greater customization and save
memory space as well.
A bit field is a structure member that
contains a specified number of bits.
one can declare a bit field to contain
one bit, two bits, or whatever number
of bits is required to hold the data
stored in the field.
5/21/2014 Version-1.2 390
First C Program
main()
{
printf("Hello, World!");
}




Go Back
5/21/2014 Version-1.2 391
A program to find area of Circle
#include<math.h>
main()
{
const float pi=3.14156;
float area,radius;
printf("Enter the radius of the
circle\n");
scanf("%f",&radius);
area=pi*(pow(radius,2));
printf("Area of the circle is
%f\n",area);
}


5/21/2014 Version-1.2 392

5/21/2014 Version-1.2 393
A library is a file containing several
object files that can be used as a
single entity in a linking phase of a
program.

Normally the library is indexed, so it is
easy to find symbols (functions,
variables and so on) in them. For this
reason, linking a program whose
object files are ordered in libraries is
faster than linking a program whose
object files are separate on the disk.

Static libraries are just collections of
object files that are linked into the
program during the linking phase of
compilation, and are not relevant
during runtime. This last comment
seems obvious, as we already know
that object files are also used only
during the linking phase, and are not
required during runtime - only the
program's executable file is needed in
order to run the program.
5/21/2014 Version-1.2 394
Shared libraries (also called dynamic libraries) are linked into the
program in two stages. First, during compile time, the linker verifies
that all the symbols (again, functions, variables and the like)
required by the program, are either linked into the program, or in
one of its shared libraries.

However, the object files from the dynamic library are not inserted
into the executable file. Instead, when the program is started, a
program in the system (called a dynamic loader) checks out which
shared libraries were linked with the program, loads them to
memory, and attaches them to the copy of the program in memory.

The complex phase of dynamic loading makes launching the program
slightly slower, but this is a very insignificant drawback, that is out-
weighted by a great advantage - if a second program linked with the
same shared library is executed, it can use the same copy of the
shared library, thus saving a lot of memory.

For example, the standard "C" library is normally a shared library,
and is used by all C programs. Yet, only one copy of the library is
stored in memory at any given time.
5/21/2014 Version-1.2 395
Creating A Static "C" Library Using "ar"
The basic tool used to create static libraries is a program called 'ar',
for 'archiver'.

$ar rc libutil.a util_file.o util_net.o util_math.o

This command creates a static library named 'libutil.a' and puts
copies of the object files "util_file.o", "util_net.o" and "util_math.o"
in it.

If the library file already exists, it has the object files added to it, or
replaced, if they are newer than those inside the library.

The 'c' flag tells ar to create the library if it doesn't already exist. The
'r' flag tells it to replace older object files in the library, with the new
object files.
5/21/2014 Version-1.2 396
Indexing the library using "ranlib"
After an archive is created, or
modified, there is a need to index it.

This index is later used by the
compiler to speed up symbol-lookup
inside the library, and to make sure
that the order of the symbols in the
library won't matter during
compilation.

The command used to create or
update the index is called 'ranlib', and
is invoked as follows:

$ ranlib libutil.a

5/21/2014 Version-1.2 397
Using A "C" Library In A Program
After we created our archive, we want
to use it in a program. This is done by
adding the library's name to the list of
object file names given to the linker,
using a special flag, normally '-l'. Here
is an example:

cc main.o -L. -llibutil -o prog

This will create a program using object
file "main.o", and any symbols it
requires from the "util" static library.
Note that we omitted the "lib" prefix
and the ".a" suffix when mentioning
the library on the link command. The
linker attaches these parts back to the
name of the library to create a name
of a file to look for.
Note also the usage of the '-L' flag -
this flag tells the linker that libraries
might be found in the given directory
('.', referring0 to the current
directory), in addition to the standard
locations where the compiler looks for
system libraries.
5/21/2014 Version-1.2 398
Creating A Shared "C" Library Using "ld"
The creation of a shared library is
rather similar to the creation of a static
library. Compile a list of object files,
then insert them all into a shared
library file. However, there are two
major differences:

Compile for "Position Independent
Code" (PIC) - When the object files are
generated, we have no idea where in
memory they will be inserted in a
program that will use them. Many
different programs may use the same
library, and each load it into a different
memory in address. Thus, we need that
all jump calls ("goto", in assembly
speak) and subroutine calls will use
relative addresses, and not absolute
addresses. Thus, we need to use a
compiler flag that will cause this type of
code to be generated.

In most compilers, this is done by
specifying '-fPIC' or '-fpic' on the
compilation command.

5/21/2014 Version-1.2 399
Library File Creation - unlike a static
library, a shared library is not an
archive file. It has a format that is
specific to the architecture for which it
is being created. Thus, we need to use
the compiler (either the compiler's
driver, or its linker) to generate the
library, and tell it that it should create
a shared library, not a final program
file.

This is done by using the '-G' flag with
some compilers, or the '-shared' flag
with other compilers.
Thus, the set of commands we will use
to create a shared library, would be
something like this:

cc -fPIC -c util_file.c
cc -fPIC -c util_net.c
cc -fPIC -c util_math.c
cc -shared libutil.so util_file.o
util_net.o util_math.o
5/21/2014 Version-1.2 400
The first three commands compile the
source files with the PIC option, so
they will be suitable for use in a shared
library (they may still be used in a
program directly, even thought they
were compiled with PIC).

The last command asks the compiler to
generate a shared library.
5/21/2014 Version-1.2 401
Using A Shared "C" Library
Using a shared library is done in two steps:

Compile Time - here we need to tell the linker to scan the shared
library while building the executable program, so it will be convinced
that no symbols are missing. It will not really take the object files
from the shared library and insert them into the program.

Run Time - when we run the program, we need to tell the system's
dynamic loader (the process in charge of automatically loading and
linking shared libraries into the running process) where to find our
shared library.
This can be done like this:

cc main.o -L. -lutil -o prog

The linker will look for the file 'libutil.so' (-lutil) in the current
directory (-L.), and link it to the program, but will not place its object
files inside the resulting executable file, 'prog'.
5/21/2014 Version-1.2 402
The run-time part is a little trickier.

Normally, the system's dynamic loader looks for shared libraries in some
system specified directories (such as /lib, /usr/lib, /usr/X11/lib and so on).
When we build a new shared library that is not part of the system, we can use
the 'LD_LIBRARY_PATH' environment variable to tell the dynamic loader to look
in other directories.
. To check if you have this variable defined, try:

echo $LD_LIBRARY_PATH

If you get a message such as 'LD_LIBRARY_PATH: Undefined variable.', then it
is not defined.
Here is how to define this variable

$ LD_LIBRARY_PATH=/full/path/to/library/directory:${LD_LIBRARY_PATH}
$export LD_LIBRARY_PATH

After you've defined LD_LIBRARY_PATH, you can check if the system locates
the library properly for a given program linked with this library:

ldd prog

You might also like