Sie sind auf Seite 1von 113

Arrays in C Programming

What is an Array in C Language?


An array in C Programing Language can be defined as number of memory locations, each
of which can store the same data type and which can be references through the same
variable name.

An array is a collective name given to a group of similar quantities. These similar quantities
could be percentage marks of 100 students, number of chairs in home, or salaries of 300
employees or ages of 25 students. Thus an array is a collection of similar elements. These
similar elements could be all integers or all floats or all characters etc. Usually, the array of
characters is called a “string”, where as an array of integers or floats is called simply an
array. All elements of any given array must be of the same type i.e we can’t have an array
of 10 numbers, of which 5 are int and 5 are float.

Arrays and pointers have a special relationship as arrays use pointers to reference memory
locations.

Declaration of an Array
Arrays must be declared before they can be used in the program. Standard array declaration
is as

type variable_name[lengthofarray];

Here type specifies the variable type of the element which is going to be stored in the array.
In C programming language we can declare the array of any basic standard type which C
language supports. For example

double height[10];
float width[20];
int min[9];
char name[20];

In C Language, arrays starts at position 0. The elements of the array occupy adjacent
locations in memory. C Language treats the name of the array as if it were a pointer to the
first element This is important in understanding how to do arithmetic with arrays. Any item
in the array can be accessed through its index, and it can be accessed any where from with
in the program. So

m=height[0];

variable m will have the value of first item of array height.


The program below will declare an array of five integers and print all the elements of the
array.

int myArray [5] = {1,2,3,4,5};


/* To print all the elements of the array
for (int i=0;i<5;i++){
printf("%d", myArray[i]);
}

Initializing Arrays
Initializing of array is very simple in c programming. The initializing values are enclosed
within the curly braces in the declaration and placed following an equal sign after the array
name. Here is an example which declares and initializes an array of five elements of type
int. Array can also be initialized after declaration. Look at the following C code which
demonstrate the declaration and initialization of an array.

int myArray[5] = {1, 2, 3, 4, 5}; //declare and initialize the array in one statement
int studentAge[4];
studentAge[0]=14;
studentAge[1]=13;
studentAge[2]=15;
studentAge[3]=16;

Performing operations on Arrays


Here is a program that will demonstrate the simple operations of the array.

#include <stdio.h>
void oneWay(void);
void anotherWay(void);
int main(void) {
printf("\noneWay:\n");
oneWay();
printf("\nantherWay:\n");
anotherWay();
}

/*Array initialized with aggregate */


void oneWay(void) {
int vect[10] = {1,2,3,4,5,6,7,8,9,0};
int i;
for (i=0; i<10; i++){
printf("i = %2d vect[i] = %2d\n", i, vect[i]);
}
}
/*Array initialized with loop */
void anotherWay(void) {
int vect[10];
int i;
for (i=0; i<10; i++)
vect[i] = i+1;
for (i=0; i<10; i++)
printf("i = %2d vect[i] = %2d\n", i, vect[i]);
}

/* The output of this program is


oneWay:
i = 0 vect[i] = 1
i = 1 vect[i] = 2
i = 2 vect[i] = 3
i = 3 vect[i] = 4
i = 4 vect[i] = 5
i = 5 vect[i] = 6
i = 6 vect[i] = 7
i = 7 vect[i] = 8
i = 8 vect[i] = 9
i = 9 vect[i] = 0

antherWay:
i = 0 vect[i] = 1
i = 1 vect[i] = 2
i = 2 vect[i] = 3
i = 3 vect[i] = 4
i = 4 vect[i] = 5
i = 5 vect[i] = 6
i = 6 vect[i] = 7
i = 7 vect[i] = 8
i = 8 vect[i] = 9
i = 9 vect[i] = 10
*/

Here is a more complex program that will demonstrate how to read, write and traverse the
integer arrays

#include <stdio.h>
void intSwap(int *x, int *y);
int getIntArray(int a[], int nmax, int sentinel);
void printIntArray(int a[], int n);
void reverseIntArray(int a[], int n);

int main(void) {
int x[10];
int hmny;

hmny = getIntArray(x, 10, 0);


printf("The array was: \n");
printIntArray(x,hmny);
reverseIntArray(x,hmny);
printf("after reverse it is:\n");
printIntArray(x,hmny);
}

void intSwap(int *x, int *y)


/* It swaps the content of x and y */
{
int temp = *x;
*x = *y;
*y = temp;
}

/* n is the number of elements in the array a.


* These values are printed out, five per line. */
void printIntArray(int a[], int n){
int i;
for (i=0; i<n; ){
printf("\t%d ", a[i++]);
if (i%5==0)
printf("\n");
}
printf("\n");
}

/* It reads up to nmax integers and stores then in a; sentinel


* terminates input. */
int getIntArray(int a[], int nmax, int sentinel)
{
int n = 0;
int temp;

do {
printf("Enter integer [%d to terminate] : ", sentinel);
scanf("%d", &temp);
if (temp==sentinel) break;
if (n==nmax)
printf("array is full\n");
else
a[n++] = temp;
}while (1);
return n;
}

/* It reverse the order of the first n elements of array */


void reverseIntArray(int a[], int n)
{
int i;
for(i=0;i<n/2;i++){
intSwap(&a[i],&a[n-i-1]);
}
}

Copy one array into another


There is no such statement in C language which can directly copy an array into another
array. So we have to copy each item separately into another array.

#include <stdio.h>
int main()
{
int iMarks[4];
short newMarks[4];
iMarks[0]=78;
iMarks[1]=64;
iMarks[2]=66;
iMarks[3]=74;
for(i=0; i<4; i++)
newMarks[i]=iMarks[i];
for(j=0; j<4; j++)
printf("%d\n", newMarks[j]);
return 0;
}

To summarize, arrays are provides a simple mechanism where more than one elements of
same type are to be used. We can maintain, manipulate and store multiple elements of same
type in one array variable and access them through index.

Multidimensional Arrays
In C Language one can have arrays of any dimensions. To understand the concept
of multidimensional arrays let us consider the following 4 X 5 matrix

Row Column numbers (j)


number 0 11 3 5 -9 -6
(i) 1 5 6 -8 7 24
2 -8 9 2 12 45
3 10 13 -10 4 5

Let us assume the name of matrix is x

To access a particular element from the array we have to use two subscripts on for row
number and other for column number the notation is of the form X [i] [j] where i stands for
row subscripts and j stands for column subscripts. Thus X [0] [0] refers to 10, X [2] [1]
refers to 16 and so on In short multidimensional arrays are defined more or less in the same
manner as single dimensional arrays, except that for subscripts you require two squire two
square brackets. We will restrict our decision to two dimensional arrays.

Below given are some typical two-dimensional array definitions

float table [50] [50];


char line [24] [40];

The first example defines tables as a floating point array having 50 rows and 50 columns.
the number of elements will be 2500 (50 X50).

The second declaration example establishes an array line of type character with 24 rows
and 40 columns. The number of elements will be (24 X 40) 1920 consider the following
two dimensional array definition int values [3] [4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10. 11, 12, };

Values [0] [0] = 1 Values [0] [1] = 2 Values [0] [2] = 3 Values [0] [3] = 4
Values [1] [0] = 5 Values [1] [1] = 6 Values [1] [2] = 7 Values [1] [3] = 8
Values [2] [0] = 9 Values [2] [1] = 10 Values [2] [2] = 11 Values [2] [3] = 12

Here the first subscript stands for the row number and second one for column number. First
subscript ranges from 0 to 2 and there are altogether 3 rows second one ranges from 0 to 3
and there are altogether 4 columns.

Alternatively the above definition can be defined and initialized as

int values [3] [4] = {


{
1, 2, 3, 4
}
{
5, 6, 7, 8
}
{
9, 10, 11, 12
}
};
Here the values in first pair of braces are initialized to elements of first row, the values of
second pair of inner braces are assigned to second row and so on. Note that outer pair of
curly braces is required. If there are two few values within a pair of braces the remaining
elements will be assigned as zeros.

Here is a sample program that stores roll numbers and marks obtained by a student side by
side in matrix

main ( )
{
int stud [4] [2];
int i, j;
for (i =0; i < =3; i ++)
{
printf ("\n Enter roll no. and marks");
scanf ("%d%d", &stud [i] [0], &stud [i] [1] );
}
for (i = 0; i < = 3; i ++)
printf ("\n %d %d", stud [i] [0], stud [i] [1]);
}

The above example illustrates how a two dimensional array can be read and how the values
stored in the array can be displayed on screen.

Basic dataypes and operators in C


Programming
C programming language provides a standard and minimal set of basic data types.
Sometimes these are called primitive data types. More complex data structures can be built
up from these basic types.

Integer Types
The "integral" types in C form a family of integer types. They all behave like integers and
can be mixed together and used in similar ways. The differences are due to the different
number of bits ("widths") used to implement each type — the wider types can store a
greater ranges of values.

char ASCII character at least 8 bits. Pronounced "car". As a practical matter char is
basically always a byte which is 8 bits which is enough to store a single ASCII character. 8
bits provides a signed range of -128..127 or an unsigned range is 0..255. char is also
required to be the "smallest addressable unit" for the machine — each byte in memory has
its own address.
short Small integer — at least 16 bits which provides a signed range of -32768..32767.
Typical size is 16 bits. Not used so much.

int Default integer — at least 16 bits, with 32 bits being typical. Defined to be the "most
comfortable" size for the computer. If you do not really care about the range for an integer
variable, declare it int since that is likely to be an appropriate size (16 or 32 bit) which
works well for that machine.

long Large integer — at least 32 bits. Typical size is 32 bits which gives a signed range of
about -2 billion ..+2 billion. Some compilers support "long long" for 64 bit ints.

The integer types can be preceded by the qualifier unsigned which disallows representing
negative numbers, but doubles the largest positive number representable. For example, a 16
bit implementation of short can store numbers in the range -32768..32767, while unsigned
short can store 0..65535. You can think of pointers as being a form of unsigned long on a
machine with 4 byte pointers. In my opinion, it’s best to avoid using unsigned unless you
really need to. It tends to cause more misunderstandings and problems than it is worth.

Extra: Portability Problems


Instead of defining the exact sizes of the integer types, C defines lower bounds. This makes
it easier to implement C compilers on a wide range of hardware. Unfortunately it
occasionally leads to bugs where a program runs differently on a 16-bit-int machine than it
runs on a 32-bit-int machine. In particular, if you are designing a function that will be
implemented on several different machines, it is a good idea to use typedefs to set up types
like Int32 for 32 bit int and Int16 for 16 bit int. That way you can prototype a function
Foo(Int32) and be confident that the typedefs for each machine will be set so that the
function really takes exactly a 32 bit int. That way the code will behave the same on all the
different machines.

char Constants
A char constant is written with single quotes (‘) like ‘A’ or ‘z’. The char constant ‘A’ is
really just a synonym for the ordinary integer value 65 which is the ASCII value for
uppercase ‘A’. There are special case char constants, such as ‘\t’ for tab, for characters
which are not convenient to type on a keyboard.

‘A’ uppercase ‘A’ character


‘\n’ newline character
‘\t’ tab character
‘\0’ the "null" character — integer value 0 (different from the char digit ‘0’)
‘\012’ the character with value 12 in octal, which is decimal 10

int Constants
Numbers in the source code such as 234 default to type int. They may be followed by an
‘L’ (upper or lower case) to designate that the constant should be a long such as 42L. An
integer constant can be written with a leading 0x to indicate that it is expressed in
hexadecimal — 0x10 is way of expressing the number 16. Similarly, a constant may be
written in octal by preceding it with "0" — 012 is a way of expressing the number 10.

Type Combination and Promotion


The integral types may be mixed together in arithmetic expressions since they are all
basically just integers with variation in their width. For example, char and int can be
combined in arithmetic expressions such as (‘b’ + 5). How does the compiler deal with the
different widths present in such an expression? In such a case, the compiler "promotes" the
smaller type (char) to be the same size as the larger type (int) before combining the values.
Promotions are determined at compile time based purely on the types of the values in the
expressions. Promotions do not lose information — they always convert from a type to
compatible, larger type to avoid losing information.

Pitfall — int Overflow


I once had a piece of code which tried to compute the number of bytes in a buffer with the
expression (k * 1024) where k was an int representing the number of kilobytes I wanted.
Unfortunately this was on a machine where int happened to be 16 bits. Since k and 1024
were both int, there was no promotion. For values of k >= 32, the product was too big to fit
in the 16 bit int resulting in an overflow. The compiler can do whatever it wants in
overflow situations — typically the high order bits just vanish. One way to fix the code was
to rewrite it as (k * 1024L) — the long constant forced the promotion of the int. This was
not a fun bug to track down — the expression sure looked reasonable in the source code.
Only stepping past the key line in the debugger showed the overflow problem.
"Professional Programmer’s Language." This example also demonstrates the way that C
only promotes based on the types in an expression. The compiler does not consider the
values 32 or 1024 to realize that the operation will overflow (in general, the values don’t
exist until run time anyway). The compiler just looks at the compile time types, int and int
in this case, and thinks everything is fine.

Floating point Types


float Single precision floating point number typical size: 32 bits double Double precision
floating point number typical size: 64 bits long double Possibly even bigger floating point
number (somewhat obscure) Constants in the source code such as 3.14 default to type
double unless the are suffixed with an ‘f’ (float) or ‘l’ (long double). Single precision
equates to about 6 digits of precision and double is about 15 digits of precision. Most C
programs use double for their computations. The main reason to use float is to save
memory if many numbers need to be stored. The main thing to remember about floating
point numbers is that they are inexact. For example, what is the value of the following
double expression?
(1.0/3.0 + 1.0/3.0 + 1.0/3.0) // is this equal to 1.0 exactly?

The sum may or may not be 1.0 exactly, and it may vary from one type of machine to
another. For this reason, you should never compare floating numbers to eachother for
equality (==) — use inequality (<) comparisons instead. Realize that a correct C program
run on different computers may produce slightly different outputs in the rightmost digits of
its floating point computations.

Comments
Comments in C are enclosed by slash/star pairs:

/* .. comments .. */

which may cross multiple lines. C++ introduced a form of comment started by two slashes
and extending to the end of the line: // comment until the line end The // comment form is
so handy that many C compilers now also support it, although it is not technically part of
the C language.

Along with well-chosen function names, comments are an important part of well written
code. Comments should not just repeat what the code says. Comments should describe
what the code accomplishes which is much more interesting than a translation of what each
statement does. Comments should also narrate what is tricky or non-obvious about a
section of code.

Variables
As in most languages, a variable declaration reserves and names an area in memory at run
time to hold a value of particular type. Syntactically, C puts the type first followed by the
name of the variable. The following declares an int variable named "num" and the 2nd line
stores the value 42 into num.

int num;
num = 42;
num 42

A variable corresponds to an area of memory which can store a value of the given type.
Making a drawing is an excellent way to think about the variables in a program. Draw each
variable as box with the current value inside the box. This may seem like a "beginner"
technique, but when I’m buried in some horribly complex programming problem, I
invariably resort to making a drawing to help think the problem through.

Variables, such as num, do not have their memory cleared or set in any way when they are
allocated at run time.Variables start with random values, and it is up to the program to set
them to something sensible before depending on their values.
Names in C are case sensitive so "x" and "X" refer to different variables. Names can
contain digits and underscores (_), but may not begin with a digit. Multiple variables can be
declared after the type by separating them with commas. C is a classical "compile time"
language — the names of the variables, their types, and their implementations are all
flushed out by the compiler at compile time (as opposed to figuring such details out at run
time like an interpreter).

float x, y, z, X;

Assignment Operator =
The assignment operator is the single equals sign (=).

i = 6;
i = i + 1;

The assignment operator copies the value from its right hand side to the variable on its left
hand side. The assignment also acts as an expression which returns the newly assigned
value. Some programmers will use that feature to write things like the following.

y = (x = 2 * x); // double x, and also put x's new value in y

Truncation
The opposite of promotion, truncation moves a value from a type to a smaller type. In that
case, the compiler just drops the extra bits. It may or may not generate a compile time
warning of the loss of information. Assigning from an integer to a smaller integer (e.g..
long to int, or int to char) drops the most significant bits. Assigning from a floating point
type to an integer drops the fractional part of the number.

char ch;
int i;
i = 321;
ch = i; // truncation of an int value to fit in a char
// ch is now 65

The assignment will drop the upper bits of the int 321. The lower 8 bits of the number 321
represents the number 65 (321 – 256). So the value of ch will be (char)65 which happens to
be ‘A’.

The assignment of a floating point type to an integer type will drop the fractional part of the
number. The following code will set i to the value 3. This happens when assigning a
floating point number to an integer or passing a floating point number to a function which
takes an integer.
double pi;
int i;
pi = 3.14159;
i = pi; // truncation of a double to fit in an int
// i is now 3

Pitfall — int vs. float Arithmetic


Here’s an example of the sort of code where int vs. float arithmetic can cause problems.
Suppose the following code is supposed to scale a homework score in the

range 0..20 to be in the range 0..100.


{
int score;
...// suppose score gets set in the range 0..20 somehow score = (score / 20) * 100; // NO -
- score/20 truncates to 0
...

Unfortunately, score will almost always be set to 0 for this code because the integer
division in the expression (score/20) will be 0 for every value of score less than 20. The fix
is to force the quotient to be computed as a floating point number…

score = ((double)score / 20) * 100; // OK -- floating point division from cast


score = (score / 20.0) * 100; // OK -- floating point division from 20.0
score = (int)(score / 20.0) * 100; // NO -- the (int) truncates the floating
// quotient back to 0

No Boolean — Use int


C does not have a distinct boolean type– int is used instead. The language treats integer 0 as
false and all non-zero values as true. So the statement…

i = 0;
while (i - 10) {
...

will execute until the variable i takes on the value 10 at which time the expression (i – 10)
will become false (i.e. 0). (we’ll see the while() statement a bit later)

Mathematical Operators
C includes the usual binary and unary arithmetic operators. See the appendix for the table
of precedence. Personally, I just use parenthesis liberally to avoid any bugs due to a
misunderstanding of precedence. The operators are sensitive to the type of the operands. So
division (/) with two integer arguments will do integer division. If either argument is a
float, it does floating point division. So (6/4) evaluates to 1 while (6/4.0) evaluates to 1.5 —
the 6 is promoted to 6.0 before the division.

+ Addition
- Subtraction
/ Division
* Multiplication
% Remainder (mod)

Unary Increment Operators: ++ —


The unary ++ and — operators increment or decrement the value in a variable. There are
"pre" and "post" variants for both operators which do slightly different things (explained
below)

var++ increment &quot;post&quot; variant


++var increment &quot;pre&quot; variant
var-- decrement &quot;post&quot; variant
--var decrement &quot;pre&quot; variant
int i = 42;
i++; // increment on i
// i is now 43
i--; // decrement on i
// i is now 42

Pre and Post Variations


The Pre/Post variation has to do with nesting a variable with the increment or decrement
operator inside an expression — should the entire expression represent the value of the
variable before or after the change? I never use the operators in this way (see below), but an
example looks like…

int i = 42;
int j;
j = (i++ + 10);
// i is now 43
// j is now 52 (NOT 53)
j = (++i + 10)
// i is now 44
// j is now 54

C Programming Cleverness and Ego Issues


Relying on the difference between the pre and post variations of these operators is a classic
area of C programmer ego showmanship. The syntax is a little tricky. It makes the code a
little shorter. These qualities drive some C programmers to show off how clever they are. C
invites this sort of thing since the language has many areas (this is just one example) where
the programmer can get a complex effect using a code which is short and dense.

If I want j to depend on i’s value before the increment, I write…

j = (i + 10);
i++;

Or if I want to j to use the value after the increment, I write…

i++;
j = (i + 10);

Now then, isn’t that nicer? (editorial) Build programs that do something cool rather than
programs which flex the language’s syntax. Syntax — who cares?

Relational Operators
These operate on integer or floating point values and return a 0 or 1 boolean value.

== Equal
!= Not Equal
&gt; Greater Than
&lt; Less Than
&gt;= Greater or Equal
&lt;= Less or Equal
To see if x equals three, write something like:
if (x == 3) ...

Pitfall = ==
An absolutely classic pitfall is to write assignment (=) when you mean comparison (==).
This would not be such a problem, except the incorrect assignment version compiles fine
because the compiler assumes you mean to use the value returned by the assignment. This
is rarely what you want

if (x = 3) ...

This does not test if x is 3. This sets x to the value 3, and then returns the 3 to the if for
testing. 3 is not 0, so it counts as "true" every time. This is probably the single most
common error made by beginning C programmers. The problem is that the compiler is no
help — it thinks both forms are fine, so the only defense is extreme vigilance when coding.
Or write "= � ==" in big letters on the back of your hand before coding. This mistake is an
absolute classic and it’s a bear to debug. Watch Out! And need I say: "Professional
Programmer’s Language."

Logical Operators
The value 0 is false, anything else is true. The operators evaluate left to right and stop as
soon as the truth or falsity of the expression can be deduced. (Such operators are called
"short circuiting") In ANSI C, these are furthermore guaranteed to use 1 to represent true,
and not just some random non-zero bit pattern. However, there are many C programs out
there which use values other than 1 for true (non-zero pointers for example), so when
programming, do not assume that a true boolean is necessarily 1 exactly.

! Boolean not (unary)


&amp;&amp; Boolean and
|| Boolean or

Bitwise Operators
C includes operators to manipulate memory at the bit level. This is useful for writing
lowlevel hardware or operating system code where the ordinary abstractions of numbers,
characters, pointers, etc… are insufficient — an increasingly rare need. Bit manipulation
code tends to be less "portable". Code is "portable" if with no programmer intervention it
compiles and runs correctly on different types of computers. The bitwise operations are
typically used with unsigned types. In particular, the shift operations are guaranteed to shift
0 bits into the newly vacated positions when used on unsigned values.

~ Bitwise Negation (unary) &#8211; flip 0 to 1 and 1 to 0 throughout


&amp; Bitwise And
| Bitwise Or
^ Bitwise Exclusive Or
&gt;&gt; Right Shift by right hand side (RHS) (divide by power of 2)
&lt;&lt; Left Shift by RHS (multiply by power of 2)

Do not confuse the Bitwise operators with the logical operators. The bitwise connectives
are one character wide (&, |) while the boolean connectives are two characters wide (&&,
||). The bitwise operators have higher precedence than the boolean operators. The compiler
will never help you out with a type error if you use & when you meant &&. As far as the
type checker is concerned, they are identical– they both take and produce integers since
there is no distinct boolean type.

Other Assignment Operators


In addition to the plain = operator, C includes many shorthand operators which represents
variations on the basic =. For example "+=" adds the right hand side to the left hand side. x
= x + 10; can be reduced to x += 10;. This is most useful if x is a long expression such as
the following, and in some cases it may run a little faster.

person-&gt;relatives.mom.numChildren += 2; // increase children by 2

Here’s the list of assignment shorthand operators…

+=, -= Increment or decrement by RHS


*=, /= Multiply or divide by RHS
%= Mod by RHS
&gt;&gt;= Bitwise right shift by RHS (divide by power of 2)
&lt;&lt;= Bitwise left shift RHS (multiply by power of 2)
&amp;=, |=, ^= Bitwise and, or, xor by RHS

Graphics in C Language
In a C program, first step is to initialize the graphics drivers on the computer. This is done
using the initgraph method provided in graphics.h library. In the next few pages we will
discuss graphics.h library in details. Important functions in graphic.h library will be
discussed in details and samples programs will be provided to show the power of C
programming language.

We will restrict our discussion on Graphics in C Language to 16 bit C programming and


MS DOS environment and 640×480 VGA monitor.

Graphics mode Initialization


First of all we have to call the initgraph function that will initialize the graphics mode on
the computer. initigraph has the following prototype.

void initgraph(int far *graphdriver, int far *graphmode, char far


*pathtodriver);

Initgraph initializes the graphics system by loading the graphics driver from disk (or
validating a registered driver) then putting the system into graphics mode. Initgraph also
resets all graphics settings (color, palette, current position, viewport, etc.) to their defaults,
then resets graphresult to 0.

*graphdriver
Integer that specifies the graphics driver to be used. You can give graphdriver a value using
a constant of the graphics_drivers enumeration type whcih is listed in graphics.h. Normally
we use value as “0” (requests auto-detect). Other values are 1 to 10 and description of each
enumeration type is listed here.
*graphmode
Integer that specifies the initial graphics mode (unless *graphdriver = DETECT). If
*graphdriver = DETECT, initgraph sets *graphmode to the highest resolution available for
the detected driver. You can give *graphmode a value using a constant of the
graphics_modes enumeration type and description of each enumeration type is listed here.

*pathtodriver
Specifies the directory path where initgraph looks for graphics drivers (*.BGI) first.

1. If they’re not there, initgraph looks in the current directory.


2. If pathtodriver is null, the driver files must be in the current directory.

*graphdriver and *graphmode must be set to valid graphics_drivers and graphics_mode


values or you’ll get unpredictable results. (The exception is graphdriver = DETECT.)

After a call to initgraph, *graphdriver is set to the current graphics driver, and *graphmode
is set to the current graphics mode. You can tell initgraph to use a particular graphics driver
and mode, or to auto detect the attached video adapter at run time and pick the
corresponding driver. If you tell initgraph to auto detect, it calls detectgraph to select a
graphics driver and mode.

Normally, initgraph loads a graphics driver by allocating memory for the driver (through
_graphgetmem), then loading the appropriate .BGI file from disk. As an alternative to this
dynamic loading scheme, you can link a graphics driver file (or several of them) directly
into your executable program file.

Here is a simple program that initializes the graphics mode in C programming language and
print the line in graphics mode.

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

int main(void)
{

/* request auto detection */


int gdriver = DETECT, gmode, errorcode;

/* initialize graphics mode */


initgraph(&gdriver, &gmode, "");

/* read result of initialization */


errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */


{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}

/* draw a line */
line(0, 0, getmaxx(), getmaxy());

/* clean up */
getch();
closegraph();
return 0;
}

The below program draws a circle in the current drawing color with its center at (150,150)
and the radius (100) given by radius.

/* Sample program to draw a circle*/


#include<graphics.h>
#include<conio.h>
main()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,""); /* initialization of graphic mode */
circle(150,150,100);
getch();
closegraph(); /* Restore orignal screen mode */
}
/* End of program */

Normally the screen which we see in DOS/Command Mode is in the text mode which
means it is meant for text only. And for graphics we need to initialize graphics mode using
initgraph() method defined in graphics.h?.

circle(x coordinate ,y coordinate , radius);

The circle command takes a X coordinate which means Vertical axis and Y coordinate
which means Horizontal axis. And the last one is the radius of the circle.

closegraph();

This function unloads the graphics drivers and returns the screen back to text mode.
/*A program to draw a space with stars*/
#include<graphics.h>
#include<stdio.h>

main()
{
int gd=DETECT,gm;
int i,x,y;
initgraph(&gd,&gm,"");
line(0,0,640,0);
line(0,0,0,480);
line(639,0,639,480);
line(639,479,0,479);
for(i=0;i<=1000;i++)
{
x=rand()%639;
y=rand()%480;
putpixel(x,y,15);
}
getch();
closegraph();
}
/* End of program */

Here a sample program to illustrate how to use BARS which are used for visual statistics.
The bar is filled using the current fill pattern and fill color. Bar method accepts parameters
i.e. left, top, right and bottom. The setfillstyle() method can be used to fill the bar with a
different color or pattern

#include <graphics.h>
#include <conio.h>

main() {
int gd=DETECT,gm,maxx,maxy,x,y,button;
initgraph(&gd,&gm,"");
line(80,150,200,150);
line(80,150,80,50);
settextstyle(1,HORIZ_DIR,1);
outtextxy(100,153,"<-X axis");
settextstyle(1,VERT_DIR,1);
outtextxy(60,50,"<-Y axis");
bar(100,100,120,150);
bar(130,120,150,150);
getch();
closegraph();
}
Minimum Distance between a Point and a
Line
This article describes the technique and gives the solution to finding the shortest distance
from a point to a line or line segment. The equation of a line defined through two points P1
(x1,y1) and P2 (x2,y2) is

P = P1 + u (P2 – P1)

The point P3 (x3,y3) is closest to the line at the tangent to the line which passes through
P3, that is, the dot product of the tangent and line is 0, thus

(P3 – P) dot (P2 – P1) = 0

Substituting the equation of the line gives

[P3 – P1 – u(P2 – P1)] dot (P2 – P1) = 0

Solving this gives the value of u

Substituting this into the equation of the line gives the point of intersection (x,y) of the
tangent as

x = x1 + u (x2 – x1)
y = y1 + u (y2 – y1)

The distance therefore between the point P3 and the line is the distance between (x,y)
above and P3.

Notes

 The only special testing for a software implementation is to ensure that P1 and P2
are not coincident (denominator in the equation for u is 0)
 If the distance of the point to a line segment is required then it is only necessary to
test that u lies between 0 and 1.
 The solution is similar in higher dimensions.

Source code
//================
//
// DistancePointLine Unit Test
// Copyright (c) 2002, All rights reserved
//
// Damian Coventry
// Tuesday, 16 July 2002
//
// Implementation of theory by Paul Bourke
//
//================
#include <stdio.h>
#include <math.h>
typedef struct tagXYZ
{
float X, Y, Z;
}
XYZ;
float Magnitude( XYZ *Point1, XYZ *Point2 )
{
XYZ Vector;
Vector.X = Point2->X - Point1->X;
Vector.Y = Point2->Y - Point1->Y;
Vector.Z = Point2->Z - Point1->Z;
return (float)sqrt( Vector.X * Vector.X + Vector.Y * Vector.Y +
Vector.Z * Vector.Z );
}
int DistancePointLine( XYZ *Point, XYZ *LineStart, XYZ *LineEnd,
float *Distance )
{
float LineMag;
float U;
XYZ Intersection;
LineMag = Magnitude( LineEnd, LineStart );
U = ( ( ( Point->X - LineStart->X ) * ( LineEnd->X - LineStart->X
) ) +
( ( Point->Y - LineStart->Y ) * ( LineEnd->Y - LineStart->Y ) ) +
( ( Point->Z - LineStart->Z ) * ( LineEnd->Z - LineStart->Z ) ) )
/
( LineMag * LineMag );

if( U < 0.0f || U > 1.0f )


return 0; // closest point does not fall within the line segment
Intersection.X = LineStart->X + U * ( LineEnd->X - LineStart->X );
Intersection.Y = LineStart->Y + U * ( LineEnd->Y - LineStart->Y );
Intersection.Z = LineStart->Z + U * ( LineEnd->Z - LineStart->Z );
*Distance = Magnitude( Point, &Intersection );
return 1;
}
void main( void )
{
XYZ LineStart, LineEnd, Point;
float Distance;
LineStart.X = 50.0f; LineStart.Y = 80.0f; LineStart.Z = 300.0f;
LineEnd.X = 50.0f; LineEnd.Y = -800.0f; LineEnd.Z = 1000.0f;
Point.X = 20.0f; Point.Y = 1000.0f; Point.Z = 400.0f;
if( DistancePointLine( &Point, &LineStart, &LineEnd, &Distance ) )
printf( "closest point falls within line segment, distance =
%f\n", Distance );
else
printf( "closest point does not fall within line segment\n" );
LineStart.X = 0.0f; LineStart.Y = 0.0f; LineStart.Z = 50.0f;
LineEnd.X = 0.0f; LineEnd.Y = 0.0f; LineEnd.Z = -50.0f;
Point.X = 10.0f; Point.Y = 50.0f; Point.Z = 10.0f;
if( DistancePointLine( &Point, &LineStart, &LineEnd, &Distance ) )
printf( "closest point falls within line segment, distance =
%f\n", Distance );
else
printf( "closest point does not fall within line segment\n" );
}

The shortest line between two lines in 3D


Two lines in 3 dimensions generally don’t intersect at a point, they may be parallel (no
intersections) or they may be coincident (infinite intersections) but most often only their
projection onto a plane intersect.. When they don’t exactly intersect at a point they can be
connected by a line segment, the shortest line segment is unique and is often considered to
be their intersection in 3D.

The following will show how to compute this shortest line segment that joins two lines in
3D, it will as a biproduct identify parrallel lines. In what follows a line will be defined by
two points lying on it, a point on line “a” defined by points P1 and P2 has an equation

Pa = P1 + mua (P2 –
P1)

similarly a point on a second line “b” defined by points


P4 and P4 will be written as

Pb = P3 + mub
(P4 – P3)

The values of mua and mub range from negative to positive infinity. The line segments between P1
P2 and P3 P4 have their corresponding mu
between 0 and 1.

There are two approaches to finding the shortest line segment between lines “a” and “b”.
The first is to write down the length of the line segment joining the two lines and then find
the minimum. That is, minimize the following
|| Pb – Pa ||2

Substituting the equations of the lines gives

|| P1 – P3 + mua (P2 –
P1) – mub (P4 – P3) ||2

The above can then be expanded out in the (x,y,z) components. There are conditions to be
met at the minimum, the derivative with respect to mua and mub must be zero. Note: it is
easy to convince
oneself that the above function only has one minima and no other minima or maxima.
These two equations can then be solved for mua and mub, the actual intersection points
found by substituting the values of mu into the original equations of the line.

An alternative approach but one that gives the exact same equations is to realize that the
shortest line segment between the two lines will be perpendicular to the two lines. This
allows us to write two equations for the dot product as

(Pa – Pb) dot (P2 – P1) = 0

(Pa – Pb) dot (P4 – P3) = 0

Expanding these given the equation of the lines

( P1 – P3 + mua (P2 –
P1) – mub (P4 – P3) ) dot
(P2 – P1) = 0

( P1 – P3 + mua (P2 –
P1) – mub (P4 – P3) ) dot
(P4 – P3) = 0

Expanding these in terms of the coordinates (x,y,z) is a nightmare but the

result is as follows

d1321 + mua d2121 – mub


d4321 = 0

d1343 + mua d4321 – mub


d4343 = 0

where
dmnop = (xm – xn)(xo –
xp) + (ym – yn)(yo – yp)
+ (zm – zn)(zo – zp)

Note that dmnop = dopmn

Finally, solving for mua gives

mua = ( d1343 d4321 – d1321


d4343 ) / ( d2121 d4343 – d4321
d4321 )

and backsubstituting gives mub

mub = ( d1343 + mua d4321 )


/ d4343

typedef struct {
double x,y,z;
} XYZ;

/*
Calculate the line segment PaPb that is the shortest route
between
two lines P1P2 and P3P4. Calculate also the values of mua and
mub where
Pa = P1 + mua (P2 - P1)
Pb = P3 + mub (P4 - P3)
Return FALSE if no solution exists.
*/
int LineLineIntersect(
XYZ p1,XYZ p2,XYZ p3,XYZ p4,XYZ *pa,XYZ *pb,
double *mua, double *mub)
{
XYZ p13,p43,p21;
double d1343,d4321,d1321,d4343,d2121;
double numer,denom;

p13.x = p1.x - p3.x;


p13.y = p1.y - p3.y;
p13.z = p1.z - p3.z;
p43.x = p4.x - p3.x;
p43.y = p4.y - p3.y;
p43.z = p4.z - p3.z;
if (ABS(p43.x) < EPS && ABS(p43.y) < EPS && ABS(p43.z) <
EPS)
return(FALSE);
p21.x = p2.x - p1.x;
p21.y = p2.y - p1.y;
p21.z = p2.z - p1.z;
if (ABS(p21.x) < EPS && ABS(p21.y) < EPS && ABS(p21.z) <
EPS)
return(FALSE);

d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z;


d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z;
d1321 = p13.x * p21.x + p13.y * p21.y + p13.z * p21.z;
d4343 = p43.x * p43.x + p43.y * p43.y + p43.z * p43.z;
d2121 = p21.x * p21.x + p21.y * p21.y + p21.z * p21.z;

denom = d2121 * d4343 - d4321 * d4321;


if (ABS(denom) < EPS)
return(FALSE);
numer = d1343 * d4321 - d1321 * d4343;

*mua = numer / denom;


*mub = (d1343 + d4321 * (*mua)) / d4343;

pa->x = p1.x + *mua * p21.x;


pa->y = p1.y + *mua * p21.y;
pa->z = p1.z + *mua * p21.z;
pb->x = p3.x + *mub * p43.x;
pb->y = p3.y + *mub * p43.y;
pb->z = p3.z + *mub * p43.z;

return(TRUE);
}

Graphics Libraray in C/C++


Programming
Graphics library provided by borland C is most widely used library for graphics
programming. Mostly this graphics library is restricted to be used under 16 bit C
programming and MS DOS environment. As discussed earlier that first of all you need to
initialize the graphics drivers on the computer. This is done using the initgraph() method
provided in graphics.h library. graphics.h is used to include the reference to the graphics
library, but actual graphics library can be found in lib directory with the name of
graphics.lib. In Dev C++ there is no default graphics library, but there are some third party
graphics libraries to be used with Dev C++. You can download this library here, after
downloading the library you can read through the manual and copy all the files at their
desired locations. Also you will have to add reference to this graphics library in your
projects or programs.

Adding the graphics.h in your C programs


If you are using borland C/C++ compiler to program, then you will have to follow these
simple steps in ordered to get your C or C++ program running in graphics mode.
 First you will need to add #include reference at the top of you C/C++ program.
 Next step is to initialize the graphics environment. This can be achieved using the
function

void far initgraph(int far *driver, int far *mode, char far
*path)

 Here path is the actual path to the graphics library. You can give the path to this
library by giving the complete path, like “C:\\TC\\BGI”, where BGI is the graphics
library directory.
 After initializing the graphics mode you can check for any error which may happen
while initializing the graphics mode. The function used to find out any errors is int
errorcode = graphresult() which returns the error code for the specific error.
 If you pass this errorcode to grapherrormsg() function the, it will return the
complete description of the error message. And if the errorcode==grOk the you are
on the way to develop your first graphics program using C/C++.

If you are using Dev C++ compiler for your graphics programs then you can follow these
simple steps to configure your environment for graphics programming.

Simple graphics functions


I am providing few functions here with some description to make you start with graphics
programming. I have posted the complete description with a demo C/C++ graphics program
at my C and C++ Programming Blog. You can find my blog here, there are three parts of
the posts about graphics.h library. First part of the post discusses the necessary functions to
get the program ready to draw shapes and styles, second post provides description of
necessary functions to draw different shapes and fill them with colors or textures. And the
last part is a sample program to demonstrate that how you can write programs in graphics
mode.

Function circle

Draws the circle on the screen using a point(x,y) and the radius for the circle.

void far circle(int x, int y, int radius)

Function line

This function draws a line in the graphics mode.

void far line(int startx, int starty, int endx, int endy)
Function outtext

Displays a text string on the grpahics screen.

void far outtext(char far *str)

Function outtextxy

Displays the text at a specified position in graphics mode.

void far outtext(int x, int y, char *str)

Function rectangle

Draws a rectangular box on the screen using the points given in the parameters.

void far rectangle(int left, int top, int right, int bottom)

What is a Function?
A function is a block of code that has a name and it has a property that it is reusable i.e. it
can be executed from as many different points in a C Program as required.

Function groups a number of program statements into a unit and gives it a name. This unit
can be invoked from other parts of a program. A computer program cannot handle all the
tasks by it self. Instead its requests other program like entities – called functions in C – to
get its tasks done. A function is a self contained block of statements that perform a coherent
task of same kind

The name of the function is unique in a C Program and is Global. It means that a function
can be accessed from any location with in a C Program. We pass information to the
function called arguments specified when the function is called. And the function either
returns some value to the point it was called from or returns nothing.

We can divide a long C program into small blocks which can perform a certain task. A
function is a self contained block of statements that perform a coherent task of same kind.

Structure of a Function
There are two main parts of the function. The function header and the function body.

int sum(int x, int y)


{
int ans = 0; //holds the answer that will be returned
ans = x + y; //calculate the sum
return ans //return the answer
}

Function Header
In the first line of the above code

int sum(int x, int y)

It has three main parts

1. The name of the function i.e. sum


2. The parameters of the function enclosed in parenthesis
3. Return value type i.e. int

Function Body
What ever is written with in { } in the above example is the body of the function.

Function Prototypes
The prototype of a function provides the basic information about a function which tells the
compiler that the function is used correctly or not. It contains the same information as the
function header contains. The prototype of the function in the above example would be like

int sum (int x, int y);

The only difference between the header and the prototype is the semicolon ; there must the
a semicolon at the end of the prototype.

Functions in C/C++ Programming


Functions groups a number of program statements into a unit and gives it a name. This unit
can be invoked from other parts of a program. A computer program cannot handle all the
tasks by it self. Instead its requests other program like entities – called functions in C – to
get its tasks done. A function is a self contained block of statements that perform a coherent
task of same kind. e.g
Simple Functions
Our first example demonstrates a simple function those purpose is to print a line of 45
asterisks.The example program generates a table , and lines of asterisks are used to make
the table more readable. Here”s the listing for Table:

// table .cpp
// demonstrates simple function
# include
using namespace std;
void starline( );
into main ()
{
starline ( );
cout << "Data type Range" << endl;
starline ( );
cout << "char -128 to 127 " << endl
<< "short -32 ,768 to 32,767"<< endl
<< "int system independent: << endl
<< " long q-2,147,483,648 to 2,147,483,647" << endl;
starline ( );
return 0;
}
//""""""""""""""""""""""""..
//starline ( )
// function defintion
void starline ( )
{
for(into j=0;j<45; j++)
cout << "*" ;
cout << endl;
}
The output from the program looks like this
*************************************
Data type Range
*************************************
Char -128 to 127
Short -32,768 to 32,767
Into system dependent
Double -2,147,483,648 to 2,147,483,647
*************************************

Why we use Functions”


The most important reason to use functions is to aid in the conceptual organization of a
program.
Another reason to use functions is to reduce program size. Any sequence of instructions
that appears in program more than once is a candidate for being made into a function. The
function”s code is stored in only one place in memory, even though the function is executed
many times in the course of the program.

Two reasons
1. Writing functions avoids rewriting the same code over and over. Suppose that there
is a section of code in a program that calculates area of a triangle. If, later in the
program we want to calculate the area of a different triangle we wont like to write
the same instructions all over again. Instead we would prefer to jump to a “section
of code” that calculates area and then jump back to the place from where you left
off. This section of code is nothing but a function.
2. Using functions it becomes easier to write programs and keep track of what they are
doing. If the operation of a program can be divided in to separate activities, and
each activity placed in a different function, then each could be written and checked
more or less independently. Separating the code in to modular functions also makes
the pro-gram easier to design and understand.

Function Declaration
Just as you can”t use a variable without first telling the compiler what it is, you also can”t
use a functions without telling the compiler about it, There are two ways to do this . The
approach we show here is to declare the function before it is called. The other approach is
to define it before it”s called. ; we”ll examine that next.) in the Table program, the
functions starline() is declared in the line.

void starline ( );

The declaration tells the compiler that at some later point we plan to present a function
called starline. The keyword void specifies that the function has no return value, and the
empty parentheses indicate that it takes no arguments.

Notice that the function declarations is terminated with a semicolon It is a complete


statement in itself.

Function declarations are also called prototypes, since they provide a model or blueprint for
the function. They tell the compiler,” a function that looks like this is coming up later in the
program, so it”s all right if you see references to it before you see the function itself.”

Calling the Function


The function is called (or invoked) three times from main (). Each of the three calls look
like this:

Starline();

This is all we need to call a function name,followed by parentheses. The syntax of the call
is very similar to that of declaration, except that the return type is not used. A semicolon
terminates the call. Executing the call statement causes the function to execute; that is,
control is transferred to the function, the statement in the function definition are executed,
and then control returns
to the statement following the function call.

Function Definition
Finally, we come to the functions its self, which is referred to as the functions definition,
The definition contains the actual code for the function. Here’s the definition for starline( ) .

void starline ( )
{
for ( intj=0, j &lt; 45; j++ )
cout &lt;&lt; "*" ;
cout &lt;&lt; endl;
}

The definition consists of a line called the decelerator, followed by the function body , The
function body is composed of the statements that make up the function, delimited by
braces.

The decelerator must agree with the declaration: It must use the same function name, have
the same argument types in the same order( if there are arguments), and have the same
return type.

Notice that a semicolon does not terminate the decelerator. Figure shows the syntax of the
function declaration, function call, and function definition.

When the function is called, control is transferred to the first statement in the functions
body. The other statements in the function body are then executed, and when the closing
brace is encountered, control returns to the calling program.

There are basically two types of functions


1. Library functions Ex. printf ( ), scanf ( ) etc.
2. User defined function e.g the function message mentioned above.
The following point must be noted about functions (i) C program is a collection of
one or more functions (ii) A function gets called when the function name is
followed by a semicolon for e.g.

main ( ){

message ( );

3. Function is defined when function name is followed by a pair of braces in which


one or more statements may be present for e.g.

message ( ){

statement 1;

statement2;

statement 3;

4. Any function can be called from any other function even main ( ) can be called from
other functions. for e.g.

main ( ){

message ( );

message ( )

printf (” \n Hello”);

main ( );

5. A function can be called any number of times for eg.

main (){
message ( );

message ( );

message ( )

printf (“\n Hello”);

6. The order in which the functions are defined in a program and the order in which
they get called need not necessarily be same for e.g.

main ( );{

message 1 ( );

message 2 ( );

message 2 ( )

printf (“\n I am learning C”);

message 1 ( )

printf ( “\n Hello “);

7. A function can call itself such a process as called “recursion”.


8. A function can be called from other function, but a function cannot be defined in an-
other function. These the following program code would be wrong, since Argentina
is being defined inside another function main ( ).
main ( ){

printf (“\n I am in main”);

argentina ( )

printf {“\n I am in argentina”);

9. Any C program contains at least one function.


10. If a program contains only one function, it must be main( ).
11. In a C program if there are more than one functional present then one of these
functional must be main( ) because program execution always begins with main( ).
12. There is no limit on the number of functions that might be present in a C program.
13. Each function in a program is called in the sequence specified by the function calls
in main( )
14. After each function has done its thing, control returns to the main( ), when main( )
runs out of function calls, the program ends.

Functions declaration and prototypes Any function by default returns an int value. If we
desire that a function should return a value other than an int, then it is necessary to
explicitly mention so in the calling functions as well as in the called function. for e.g

main ( )
{
float a,b,
printf ("\n Enter any number");
scanf ("\% f", &amp;a );
b = square (a)
printf ("\n square of % f is % f", a,b);
}
square (float X)
{
float y;
Y = x * x;
return (y);
}
the sample run of this program is Enter any number 2.5 square of 2.5 is 6.000000 Here 6 is
not a square of 2.5 this happened because any C function, by default, always returns an
integer value. The following program segment illustrates how to make square ( ) capable of
returning a float value.
main ( )
{
float square ( );
float a, b;
printf ("\n Enter any number ");
scanf ("%f" &amp;a);
b = square (a);
printf ("\n square of % f is % f, " a,
b);
}
float square (float x)
{
float y;
y= x *x;
return ( y);
}
sample run Enter any number 2.5 square of 2.5 is 6.2500000

PASSING ARGUMENTS TO FUNCTION


An argument is a piece of data (an into value, for exp) passed from a program to the
function. Arguments allow a function to operate with different values, or even to do
different things, depending on the requirements of the program calling it.

PASSING CONSTANTS
As an exp, let”s suppose we decide that the starline ( ) function in the last exp is too rigid.
Instead of a function that always prints 45 asterisks, we want a function that will print any
character any number of times

Here is a program, TABLEARG, that incorporates just such a function. We use arguments
to pass the character to be printed and the number of times to print it .

// tablearg.cpp
// demonstrates funciotn arguments
# include < iostream>
using namespace std;
void repchar(char, int); //function declaration
in main ( )
{
repchar(" " " , 43);
cout << " Data type Range" < endl;
repchar ( "=", 23); //call to function
cout << " char -128 to 128" < endl
<< "short -32,768 to 32,767" < endl
<< " int system dependent " << endl
<< " double -2, 147,483,648 to 2,147,483,647" << endl;
repchar("-" , 43);
return 0;
}//""""""""""""""""""""""""""".
//repchar ( )
// funtion definiton
void repchar ( char ch , int n )
{
for ( into j=0; j<n; j++) //function body
cout < ch;
cout << endl;
}

The new function is called repchar ( ), Its declaration looks like this

Void repchar ( char, int); // declaration specifies data types

The items in the parentheses are the data types of the argument that will be sent to repchar(
): char and int.

In a function call, specific values—– constants in this case “are inserted in the appropriate
place in the parentheses:

Repchar(“-“, 43); // function call specifies actual values

This statement instructs repchar ( ) to print a line of 43 dashes. The values supplied in the
call must be of the types specified in the declaration: the first argument, the “-” character ,
must be of type[ char; and the second arguments, the number 43 must be of type int. The
types in the definition must also agree.

The next call to repchar ( ).

Repchar (“=” , 23);

Tells it to print a line of 23 equal signs. The third call again prints 43 dashes. Here”s the
output form TABLEARG.

“”””””””””””””””””””””””””””””

data type Range

===============
char -128 to 127

short -32,768 to 32,767

int system dependent

long -2,147,483,648to 2,147,483,647

The calling program supplies arguments such as “-” and 43 ,to the function. The variables
used within the functions to hold the argument values are called parameters; in repchar()
the are ch and n.These decelerator names ch and n, are used in the functions as they were
normal variables. Placing them in the decelerators is equivalent to defining them with the
statements like

Char ch;

Int n;l

When the function is called, its parameters are automatically initialized to the values passed
by the calling program.

PASSING VARIABLES
In the tablearg example the arguments were constants “-” 43,and so on. Lets look at an
example where variables, instead of constants ,are passed as arguments. This
program,VARARG,incorporates the same repchar()function as did tablearg,but let the user
specify the character and the number of times it should be repeated.

//vararg.cpp
//demonstrates variable arguments
# include <iostream>
using namespace std;
void repchar(char,int);

int main()
{
char chin;
int nin;
cout<<"enter a character:";
cin>>nin;
cout<<"enter a number of times to repeat it:";
cin>>nin;
repchar (chin,nin);
return 0;
}
//"""""""""""""""""""""""""""
//repchar ()
//function definition
void repchar(char ch,int n)
{
for(int j=0,j<n;j++)
cout<<ch;
cout<<end1;
}

Here is some sample interaction with var arg

Enter a character:+

Enter number of times to repeat it:20

++++++++++++++++

Here chin and nin in main() are used as arguments to repchar():

rephar()(chin,nin); // function call

The data types of variables used as arguments must match those specified in the function
declaration and definition, just as they must for constant. That is chin must be a char and
nin must be an int.

RETURNING VALUES FROM


FUNCTIONS
When a function completes its execution, it can return a single value to the calling program.
Usually this return value consists of an answer to the problem the function has solved. The
next example demonstrates a function that returns a weight in kg after being given a weight
in ponds.

//convert.cpp
//demonstrates return values, converts a pound to kg
#include <iostream>
using namespace std;
float lbstokg(float);

int main()
{
float lbs,kgs;
cout<<"enter your weight in pounds:";
cin>>lbs;
kgs=lbstokg(lbs);
cout<<"your weight in kg is "<<kgs<<end1;
return 0;
}
//"""""""""""""""""..
//lbstokg()
//converts pounds to kg
float lbstokg(float pounds)
{
float kg=0.453592*pounds;
return kg;
}

When a function returns a value. The data type of this value must be specified. The function
declaration does this by placing the data types, float in this case, before the function name
in the declaration and the definition. Functions in earlier program examples returned no
value, so the return type was void. In the above function lbstokg() returns type float, so the
declaration is

Float lbstokg(float);

The first float specifies the return type. The float in parentheses s specifies that an argument
to be passed to lbstokg() is also of type float.

CALL BY VALUE
In the preceding examples we have seen that whenever we called a function we have
always passed the values of variables to the called function. Such function calls are called
“calls by value” by this what it meant is that on calling a function we are passing values of
variables to it. The example of call by value are shown below ;

sum = calsum (a, b, c); f = factr (a);

In this method the value of each of the actual arguments in the calling function is copied
into corresponding formal arguments of the called function. With this method the changes
made to the formal arguments in the called function have no effect on the values of actual
argument in the calling function. The following program illustrates this:

main ( )
{
int a = 10, b=20;
swapy (a,b);
printf ("\na = % d b = % d", a,b);
}
swapy (int x, int y)
{
int t;
t = x;
x = y;
y = t;
printf ( "\n x = % d y = % d" , x, y);
}

The output of the above program would be; x = 20 y = 10 a =10 b =20

CALL BY REFERENCE
In the second method the addresses of actual arguments in the calling function are copied in
to formal arguments of the called function. This means that using these addresses we would
have an access to the actual arguments and hence we would be able to manipulate them the
following program illustrates this.

main ( )
{
int a = 10, b =20,
swapv (&amp;a, &amp;b);
printf ("\n a = %d b= %d", a, b);
}
swapr (int **, int * y)
{
int t;
t = *x
*x = *y;
*y = t;
}
The output of the above program would be a = 20 b =10

Pointers

Each memory location that we use to store the data hase an address in computre memory
(RAM). Computer Hardware i.e. CPU uses this addess to reference to a particular data
item. A pointer is a variable that stores the address of another variable.

A pointer is a variable that represents the location of a data item, such as a variable or an
array element. Pointers are used frequently in C, as they have a number of useful
applications. For example, pointers can be used to pass information back and forth between
a function and its reference point. Pointers provide a way to return multiple data items from
a function via function arguments to
be specified as arguments to a given function.

Pointers are also closely associated with arrays and therefore provide an alternate way to
access individual array elements.

Within the computer?s memory, every stored data item occupies one or more adjacent
memory cells. The number of memory cells required to store a data item depends on the
type of data item. For example, a single character will be stored in 1 byte of memory
integer usually requires two adjacent bytes, a floating point number may require four
adjacent bytes.

Declaring a Pointer
A pointer is declared just like we declare a variable. There is only one difference in
declaration is that we add an asterisk * infront of it to indicate that it’s a variable which is a
pointer. For example

int* i;
long* y;

you can also declare the pointers as

int *i;
long *y;

How Pointer work?


Lets write an example to demonstrate the use of pointers.

int num = 10;


int *pnum;
pnum = &amp;num;

You can also initialize the pointer to the default null value.

int* pnum = NULL;

Here is a simple example that demonstrates the different aspects of the pointer operations.

#include &lt;stdio.h&gt;
int main(void){
int num=10;
int* pnum=NULL;
pnum = &amp;num;
*pnum += 20;
printf("\nNumber = %d", num);
printf("\nPointer Number = %d", *pnum);
return 0;
}

THE and * Operators


A pointer is a variable that represents the location of a data item, such as a variable or an
array element. Pointers are used frequently in C, as they have a number of useful
applications. For example, pointers can be used to pass information back and forth between
a function and its reference point. Pointers provide a way to return multiple data items from
a function via function arguments to be specified as arguments to a given function.

Pointers are also closely associated with arrays and therefore provide an alternate way to
access individual array elements.

Within the computer?s memory, every stored data item occupies one or more adjacent
memory cells. The number of memory cells required to store a data item depends on the
type of data item. For example, a single character will be stored in 1 byte of memory
integer usually requires two adjacent bytes, a floating point number may require four
adjacent bytes.

Suppose V is a variable that represents some particular data item. The compiler will
automatically assign memory cells for this data item. The data item can be accessed if we
know the location of the first memory cell. The address of V?S memory location can be
determined by the expression & V, where & is a unary operator, called the address
operator, that evaluates the address of its operand.

Now let us assign the address of V to another variable, PV. Thus

PV = &amp; V

This new variable is called a pointer to V, since it “Points” to the location where V is stored
in memory. Remember, however, that PV represents V?s address, not its value. Thus, Pv is
called pointer variable.

address of V value of V
PV V

Relationship between PV and V (where PV = & V and V = * PV)


The data item represented by V can be accessed by the expression *PV where * is a unary
operator, that operates only on a pointer variable. Therefore, PV and V both represent the
same data item. Furthermore, if we write PV = &V and U = PV, then u and v will both
represent the same values i.e., the value of V will indirectly be assigned to u.

Example :

int quantity = 179 ;

The statement instructs the system to find a location for the integer quantity and puts the
value 179 in that location. Let us reassume that the system has chosen the address location
5000 for quantity.

Quantity Variable
179 Value
5000 Address

Representation of a Variable
Remember, since a pointer is a variable, its value is also stored in the memory in another
location.

The address of P can be assumed to be 5048.

Variable Value Address


Quantity 179 5000
P 5000 5048

DYNAMIC MEMORY ALLOCATION


C language requires that the number of elements in an array should be specified at compile
time. Our initial judgment of size, if it is wrong, may cause failure of the program or
wastage of memory space. Many languages permit a programmer to specify an array?s size
at run time. Such languages take the ability to calculate and assign, during execution, the
memory space required by the variables in a program. The process of allocating memory at
run time is known as dynamic memory allocation. The library functions used for allocating
memory are :

Function ———— Task


Malloc() ————Allocates requested size of bytes and returns a pointer to the first byte of
the allocated space
Calloc() ———— Allocates space for an array of element, initializes them to zero and then
returns a pointer to the memory
Memory Allocation Process
Let us first look at the memory allocation process associated with a C program. Fig. below
shows the conceptual view of storage of a C program in memory.

 Local Variable Stack


 Free Memory Heap
 Global Variables
 C Program instructions

The program instructions and global and static variables are stored in a region known as
permanent storage area and the local variables are stored in another area called stack. The
memory space that is located between these two regions is available for dynamic allocation
during execution of the program. The free memory region is called the heap. The size of the
heap keeps changing when program is executed due to creation and death of variables that
are local to functions and blocks. Therefore, it is possible to encounter memory “overflow”
during dynamic allocation process. In such situations, the memory allocations functions
mentioned above returns a NULL pointer.

ALLOCATING A BLOCK OF MEMORY


A block of memory may be allocated using the function malloc. The malloc function
reserves a block of memory of specified size and returns a pointer of type void. This means
that we can assign it to any type of pointer. It takes the following form;

Ptr = ( Cast type * ) malloc ( byte size ) ;

Ptr is a pointer of type cast type. The malloc returns a pointer (of cast type) to an area of
memory with size byte – size.

Example :
X = ( int * ) malloc ( 100 * size of ( int )) ;

On successful execution of this statement, a memory space equivalent to “100 times the
size of an int” bytes is reserved and the address of the first byte of the memory allocated is
assigned to the pointer X of type int.

Similarly, the statement


Cptr = ( char * ) malloc ( 10 ) ;

allocates 10 bytes of space for the pointer cptr of type char. This is illustrated below :

Cptr
Address of
first byte
10 bytes of Space

Remember, the malloc allocates a block of adjacent bytes. The allocation can fail if the
space in the heap is not sufficient to satisfy the request. If it foils, it returns a NULL. We
should therefore check whether the allocation is successful before using the memory
pointer.

Example :

Write a program that uses a table of integers whose size will be specified interactively at
run time. Program :

# include &lt; Stdio.h &gt;


# include &lt; Stdlib. h &gt;
# define NULL O
main ( )
{
int * P, * table ;
int size ;
Printf ( "In What is the size of table ?" ) ;
Scanf ( " % d", size ) ;
Printf ( "In" ) ;
if (( table = (int * ) malloc (size *size of (int)) = = NULL )
{
Printf ("No space available \ n") ;
exit ( i ) ;
}
Printf ("\n address of the first byte is % 1d\n", table );
Printf("\n Input table values");
for ) P = table; P &lt; table+size; P++)
Scanf ("%d", *P );
for ( P = table + size-1; P &gt; = table; P-- )
Printf ("%d is stored at address %1d\n", *P, P );
}

Allocating Multiple Blocks of Memory


Calloc is another memory allocation function that is normally used for requesting memory
space at runtime for storing derived data types such as arrays and structures. While malloc
allocates a single block of storage space, calloc allocates multiple blocks of storage, each of
the same size, and then allocates all bytes to O. The general form of calloc is :

Ptr = (Cast type * ) Calloc ( n, elem-size );


The above statement allocates contiguous space for n blocks, each of size elem-size bytes.
All bytes are initialized to zero and a pointer to the first byte of the allocated region is
returned. If there is not enough space, a NULL pointer is returned.

The following program allocates space for a structure variable.

# include &lt; Stdio. h;


# include &lt; Std lib.h;
Struct Student
{
char name (25);
float age;
long int num;
};
typedef struct student record ;
record * ptr ;
int class-size = 30 ;
Ptr = ( record * ) calloc ( class-size,
size of ( record ));
- - - -- - -record is of type struct student having three number :

name, age and num. The calloc allocates memory to hold data for 30 such records. We
should check if the requested memory has been allocated successfully before using the ptr.
This may be done as follows:

if ( ptr = = NULL ){
Printf ( “Available memory not sufficient”) ;
exit ( 1 ) ;
}

POINTERS VS. ARRAY


When an array is declared, the compiler allocates a base address and sufficient amount of
storage to contain all the elements of the array in contiguous memory locations. The base
address is the location of the first element (index 0) of the array. The compiler also defines
the array name as a constant pointer to the first element suppose we declare an array X as

follows :

Static int X [ 6 ] = { 1, 2, 3, 4, 5, 6 } ;

Suppose the base address of X is 1000 and assuming that each integer requires two bytes,
the five elements will be stored as follows :

ELEMENTS x[0] x[1] x[2] x[3] x[4] x[5]


VALUE 1 2 3 4 5 6

Address 1000 1002 1004 1006 1008 1010

BASE ADDRESS

The name X is defined as a constant pointer pointing to the first clement, x [0] and
therefore the value of X is 1000, the location whose X[0] is stored. That is ;

X = & x[0] = 1000

If we declare P as an integer pointer, then we can make the pointer P to point to the array X
by

the following assignment :

P=X;

This is equivalent to P = & X[0] ;

Now we can access every value of x using P+ + to more from one element to another. The
relationship between P and X is shown below :

P = &amp; x[0] ( = 1000)


P+1 = &amp; x[1] ( = 1002)
P+2 = &amp; x[2] ( = 1004)
P+3 = &amp; x[3] ( = 1006)
P+4 = &amp; x[4] ( = 1008)
P+5 = &amp; x[5] ( = 1010)

The address of an element is calculated using its index and the scale factor of the data type.
For instance,

address of X[3] = base address + (3 X Scale factor of int) = 1000 + (3 x 2) = 1006

When handling array, instead of using array indexing, we can use pointers to access array
elements. Note that X(P+3) gives the value of X[3]. The pointer accessing method is more
faster than array indexing.

POINTERS AND FUNCTIONS

When an array is passed to a function as an argument, only the address of the first element
of the array is passed, but not the actual values of the array elements. The function uses this
address for manipulating the array elements. Similarly, we can pass the address of a
variable as an argument to a function in the normal fashion. When we pass addresses to a
function, the parameters receiving the addresses should be pointers. The process of calling
function using pointers to pass the address of variable is known as call by reference. The
function which is called by reference can change the value of the variable used in the call.
eg.

main ( ) {
int X ;
X = 40 ;
Change ( &amp; X ) ;
Printf ( " %d", X ) ;
{
Change ( int * P )
{
* P = * P + 10 ;
}

When the function change is called, the address of the variable X, not its value, is passed
into the function change ( ). Inside change ( ), the variable P is declared as a pointer and
therefore P is the address of the variable X. The statement,

* P = * P + 10 ;

means add 10 to the value stored at address P. Since P represents the address of X, the
value of X is changed from 50. Therefore, the output of the program will be 50 not 40.
These, call by reference provides a mechanism by which the function can change the stored
values in the calling function.

Unions and Structures


What is a Union?
A union is a user defined variable which may hold members of different sizes and type.
Union uses a single memory location to hold more than one variable. We can use the
unions in the following locations.

1. Share a single memory location for a variable myVar1 and use the same location for
myVar2 of different data type when myVar1 is not required any more.
2. Use it if you want to user, for example, a long variable as two short type variables.
3. We don’t know what type of data is to be passed to a function, and you pass union
which contains all the possible data types.

Defining a Union
Union can be defined by the keyword union.

union myUnion{
int var1;
long var2;
};

Here we have defined a union with the name myUnion and it has two members i.e. var1 of
type int and var2 of type long

Declaring the Union


We can declare the union in various ways. By taking the above example we can declare the
above defined union as.

union myUnion{
int var1;
long var2;
}newUnion;

So newUnion will be the variable of type myUnion. We can also declare the union as

myUnion newUnion;

Initializing the Union


We can initialize the union in various ways. For example

union myUnion{
int var1;
long var2;
}newUnion={10.5};

or we can initialize it as

newUnion.var1= 10;

In later stages we can also initialize the var2 as well but this will over write the var1 value.
Normally when we declare the union it is allocated the memory that its biggest member can
occupy. So here in our example newUnion will occupy the memory which a long type
variable can occupy.

What is a Structure
A structure is a convenient tool for handling a group of logically related data items.
Structure help to organize complex data is a more meaningful way. It is powerful concept
that we may after need to use in our program Design.

A structure is combination of different data types. Lets take the example of a book, if we
cant to declare a book we will be thinking about the name, title, authors and publisher of
the book and publishing year. So to declare a book we need to have some complex data
type which can deal with more than one data types. Lets declare a Book.

Defining a Structure
We can declare a structure to accommodate the book.

struct Book
{
char Name[100];
char Author[100];
char Publisher[80];
int Year;
};

The keyword struct defines a book, and each line with in the braces defines the elements of
the Book. Now when ever we create an instance of Book it will have all the elements of the
structure i.e. Name, Author, Publisher and Year.

Declaring a Structure
We can declare the structure just like union.

Book CProgrammingBook;

Initializing a Structure
Lets initialize the structure variable CProgrammingBook.

Book CProgrammingBook =
{
"Beginning VC++ 6",
"Ivor Horton",
"Wrox",
2001
};

Accessing the members of a Structure


We can access all the members of a structure by adding a period after the name of the
structure variable name and then the name of the field we want to access. For example we
want to change the Publish year from 2001 to 2002, we will do
it as

CProgrammingBook.Year = 2002;

STRUCTURE
A structure is a convenient tool for handling a group of logically related data items.
Structure help to organize complex data is a more meaningful way. It is powerful concept
that we may after need to use in our program Design. A structure is combination of
different data types using the & operator, the beginning address of structure can be
determined. This is variable is of type structure, then & variable represent the starting
address of that variable.

STRUCTURE DEFINITION
A structure definition creates a format that may be used to declare structure variables
consider the following example.

Struct book-bank
{
Char title [20];
Char author [15];
int pages;
float price;
};

Here keyword Struct hold the details of four fields these fields are title, author, pages, and
price, these fields are called structure elements. Each element may belong to different types
of data. Here book-bank is the name of the structure and is called the structure tag. It
simply describes as shown below.

Struct book-bank

Title array of 20 characters

Author array of 15 characters

Pages integer

Price float

The general format of a structure definition is as follows


struct teg_name{
data_type member 1;
data_type member 2;
------
------
------
}

ARRAY OF STRUCTURES
Each element of the array itself is a structure see the following example shown below. Here
we want to store data of 5 persons for this purpose, we would be required to use 5 different
structure variables, from sample1 to sample 5. To have 5 separate variable will be
inconvenient.

#include <stdio.h>
main()
{
struct person
{
char name [25];
char age;
};
struct person sample[5];
int index;
char into[8];
for( index = 0; index <5; index ++)
{
print("Enter name;");
gets(sample [index]. name);
printf("%Age;");
gets(info);
sample [index]. age = atoi (info);
}
for (index = 0; index <5; index++)
{
printf("name = %5\n", sample [index].name);
printf("Age = %d \n", sample [index].age);
getch( );
}
}

The structure type person is having 2 elements: Name an array of 25 characters and
character type variable age
USING THE STATEMENT
Struct person sample[5]; we are declaring a 5 element array of structures. Here, each
element of sample is a separate structure of type person. We, then defined 2 variables into
index and an array of 8 characters, info. Here, the first loop executes 5 times, with the value
of index varying from 0 to 4. The first printf statement displays. Enter name gets( ) function
waits for the input string. For the first time this name you enter will go to sample[0]. name.
The second printf display age the number you type is will be 5 stored as character type,
because the member age is declared as character type. The function atoi( ) converts this into
an integer. atoi stands for alpha to integer. This will be store in sample[0] age. The second
for loop in responsible for printing the information stored in the array of structures.

STRUCTURES WITHIN STRUCTURES


Structure with in a structure means nesting of structures. Let us consider the following
structure defined to store information about the salary of employees.

Str uct salary {


char name[20];
char department[10];
int basic_pay;
int dearness_allowance;
int city_allowance;
}
employee;

This structure defines name, department, basic pay and 3 kinds of allowance. we can group
all the items related to allowance together and declare them under a substructure are shown
below:

struct salary
{
char name [20];
char department[10];
str uct
{
int dearness;
int hous_rent;
int city;
}
allowance;
}
employee;
The salary structure contains a member named allowance which itself is a structure with 3
members. The members contained in the inner, structure namely dearness, house_rent, and
city can be referred to as :

employee allowance. dearness


employee. allowance. house_rent
employee. allowance. city

An inner-most member in a nested structure can be accessed by chaining all the concerned.
Structure variables (from outer-most to inner-most) with the member using dot operator.
The following being invalid.

employee. allowance (actual member is missing)


employee. house_rent (inner structure variable is missing)
Passing a Structure as a whole to a Function
Structures are passed to functions by way of their pointers. Thus, the changes made to the
stru #include <stdio.h>

typedef struct
{
char *name;
int acc_no;
char acc_types;
float balance;
} account;

main()
{
void change(account *pt);
static account person = {"David", 4323,?R?, 12.45};
printf("%s %d %c %.2f \n", person.
name,person. acc_type, person. acc_type,person.balance);
change(&person);
printf("%s %d %c %2f \n", person. name, person. acc_type,person.acc-type, person.
balance);
getch( );
}

void change(account *pt)


{
pt - > name = David R";
pt - > acc_no = 1111;
pt - > acc_type = ?c?;
pt - > balance = 44.12;
return;
}
Output

David 4323 R 12.45


David R 1111 c 44.12

. UNIONS
Unions, like structure contain members, whose individual data types may vary. These is
major distinction between them in terms of storage .In structures each member has its own
storage location, where as all the members of a union use the same location. Like
structures, a union can be declared using the keyword union is follows:

union item{
int m;
float x;
char c;
} code;

This declares a variable code of type union them. The union contains them members, each
with a different date type. However, we can use only one of them at a time. This is due to
the fact that only one location is allocated for a union variable, irrespective of its size. The
compiler allocates a piece of storage that is large enough to hold the largest variable type in
the union. In the declaration above, the member x requires 4 bytes which is the largest
among the members. The above figure shown how all the three variables share the same
address, this assumes that a float variable requires 4 bytes of storage. To access a union
member, we can use the same syntax that we as for structure members, that is,

code. m
code. x
code. c are all valid

Member variables, we should make sure that we can accessing the member whose value is
currently storage. For example

code. m = 565;
code. x = 783.65;
printf(“%d”, code. m); would produce erroneous output.

# include <stdio.h>
main( ){
union
{
int one;
char two;
} val;
val.one = 300;
printf("val. one = %d \n", val.one);
printf("val. two = %d \n", val.two);
}

The format of union is similar to structure, with the only difference in the keyword used.
The above example, we have 2 members int one and char two we have then initialized the
member ?one? to 300. Here we have initialized only one member of the union. Using two
printf statements, then we are displaying the individual members of the union val as:

val. one = 300


val. two = 44

As we have not initialized the char variable two, the second printf statement will give a
random value of 44.
The general formats of a union thus, can be shown as.

union tag {
member 1;
member 2;
---
---
member
m;
};

The general format for defining individual union variables:

Storage-class Union tag variable 1, variable 2,………, variable n;

Storage-class and tag are optional variable 1, variable 2 etc, are union variable of type tag.

Declaring union and defining variables can be done at the same time as shown below:

Stroage-calss union teg {


member 1;
member 2;
---
---
- - -member
m;
}
variable 1, variable 2, - - - , variable n;
Comparing Two Stuctures
You can use memcmp(). See man
memcmp for more details. If your structure has pointers, then move them to the
end and do not compare memory area for the pointer. You have to compare pointers
explicitly.

See sample program below.

# include <stdio.h>
# include <conio.h>
struct S{
int i;
char sz[4];
char *ptrC;
}s1, s2, s3;
void compare(void *, void *, int);
#define POPULATE(S,li,lsz,lptr) { S.i=li; memcpy(S.sz,lsz,4); S.sz[3]=0; S.ptrC = lptr; }
char * one = "one";
char * two = "two";
int main(int argc, char* argv[])
{
POPULATE(s1,12,"HI",one);
POPULATE(s2,12,"HI",one);
POPULATE(s3,12,"HI",two);
compare(&s1, &s2 , sizeof(s1) );
compare(&s1, &s3 , sizeof(s1) );
compare(&s1, &s3 , 8 );
return 0;
}
void compare(void *v1, void* v2, int size)
{
if( memcmp( v1, v2, size) == 0 ){
printf("Memory area is same type\n");
}
else{
printf("Memory area is different type\n");
}
return ;
}

The memcmp method needs a bit of extra caution because of memory alignment
considerations.

For example:
struct A
{
int n;
char c;
int m;
};

The memory layout of the struct A will be, on a 32 bit system with 4 byte alignment:

4 bytes for n;
1 byte for c;
3 unused bytes (garbage);
4 bytes for m;

If you use memcmp, it can be that the 4 + 1 + 4 used bytes are identical but that there is a
difference between the 3 garbage bytes. I don’t think in this
case you want your comparison function to return false.

A workaround can be something like:

bool areEqual (struct A a1, struct A a2)


{
struct A t1, t2;
memset (&amp;t1, 0, sizeof(A));
memset (&amp;t1, 0, sizeof(A));
t1 = a1;
t2 = a2;
return !memcmp (&amp;t1, &amp;t2, sizeof(A));
}

If you have pointers in your structures, I suggest that you use a different structure for your
“raw” data and add the pointers later:

struct A
{
int n;
char c;
int m;
};

struct APTR
{
A a;
char* pt;
};
bool areEqualPtr (struct APTR a1, struct APTR a2)
{
if (!areEqual (a1.a, a2.a))
return false;
return !strcpy (a1.pt, a2.pt);
}

Input and Output


First of all we need to learn about streams in C Programming. All C Programming input
and output is done with streams, no matter where input is coming from or where output is
going to. This is the standard way of handling all input and output and has definite
advantages for the programmer. A library package has been evolved which is known as
known as the ?Standard I/O Library? which is used in any C program by using stdio.h
header. Of course, now that we know its importance, it is essential that we understand what
streams are and how they work. First, however, we need to understand exactly what the
terms input and output mean in context of C.

The C programming language provides input and output support using library functions,
which gives an advantage to system designers to tailor their input and output on their own.

What Exactly Is Program Input/Output?


A C program keeps data in random access memory (RAM) while executing. This data is in
the form of variables, structures, and arrays that have been declared by the program. The
question is where did this data come from, and what can the program do with it?

1. Data can come from some location external to the program. Data moved from an
external location into RAM, where the program can access it, is called input. The
keyboard and disk files are the most common sources of program input.
2. Data can also be sent to a location external to the program; this is called output. The
most common destinations for output are the screen, a printer, and disk files.

Input sources and output destinations are collectively referred to as devices. The keyboard
is a device; the screen is a device, and so on. Some devices (the keyboard) are for input
only, others (the screen) are for output only, and still others (disk files) are for both input
and output. Whatever the device, and whether it’s performing input or output, C carries out
all input and output operations by means of streams.

What is a Stream?
A stream is a sequence of characters. More exactly, it is a sequence of bytes of data. A
sequence of bytes flowing into a program is an input stream; a sequence of bytes flowing
out of a program is an output stream. By focusing on streams, we don’t have to worry as
much about where they’re going or where they originated.
The major advantage of streams, therefore, is that input/output programming is device
independent. Programmers don’t need to write special input/output functions for each
device (keyboard, disk, and so on). The program sees input/output as a continuous stream
of bytes no matter where the input is coming from or going to.

Every C stream is connected to a file. In this context, the term file doesn’t refer to a disk
file. Rather, it is an intermediate step between the stream that the program deals with and
the actual physical device being used for input or output. For the most part, the beginning C
programmer doesn’t need to be concerned with these files, because the details of
interactions between streams, files, and devices are taken care of automatically by the C
library functions and the operating system.

Modes of Streams in C Language


C streams can be divided into two modes: text and binary.

Text Stream

A text stream consists only of characters, such as text data being sent to the screen. Text
streams are organized into lines, which can be up to 255 characters long and are terminated
by an end-of-line, or newline, character. Certain characters in a text stream are recognized
as having special meaning, such as the newline character.

Binary Stream

A binary stream can handle any sort of data, including, but not limited to, text data. Bytes
of data in a binary stream aren’t translated or interpreted in any special way; they are read
and written exactly as-is. Binary streams are used primarily with disk files.

Predefined Streams

ANSI C has three predefined streams, also referred to as the standard input/output files. If
you’re programming for an IBM-compatible PC running DOS, two additional standard
streams are available to you. These streams are automatically opened when a C program
starts executing and are closed when the program terminates. The programmer doesn’t need
to take any special action to make these streams available. Table lists the standard streams
and the devices they normally are connected with. All five of the standard streams are text-
mode streams.

The five standard streams.


NAME STREAM DEVICE
stdin Standard Input Keyboard
stdout Standard Output Screen
stderr Standard Error Screen
stdprn* Standard Printer Printer (LPT1)
stdaux* Standard Auxiliary Serial Port (COM1)
(*) Supported only under DOS

Whenever we have to use the printf() or puts() functions to display text on-screen, we use
the stdout stream. Likewise, when we use gets() or scanf() to read keyboard input, we use
the stdin stream. The standard streams are opened automatically, but other streams, such as
those used to manipulate information stored on disk, must be opened explicitly.

Stream functions in C Language


The C standard library has a variety of functions that deal with stream input and output.
Most of these functions come in two varieties: one that always uses one of the standard
streams, and one that requires the programmer to specify the stream.

These functions are listed in table below. This table doesn’t list all of C’s input/output
functions.

The standard library’s stream input/output functions.


Uses One of the Standard Requires a Stream
Description
Streams Name
printf() fprintf() Formatted output
Formatted output with a variable
vprintf() vfprintf()
argument list
puts() fputs() String output
putchar() putc(), fputc() Character output
scanf() fscanf() Formatted input
gets() fgets() String input
getchar() getc(), fgetc() Character input
perror() String output to stderr only

All these functions require that we include STDLIB.H. The function perror() may also
require STDLIB.H. The functions vprintf() and vfprintf() also require STDARGS.H. On
UNIX systems, vprintf() and vfprintf() may also require VARARGS.H. The compiler”s
Library Reference will state whether any additional or alternative header files are needed.

An Example

The short program demonstrates the equivalence of streams.


The equivalence of streams.
/* Demonstrates the equivalence of stream input and output. */
#include &lt;STDIO.H&gt;

main()
{
char buffer[256];

/* Input a line, then immediately output it. */

puts(gets(buffer));

return 0;
}

On line 10, the gets() function is used to input a line of text from the keyboard (stdin).
Because gets() returns a pointer to the string, it can be used as the argument to puts(), which
displays the string on-screen (stdout). When run, this program inputs a line of text from the
user and then immediately displays the string on-screen.

Accepting Keyboard Input


Most C programs require some form of input from the keyboard (that is, from stdin). Input
functions are divided into a hierarchy of three levels: character input, line input, and
formatted input.

Character Input

The character input functions read input from a stream one character at a time. When
called, each of these functions returns the next character in the stream, or EOF if the end of
the
file has been reached or an error has occurred. EOF is a symbolic constant defined in
STDIO.H as -1. Character input functions differ in terms of buffering and echoing.

1. Some character input functions are buffered. This means that the operating system
holds all characters in a temporary storage space until you press Enter, and then the
system sends the characters to the stdin stream. Others are unbuffered, meaning that
each character is sent to stdin as soon as the key is pressed.
2. Some input functions automatically echo each character to stdout as it is received.
Others don”t echo; the character is sent to stdin and not stdout. Because stdout is
assigned to the screen, that”s where input is echoed.

The uses of buffered, unbuffered, echoing, and nonechoing character input are explained in
the following sections.

The getchar() Function


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

int getchar(void);

The use of getchar() is demonstrated below. Notice that the putchar() function, explained in
detail, simply displays a single character on-screen.

The getchar() function.

/* Demonstrates the getchar() function. */

#include &lt;STDIO.H&gt;

main()
{
int ch;

while ((ch = getchar()) != '\n')


putchar(ch);

return 0;
}
This is what''s typed in.
This is what''s typed in.

On line 9, the getchar() function is called and waits to receive a character from stdin.
Because getchar() is a buffered input function, no characters are received until we press
Enter. However, each key we press is echoed (showed) immediately on the screen.

When we press Enter, all the characters we entered, including the newline, are sent to stdin
by the operating system. The getchar() function returns the characters one at a time,
assigning each in turn to ch.

Each character is compared to the newline character \n and, if not equal, displayed on-
screen with putchar(). When a newline is returned by getchar(), the while loop terminates.

The getchar() function can be used to input entire lines of text, as shown below. However,
other input functions are better suited for this task

Using the getchar() function to input an entire line of text.

/* Using getchar() to input strings. */

#include &lt;STDIO.H&gt;
#define MAX 80

main()
{
char ch, buffer[MAX+1];
int x = 0;

while ((ch = getchar()) != '\n' &amp;&amp; x &lt; MAX)


buffer[x++] = ch;

buffer[x] = '\0';

printf("%s\n", buffer);

return 0;
}
This is a string
This is a string

This program is similar to the previous function in the way that it uses getchar(). An extra
condition has been added to the loop. This time the while loop accepts characters from
getchar() until either a newline character is reached or 80 characters are read. Each
character is assigned to an array called buffer. When the characters have been input, line 15
puts a null on the end of the array
so that the printf() function on line 17 can print the entered string.

On line 9, why was buffer declared with a size of MAX + 1 instead of just MAX? If we
declare buffer with a size of MAX + 1, the string can be 80 characters plus a null
terminator. So don”t forget to include a place for the null terminator at the end of the
strings.

The getch() Function


The getch() function obtains the next character from the stream stdin. It provides
unbuffered character input without echo. The getch() function isn”t part of the ANSI
standard. This means
that it might not be available on every system. Additionally, it might require that different
header files be included. Generally, the prototype for getch() is in the header file CONIO.H,
as follows:

int getch(void);

Because it is unbuffered, getch() returns each character as soon as the key is pressed,
without waiting for the user to press Enter. Because getch() doesn’t echo its input, the
characters aren”t displayed on-screen. Listing 14.4 illustrates the use of getch().
The following function uses getch(), which is not ANSI-compliant. There is no guarantee
that all compilers support non-ANSI functions.

Using the getch() function.

/* Demonstrates the getch() function. */


/* Non-ANSI code */
#include &lt;STDIO.H&gt;
#include &lt;CONIO.H&gt;

main()
{
int ch;

while ((ch = getch()) != '\r')


putchar(ch);

return 0;
}
Testing the getch() function

When this program runs, getch() returns each character as soon as we press a key–it doesn”t
wait for us to press Enter. There”s no echo, so the only reason that each character is
displayed on-screen is the call to putchar(). To get a better understanding, add a semicolon
to the end of line 10 and remove line 11 (putchar(ch)). When we rerun the program, you
will find that nothing
we type is echoed to the screen. The getch() function gets the characters without echoing
them to the screen. We know the characters are being gotten because the original listing
used putchar() to display them.

Why does this program compare each character to \r instead of to \n? The code \r is the
escape sequence for the carriage return character. When we press Enter, the keyboard
device sends a carriage return to stdin. The buffered character input functions automatically
translate the carriage return to a newline, so the program must test for \n to determine
whether Enter has been pressed. The
unbuffered character input functions don”t translate, so a carriage return is input as \r, and
that”s what the program must test for.

The next function uses getch( ) to input an entire line of text. Running this program clearly
illustrates that getch( ) doesn”t echo its input

Using the getch( ) function to input an entire line.


/* Using getch() to input strings. */
/* Non-ANSI code */
#include
#include
#define MAX 80

main()
{
char ch, buffer[MAX+1];
int x = 0;

while ((ch = getch()) != '\r' &amp;&amp; x &lt; MAX)


buffer[x++] = ch;

buffer[x] = '\0';

printf("%s", buffer);

return 0;
}
Here's a string
Here's a string

Remember that getch() isn’t an ANSI-standard command. This means that your compiler
(and other compilers) might or might not support it. getch() is supported by Symantec and
Borland. Microsoft
supports _getch().

The getche() Function


getche() is exactly like getch(), except that it echoes each character to stdout. Modify the
first program in the getch() portion to use getche() instead of getch() and when the program
runs, each key we press is displayed on-screen twice–once as echoed by getche(), and once
as echoed by putchar(). getche() is not an ANSI-standard command, but many C compilers
support it.

The getc() and fgetc() Functions

The getc() and fgetc() character input functions don”t automatically work with stdin.
Instead, they let the program specify the input stream. They are used primarily to read
characters from disk files. See Day 16 for more details.

“Ungetting” a Character with ungetc()


Suppose that the program is reading characters from an input stream and can detect the end
of input only by reading one character too many. For example, we might be inputting digits
only, so we know that input has ended when the first nondigit character is encountered.
That first nondigit character might be an important part of subsequent data, but it has been
removed from the input
stream. Is it lost? No, it can be “ungotten” or returned to the input stream, where it is then
the first character read by the next input operation on that stream.

To “unget” a character, we use the ungetc() library function. Its prototype is

int ungetc(int ch, FILE *fp);

The argument ch is the character to be returned. The argument *fp specifies the stream that
the character is to be returned to, which can be any input stream. For now, simply specify
stdin as the second argument: ungetc(ch, stdin);. The notation FILE *fp is used with
streams associated with disk files.

We can unget only a single character to a stream between reads, and can”t unget EOF at
any time. The function ungetc() returns ch on success and EOF if the character can”t be
returned to the stream.

Reading a Line
The line input functions read a line from an input stream. They read all characters up to the
next newline character ‘\n’. The standard library has two line input functions, gets() and
fgets().

The gets() Function


This is a straight forward function, reading a line from stdin and storing it in a string. The
function prototype is

char *gets(char *str);

gets() takes a pointer to type char as its argument and returns a pointer to type char. The
gets() function reads characters from stdin until a newline (\n) or end-of-file is encountered;
the newline is replaced with a null character, and the string is stored at the location
indicated by str.

The return value is a pointer to the string (the same as str). If gets() encounters an error or
reads end-of-file before any characters are input, a null pointer is returned.

Before calling gets(), we must allocate sufficient memory space to store the string. This
function has no way of knowing whether space pointed to by ptr is allocated; the string is
input and stored starting at ptr in either case. If the space hasn’t been allocated, the string
might overwrite other data and cause program errors.

Using gets() to input string data from the keyboard.


/* Demonstrates using the gets() library function. */
#include &lt;STDIO.H&gt;

/* Allocate a character array to hold input. */

char input[81];

main()
{
puts("Enter some text, then press Enter: ");
gets(input);
printf("You entered: %s\n", input);

return 0;
}
Enter some text, then press Enter:
This is a test
You entered: This is a test

In this example, the argument to gets() is the expression input, which is the name of a type
char array and therefore a pointer to the first array element. The array is declared with 81
elements in line 7. Because the maximum line length possible on most computer screens is
80 characters, this array size provides space for the longest possible input line (plus the null
character that gets()
adds at the end).

The gets() function has a return value. gets() returns a pointer to type char with the address
where the input string is stored. This is the same value that is passed to gets(), but having
the value returned to the program in this way lets your program test for a blank line.

Using the gets() return value to test for the input of a blank line.
/* Demonstrates using the gets() return value. */

#include &lt;STDIO.H&gt;

/* Declare a character array to hold input, and a pointer. */

char input[81], *ptr;

main()
{
/* Display instructions. */

puts("Enter text a line at a time, then press Enter.");


puts("Enter a blank line when done.");

/* Loop as long as input is not a blank line. */


while ( *(ptr = gets(input)) != NULL)
printf("You entered %s\n", input);

puts("Thank you and good-bye\n");

return 0;
}
Enter text a line at a time, then press Enter.
Enter a blank line when done.
First string
You entered First string
Two
You entered Two
Asfia Firdaus
You entered Asfia Firdaus
Thank you and good-bye

If we enter a blank line (that is, if we simply press Enter) in response to line 18, the string
(which contains 0 characters) is still stored with a null character at the end. Because the
string has a length of 0, the null character is stored in the first position. This is the position
pointed to by the return value of gets(), so if we test that position and find a null character,
we know
that a blank line was entered.

The fgets() Function


The fgets() library function is similar to gets() in that it reads a line of text from an input
stream. It’s more flexible, because it lets the programmer specify the specific input stream
to use and the maximum number of characters to be input. The fgets() function is often
used to input text from disk files. To use it for input from stdin, we specify stdin as the
input stream. The prototype of fgets() is

char *fgets(char *str, int n, FILE *fp);

The last parameter, FILE *fp, is used to specify the input stream. Simply specify the
standard input stream, stdin, as the stream argument.

The pointer str indicates where the input string is stored. The argument n specifies the
maximum number of characters to be input. The fgets() function reads characters from the
input stream until a newline or end-of-line is encountered or n – 1 characters have been
read. The newline is included in the string and terminated with a \0 before it is stored. The
return values of fgets() are the
same as described earlier for gets().
Strictly speaking, fgets() doesn’t input a single line of text (if you define a line as a
sequence of characters ending with a newline). It can read less than a full line if the line
contains more than n -1 characters. When used with stdin, execution doesn’t return from
fgets() until you press Enter, but only the first n-1 characters are stored in the string. The
newline is included in the string only if it falls within the first n-1 characters.

Using the fgets() function for keyboard input.


/* Demonstrates the fgets() function. */

#include &lt;STDIO.H&gt;

#define MAXLEN 10

main()
{
char buffer[MAXLEN];

puts("Enter text a line at a time; enter a blank to exit.");

while (1)
{
fgets(buffer, MAXLEN, stdin);

if (buffer[0] == `\n')
break;

puts(buffer);
}
return 0;
}
Enter text a line at a time; enter a blank to exit.
Roses are red
Roses are
red
Violets are blue
Violets a
re blue
Programming in C
Programmi
ng in C
Is for people like you!
Is for pe
ople like
you!

Line 15 contains the fgets() function. When running the program, enter lines of length less
than and greater than MAXLEN to see what happens. If a line greater than MAXLEN is
entered, the first MAXLEN – 1 characters are read by the first call to fgets(); the remaining
characters remain in the keyboard buffer and are read by the next call to fgets() or any other
function that reads from stdin. The program exits when a blank line is entered (lines 17 and
18).

Formatted Input
The input functions covered up to this point have simply taken one or more characters from
an input stream and put them somewhere in memory. No interpretation or formatting of the
input has been done, and you still have no way to input numeric variables. For example,
how would you input the value 12.86 from the keyboard and assign it to a type float
variable? Enter the scanf() and fscanf() functions.

These two functions are identical, except that scanf() always uses stdin, whereas the user
can specify the input stream in fscanf(). This section covers scanf(); fscanf() generally is
used with disk file input.

The scanf() Function’s Arguments


The scanf() function takes a variable number of arguments; it requires a minimum of two.
The first argument is a format string that uses special characters to tell scanf() how to
interpret the input. The second and additional arguments are the addresses of the variable(s)
to which the input data is assigned. Here’s an example:

scanf("%d", &amp;x);

The first argument, “%d”, is the format string. In this case, %d tells scanf() to look for one
signed integer value. The second argument uses the address-of operator (&) to tell scanf()
to assign the input value to the variable x.
The scanf() format string can contain the following:

1. Spaces and tabs, which are ignored (they can be used to make the format string
more readable).
2. Characters (but not %), which are matched against non-white-space characters in
the input.
3. One or more conversion specifications, which consist of the % character followed
by special characters. Generally, the format string contains one conversion
specification for each variable.

The only required part of the format string is the conversion specifications. Each
conversion specification begins with the % character and contains optional and required
components in a
certain order. The scanf() function applies the conversion specifications in the format
string, in order, to the input fields. An input field is a sequence of non-white-space
characters that ends when the next white space is encountered or when the field width, if
specified, is reached. The conversion specification components include the following:

1. The optional assignment suppression flag (*) immediately follows the %. If present,
this character tells scanf() to perform the conversion corresponding to the current
conversion specifier but to ignore the result (not assign it to any variable).
2. The next component, the field width, is also optional. The field width is a decimal
number specifying the width, in characters, of the input field. In other words, the
field width specifies how many characters from stdin scanf() should examine for the
current conversion. If a field width isn’t specified, the input field extends to the next
white space.
3. The next component is the optional precision modifier, a single character that can be
h, l, or L. If present, the precision modifier changes the meaning of the type
specifier that follows it.
4. The only required component of the conversion specifier (besides the %) is the type
specifier. The type specifier is one or more characters that tell scanf() how to
interpret the input. These characters are listed and described in the table given
below. The Argument column lists the required type of the corresponding variable.

For example, the type specifier d requires int * (a pointer to type int).

The type specifier


characters used in scanf() conversion specifiers.
Type Argument Meaning of Type
d int * A decimal integer.
An integer in decimal, octal (with leading 0), or hexadecimal (with
i int *
leading 0X or 0x) notation.
o int * An integer in octal notation with or without the leading 0.
unsigned
u An unsigned decimal integer.
int *
x int * A hexadecimal integer with or without the leading 0X or 0x.
One or more characters are read and assigned sequentially to the
memory location indicated by the argument. No terminating \0 is added.
c char * If a field width argument isn’t given, one character
is read. If a field width argument is given, that number of characters,
including white space (if any), is read.
A string of nonwhitespace characters is read into the specified memory
s char *
location, and a terminating \0 is added.
A floating-point number. Numbers can be input in decimal or scientific
e,f,g float *
notation.
A string. Only the characters listed between the brackets are accepted.
[…] char *
Input ends as soon as a nonmatching character is encountered, the
specified field width is reached, or
Enter is pressed. To accept the ] character, list it first:[]…]. A \0 is
added at the end of the string.
The same as […], except that only characters not listed between the
[^…] char *
brackets are accepted.
% None Literal %: Reads the % character. No assignment is made.

Before seeing some examples of scanf(), we need to understand the precision modifiers.

The precision
modifiers.
Precision
Meaning
Modifier
When placed before the type specifier d, i, o, u, or x, the modifier h specifies
h that the argument is a pointer to type short instead of type int. On a PC, the
type short is the same as type int, so the h precision modifier is never needed.
When placed before the type specifier d, i, o, u, or x, the modifier l specifies
that the argument is a pointer to type long. When placed before the type
l
specifier e, f, or g, the modifier l specifies that the argument is a pointer to
type double.
When placed before the type specifier e, f, or g, the modifier L specifies that
L
the argument is a pointer to type long double.

Handling Extra Characters


Input from scanf() is buffered; no characters are actually received from stdin until the user
presses Enter. The entire line of characters then “arrives” from stdin, and is processed, in
order, by scanf(). Execution returns from scanf() only when enough input has been received
to match the specifications in the format string. Also, scanf() processes only enough
characters from stdin to
satisfy its format string. Extra, unneeded characters, if any, remain waiting in stdin. These
characters can cause problems.

When a call to scanf() is executed and the user has entered a single line, we can have three
situations. For these examples, assume that scanf(“%d %d”, &x, &y); is being executed; in
other words, scanf() is expecting two decimal integers. Here are the possibilities:

1. The line the user inputs matches the format string. For example, suppose the user
enters 12 14 followed by Enter. In this case, there are no problems.
2. scanf() is satisfied, and no characters are left over in stdin. The line that the user
inputs has too few elements to match the format string. For example, suppose the
user enters 12 followed by Enter. In this case, scanf() continues to wait for the
missing input. Once the input is received, execution continues, and no characters are
left over in stdin.
3. The line that the user enters has more elements than required by the format string.
For example, suppose the user enters 12 14 16 followed by Enter. In this case,
scanf() reads the 12 and the 14 and then returns. The extra characters, the 1 and the
6, are left waiting in stdin.

It is this third situation (specifically, those leftover characters) that can cause problems.
They remain waiting for as long as the program is running, until the next time the program
reads input from stdin. Then the leftover characters are the first ones read, ahead of any
input the user makes at the time. It’s clear how this could cause errors. For example, the
following code asks the user to input an integer and then a string:

puts("Enter your age.");


scanf("%d", &amp;age);
puts("Enter your first name.");
scanf("%s", name);

Say, for example, that in response to the first prompt, the user decides to be precise and
enters 21.00 and then presses Enter. The first call to scanf() is looking for an integer, so it
reads the characters 21 from stdin and assigns the value 21 to the variable age. The
characters .00 are left waiting in stdin. The next call to scanf() is looking for a string. It
goes to stdin for input and finds .00 waiting there. The result is that the string .00 is
assigned to name.

A solution is to make sure there are no extra characters waiting in stdin before prompting
the user for input. We can do this by calling gets(), which reads any remaining characters
from stdin, up to and including the end of the line. Rather than calling gets() directly from
the program, we can put it in a separate function with the descriptive name of clear_kb().

Clearing stdin of extra characters to avoid errors.


/* Clearing stdin of extra characters. */

#include &lt;STDIO.H&gt;

void clear_kb(void);

main()
{
int age;
char name[20];

/* Prompt for user's age. */

puts("Enter your age.");


scanf("%d", &amp;age);
/* Clear stdin of any extra characters. */

clear_kb();

/* Now prompt for user's name. */

puts("Enter your first name.");


scanf("%s", name);
/* Display the data. */

printf("Your age is %d.\n", age);


printf("Your name is %s.\n", name);

return 0;
}

void clear_kb(void)

/* Clears stdin of any waiting characters. */


{
char junk[80];
gets(junk);
}
Enter your age.
21 and never older LOL!
Enter your first name.
Asfia
Your age is 21.
Your name is Asfia.

When running this, enter some extra characters after the age, before pressing Enter. Make
sure the program ignores them and correctly prompts for the name. Then modify the
program by removing the call to clear_kb(), and run it again. Any extra characters entered
on the same line as your age are assigned to name

Handling extra characters with fflush()


If we are using the buffered streams with files or disk operations, means that we are using
the buffers to store the information and then process it. So here in this case if we use the
fflush() function then it will flushes all the data and clears the buffers. This function has no
effect on the streams which are not using the buffers.

There is a second way through which we can clear the extra characters that were typed in.
The fflush() function flushes the information in a stream–including the standard input
stream. fflush() is generally used with disk files.
The next program uses the fflush() function instead of the clear_kb() function.

Clearing stdin of extra characters using fflush().


/* Clearing stdin of extra characters. */
/* Using the fflush() function */
#include &lt;STDIO.H&gt;

main()
{
int age;
char name[20];

/* Prompt for user's age. */


puts("Enter your age.");
scanf("%d", &amp;age);

/* Clear stdin of any extra characters. */


fflush(stdin);

/* Now prompt for user's name. */


puts("Enter your first name.");
scanf("%s", name);

/* Display the data. */


printf("Your age is %d.\n", age);
printf("Your name is %s.\n", name);

return 0;
}
Enter your age.
21 and never older LOL!
Enter your first name.
Asfia
Your age is 21.
Your name is Asfia.

As can be seen in line 15, the fflush() function is being used. The prototype for the fflush()
function is as follows:

int fflush( FILE *stream);

The stream is the stream to be flushed. In the above function, the standard input stream,
stdin, is being passed for stream.

scanf() Examples
It’s a powerful function, but it can be a bit confusing at times. Try it and see what happens.
Compile and run this program and then experiment by making changes to the scanf()
format strings.

Some ways to use scanf() for keyboard input.


1: /* Demonstrates some uses of scanf(). */
2:
3: #include &lt;STDIO.H&gt;
4:
5:
6
7: main()
8: {
9: int i1, i2;
10: long l1;
11:
12: double d1;
13: char buf1[80], buf2[80];
14:
15: /* Using the l modifier to enter long integers and doubles.*/
16:
17: puts("Enter an integer and a floating point number.");
18: scanf("%ld %lf", &amp;l1, &amp;d1);
19: printf("\nYou entered %ld and %lf.\n",l1, d1);
20: puts("The scanf() format string used the l modifier to store");
21: puts("your input in a type long and a type double.\n");
22:
23: fflush(stdin);
24:
25: /* Use field width to split input. */
26:
27: puts("Enter a 5 digit integer (for example, 54321).");
28: scanf("%2d%3d", &amp;i1, &amp;i2);
29:
30: printf("\nYou entered %d and %d.\n", i1, i2);
31: puts("Note how the field width specifier in the scanf() format");
32: puts("string split your input into two values.\n");
33:
34: fflush(stdin);
35:
36: /* Using an excluded space to split a line of input into */
37: /* two strings at the space. */
38:
39: puts("Enter your first and last names separated by a space.");
40: scanf("%[^ ]%s", buf1, buf2);
41: printf("\nYour first name is %s\n", buf1);
42: printf("Your last name is %s\n", buf2);
43: puts("Note how [^ ] in the scanf() format string, by excluding");
44: puts("the space character, caused the input to be split.");
45:
46: return 0;
47: }

//---------------------
//Output of the Program
//---------------------

Enter an integer and a floating point number.


123 45.6789
You entered 123 and 45.678900.
The scanf() format string used the l modifier to store
your input in a type long and a type double.
Enter a 5 digit integer (for example, 54321).
54321
You entered 54 and 321.
Note how the field width specifier in the scanf() format
string split your input into two values.
Enter your first and last names separated by a space.
Asfia Firdaus
Your first name is Asfia
Your last name is Firdaus
Note how [^ ] in the scanf() format string, by excluding
the space character, caused the input to be split.

This program starts by defining several variables in lines 9 through 13 for data input. The
program then goes through various types of data. Lines 17 through 21 print long integers
and a double. Line 23 calls the fflush() function to clear any unwanted characters from the
standard input stream. Lines 27 and 28 get the next value, a five-character integer. Because
there are width specifiers, the five-digit integer is split into two integers–one that is two
characters, and one that is three characters. Line 34 calls fflush() to clear the keyboard
again. The final example, in lines 36 through 44, uses the exclude character. Line 40 uses
“%[^ ]%s”, which tells scanf() to get a string but to stop at any spaces. This effectively
splits the input.

Play with this program, change it around a bit and see what happens ?

The scanf() function can be used for most of the input needs, particularly those involving
numbers (strings can be input more easily with gets()).

Screen Output
Screen output functions are divided into three general categories along the
same lines as the input functions.
1. Character output
2. Line output
3. Formatted output

Character Output with putchar(), putc(), and fputc()


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 functions fputc() and putc()
send their output to a stream specified in the argument list.

Using the putchar() Function

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

int putchar(int c);

This function writes the character stored in C to stdout. Although the prototype specifies a
type int argument, we pass putchar() a type char. We can also pass it a type int as long as its
value is appropriate for a character (that is, in the range 0 to 255). The function returns the
character that was just written, or EOF if an error has occurred.

The putchar() function.


/* Demonstrates putchar(). */

#include &lt;STDIO.H…
main()
{
int count;

for (count = 14; count &lt; 128; )


putchar(count++);

return 0;
}

We can also display strings with the putchar() function.

Displaying a string with putchar().


1: /* Using putchar() to display strings. */
2:
3: #include &lt;STDIO.H&gt;
4:
5: #define MAXSTRING 80
6:
7: char message[] = "Displayed with putchar().";
8: main()
9: {
10: int count;
11:
12: for (count = 0; count &lt; MAXSTRING; count++)
13: {
14:
15: /* Look for the end of the string. When it's found, */
16: /* write a newline character and exit the loop. */
17:
18: if (message[count] == `\0')
19: {
20: putchar(`\n');
21: break;
22: }
23: else
24:
25: /* If end of string not found, write the next character. */
26:
27: putchar(message[count]);
28: }
29: return 0;
30: }
Displayed with putchar().

Using the putc() and fputc() Functions

These two functions perform the same action–sending a single character to a specified
stream. putc() is a macro implementation of fputc().Its prototype is

int fputc(int c, FILE *fp);

The FILE *fp part might puzzle you. If wespecify stdout as the stream, fputc() behaves
exactly the same as putchar(). Thus, the following two statements are equivalent:

putchar(`x');
fputc(`x', stdout);

Using puts() and fputs() for String Output


The programs display strings on-screen more often than they display single characters. The
library function puts() displays strings. The function fputs() sends a string to a specified
stream; otherwise, it is identical to puts(). The prototype for puts() is

int puts(char *cp);


*cp is a pointer to the first character of the string that we want displayed. The puts()
function displays the entire string up to but not including the terminating null character,
adding a newline at the end. Then puts() returns a positive value if successful or EOF on
error. (Remember, EOF is a symbolic constant with the value -1; it is defined in STDIO.H.)

The puts() function can be used to display any type of string.

Using the puts() function to display strings.


/* Demonstrates puts(). */

#include &lt;STDIO.H&gt;

/* Declare and initialize an array of pointers. */

char *messages[5] = { "This", "is", "a", "short", "message." };

main()
{
int x;

for (x=0; x&lt;5; x++)


puts(messages[x]);

puts("And this is the end!");

return 0;
}
This
is
a
short
message.
And this is the end!

This program declares an array of pointers. Lines 13 and 14 print each of the strings stored
in the message array.

Using printf() and fprintf() for Formatted Output


To display numbers, we must use the C library’s formatted output functions, printf() and
fprintf(). These functions can also display strings and characters.

The two functions printf() and fprintf() are identical, except that printf() always sends
output to stdout, whereas fprintf() specifies the output stream. fprintf() is generally used for
output to disk files.
The printf() function takes a variable number of arguments, with a minimum of one. The
first and only required argument is the format string, which tells printf() how to format the
output. The optional arguments are variables and expressions whose values we want to
display. Take a look at these simple examples:

1. The statement printf(“Hello, world.”); displays the message Hello, world. on-screen.
This is an example of using printf() with only one argument, the format string. In
this case, the format string contains only a literal string to be displayed on-screen.
2. The statement printf(“%d”, i); displays the value of the integer variable i on-screen.
The format string contains only the format specifier %d, which
tells printf() to display a single decimal integer. The second argument is the name of
the variable whose value is to be displayed.
3. The statement printf(“%d plus %d equals %d.”, a, b, a+b); displays 2 plus 3 equals
5 on-screen (assuming that a and b are integer variables with the values of 2 and 3,
respectively). This use of printf() has four arguments: a format string that contains
literal text as well as format specifiers, and two variables and an expression whose
values are to be displayed.

The printf() format string can contain the following:

1. Zero, one, or more conversion commands that tell printf() how to display a value in
its argument list. A conversion command consists of % followed by one or more
characters.
2. Characters that are not part of a conversion command and are displayed as-is.

The third example’s format string is %d plus %d equals %d. In this case, the three %ds are
conversion commands, and the remainder of the string, including the spaces, is literal
characters that are displayed directly.

Now we can discuss the conversion command. The components of the command are given
here and explained next. Components in brackets are optional.

%[flag][field_width][.[precision]][l]conversion_char

The conversion_char is the only required part of a conversion command (other than the %).
Table lists the conversion characters and their meanings.

The printf() and fprintf() conversion characters.


Conversion
Meaning
Character
d,i Display a signed integer in decimal notation.
u Display an unsigned integer in decimal notation.
o Display an integer in unsigned octal notation.
x,X Display an integer in unsigned hexadecimal notation. Use x for lowercase
output and X for uppercase output.
c Display a single character (the argument gives the character’s ASCII code).
Display a float or double in scientific notation (for example, 123.45 is
displayed as 1.234500e+002). Six digits are displayed to the right of the
e,E
decimal point unless another precision
is specified with the f specifier. Use e or E to control the case of output.
Display a float or double in decimal notation (for example, 123.45 is
f displayed as 123.450000). Six digits are displayed to the right of the
decimal point unless another precision is specified.
Use e, E, or f format. The e or E format is used if the exponent is less than -
g, G 3 or greater than the precision (which defaults to 6). f format is used
otherwise. Trailing zeros are truncated.
Nothing is displayed. The argument corresponding to an n conversion
n command is a pointer to type int. The printf() function assigns to this
variable the number of characters output so far.
Display a string. The argument is a pointer to char. Characters are
displayed until a null character is encountered or the number of characters
s
specified by precision (which defaults to 32767) is displayed. The
terminating null character is not output.
% Display the % character.

We can place the l modifier just before the conversion character. This modifier applies only
to the conversion characters o, u, x, X, i, d, and b. When applied, this modifier specifies
that the argument is a type long rather than a type int. If the l modifier is applied to the
conversion characters e, E, f, g, or G, it specifies that the argument is a type double. If an l
is placed before any other conversion character, it is ignored.

The precision specifier consists of a decimal point (.) by itself or followed by a number. A
precision specifier applies only to the conversion characters e, E, f, g, G, and s. It specifies
the number of digits to display to the right of the decimal point or, when used with s, the
number of characters to output. If the decimal point is used alone, it specifies a precision of
0.

The field-width specifier determines the minimum number of characters output. The field-
width specifier can be the following:

1. A decimal integer not starting with 0. The output is padded on the left with spaces
to fill the designated field width.
2. A decimal integer starting with 0. The output is padded on the left with zeros to fill
the designated field width.
3. The * character. The value of the next argument (which must be an int) is used as
the field width. For example, if w is a type int with a value of 10, the statement
printf(“%*d”, w, a); prints the value of a with a field width of 10.
If no field width is specified, or if the specified field width is narrower than the output, the
output field is just as wide as needed.

The last optional part of the printf() format string is the flag, which immediately follows the
% character. There are four available flags:

?-? This means that the output is left-justified in its field rather than right-justified, which is
the default.

?+? This means that signed numbers are always displayed with a leading + or -.

A space means that positive numbers are preceded by a space.

?#? This applies only to x, X, and o conversion characters. It specifies that nonzero
numbers are displayed with a leading 0X or 0x (for x and X) or a leading 0 (for o).

When we use printf(), the format string can be a string literal enclosed in double quotes in
the printf() argument list. It can also be a null-terminated string stored in memory, in
which case we pass a pointer to the string to printf(). For example, this statement:

char *fmt = "The answer is %f.";


printf(fmt, x);

is equivalent to this statement:

printf("The answer is %f.", x);

The printf() format string can contain escape sequences that provide special control over
the output. Table below lists the most frequently used escape sequences. For example,
including the newline sequence (\n) in a format string causes subsequent output to appear
starting on the next screen line

The most frequently used escape sequences.


Sequence Meaning
\a Bell (alert)
\b Backspace
\n Newline
\t Horizontal tab
\\ Backslash
\? Question mark
\' Single quote
\" Double quote

printf() is somewhat complicated. The best way to learn how to use it is to look at examples
and then experiment on your own but don?t be alarmed, it?s easy ?
Some ways to use the printf() function.
/* Demonstration of printf(). */

#include &lt;STDIO.H&gt;

char *m1 = "Binary";


char *m2 = "Decimal";
char *m3 = "Octal";
char *m4 = "Hexadecimal";

main()
{
float d1 = 10000.123;
int n, f;

puts("Outputting a number with different field widths.\n");

printf("%5f\n", d1);
printf("%10f\n", d1);
printf("%15f\n", d1);
printf("%20f\n", d1);
printf("%25f\n", d1);

puts("\n Press Enter to continue...");


fflush(stdin);
getchar();

puts("\nUse the * field width specifier to obtain field width");


puts("from a variable in the argument list.\n");

for (n=5;n&lt;=25; n+=5)


printf("%*f\n", n, d1);

puts("\n Press Enter to continue...");


fflush(stdin);
getchar();

puts("\nInclude leading zeros.\n");

printf("%05f\n", d1);
printf("%010f\n", d1);
printf("%015f\n", d1);
printf("%020f\n", d1);
printf("%025f\n", d1);
puts("\n Press Enter to continue...");
fflush(stdin);
getchar();

puts("\nDisplay in octal, decimal, and hexadecimal.");


puts("Use # to precede octal and hex output with 0 and 0X.");
puts("Use - to left-justify each value in its field.");
puts("First display column labels.\n");

printf("%-15s%-15s%-15s", m2, m3, m4);

for (n = 1;n&lt; 20; n++)


printf("\n%-15d%-#15o%-#15X", n, n, n);

puts("\n Press Enter to continue...");


fflush(stdin);
getchar();

puts("\n\nUse the %n conversion command to count characters.\n");

printf("%s%s%s%s%n", m1, m2, m3, m4, &amp;n);

printf("\n\nThe last printf() output %d characters.\n", n);

return 0;
}
Outputting a number with different field widths.
10000.123047
10000.123047
10000.123047
10000.123047
10000.123047
Press Enter to continue...
Use the * field width specifier to obtain field width
from a variable in the argument list.
10000.123047
10000.123047
10000.123047
10000.123047
10000.123047
Press Enter to continue...
Include leading zeros.
10000.123047
10000.123047
00010000.123047
0000000010000.123047
000000000000010000.123047
Press Enter to continue...
Display in octal, decimal, and hexadecimal.
Use # to precede octal and hex output with 0 and 0X.
Use - to left-justify each value in its field.
First display column labels.
Decimal Octal Hexadecimal
1 01 0X1
2 02 0X2
3 03 0X3
4 04 0X4
5 05 0X5
6 06 0X6
7 07 0X7
8 010 0X8
9 011 0X9
10 012 0XA
11 013 0XB
12 014 0XC
13 015 0XD
14 016 0XE
15 017 0XF
16 020 0X10
17 021 0X11
18 022 0X12
19 023 0X13
Press Enter to continue...
Use the %n conversion command to count characters.
BinaryDecimalOctalHexadecimal
The last printf() output 29 characters.

Redirecting Input & Output


A program that uses stdin and stdout can utilize an operating-system feature called
redirection. Redirection allows you to do the following:

1. Output sent to stdout can be sent to a disk file or the printer rather than to the
screen.
2. Program input from stdin can come from a disk file rather than from the keyboard.

We don’t code redirection into our programs; we specify it on the command line$ when we
run the program. In DOS, as in UNIX, the symbols for redirection are < and >.

Remember the first C program, HELLO.C? It used the printf() library function to display
the message Hello, world on-screen. As we now know, printf() sends output to stdout, so it
can be redirected. When we enter the program name at the command-line prompt, follow it
with the > symbol and the name of the new destination:
hello > destination

Thus, if we enter hello >prn, the program output goes to the printer instead of to the screen
(prn is the DOS name for the printer attached to port LPT1:). If we enter hello >hello.txt,
the output is placed in a disk file with the name HELLO.TXT.
When we redirect output to a disk file, be careful. If the file already exists, the old copy is
deleted and replaced with the new file. If the file doesn’t exist, it is created. When
redirecting output to a file, we can also use the >> symbol. If the specified destination file
already exists, the program output is appended to the end of the file.

The redirection of input and output.


/* Can be used to demonstrate redirection of stdin and stdout. */

#include &lt;stdio.h&gt;

main()
{
char buf[80];

gets(buf);
printf("The input was: %s\n", buf);
return 0;
}

This program accepts a line of input from stdin and then sends the line to stdout, preceding
it with The input was:. After compiling and linking the program, run it without redirection
(assuming that the program is named TRIAL) by entering TRIAL at the command-line
prompt. If we then enter I am teaching myself C, the program displays the following on-
screen:

The input was: I am teaching myself C

If we run the program by entering TRIAL >test.txt and make the same entry, nothing is
displayed on-screen. Instead, a file named TEST.TXT is created on the disk. If we use the
DOS TYPE (or an equivalent) command to display the contents of the file:

type test.txt

We’ll see that the file contains only the line The input was: I am teaching myself C.
Similarly, if we had run the program by entering TRIAL >prn, the output line would have
been printed on the printer (prn is a DOS command name for the printer).
Just for the sake of it run the program again, this time redirecting output to TEST.TXT with
the >> symbol. Instead of the file’s getting replaced, the new output is appended to the end
of TEST.TXT. Give it a try ?

Redirecting Input
First we need a source file. Use the editor to create a file named INPUT.TXT that contains
the single line COMSATS Abbottabad. Now run the previous program by entering the
following at the DOS prompt:

trial &lt; INPUT.TXT

The program doesn’t wait for you to make an entry at the keyboard. Instead, it immediately
displays the following message on-screen:

The input was: COMSATS Abbottabad

The stream stdin was redirected to the disk file INPUT.TXT, so the program’s call to gets()
reads one line of text from the file rather than the keyboard.

We can redirect input and output at the same time. Try running the program with the
following command to redirect stdin to the file INPUT.TXT and redirect stdout to
JUNK.TXT:

trial &lt; INPUT.TXT &gt; JUNK.TXT

Redirecting stdin and stdout can be useful in certain situations. A sorting program, for
example, could sort either keyboard input or the contents of a disk file. Likewise, a mailing
list program could display addresses on-screen, send them to the printer for mailing labels,
or place them in a file for some other use.

When to Use fprintf()


The library function fprintf() is identical to printf(), except that we can specify the stream to
which output is sent. The main use of fprintf() involves disk files. There are two other uses.

Using stderr
One of C’s predefined streams is stderr (standard error). A program’s error messages
traditionally are sent to the stream stderr and not to stdout. Output to stdout can be
redirected to a destination other than the display screen. If stdout is redirected, the user
might not be aware of any error messages the program sends to stdout. Unlike stdout, stderr
can’t be redirected and is always connected to the screen (at least in DOS–UNIX systems
might allow redirection of stderr). By directing error messages to stderr, we can be sure the
user always sees them. We do this with fprintf():

fprintf(stderr, "An error has occurred.");

We can write a function to handle error messages and then call the function when an error
occurs rather than calling fprintf():
error_message("An error has occurred.");
void error_message(char *msg)
{
fprintf(stderr, msg);
}

By using our own function instead of directly calling fprintf(), we provide additional
flexibility (one of the advantages of structured programming). For example, in special
circumstances we might want a program’s error messages to go to the printer or a disk file.
All we need to do is modify the error_message() function so that the output is sent to the
desired destination.

Printer Output Under DOS


On a DOS or Windows system, we send output to the printer by accessing the predefined
stream stdprn. To use stdprn, you need to turn ANSI compatibility off in your compiler.
The program presents a simple example.

Sending output to the printer.


1: /* Demonstrates printer output. */
2:
3: #include &lt;stdio.h&gt;
4:
5: main()
6: {
7: float f = 2.0134;
8:
9: fprintf(stdprn, "\nThis message is printed.\r\n");
10: fprintf(stdprn, "And now some numbers:\r\n");
11: fprintf(stdprn, "The square of %f is %f.", f, f*f);
12:
13: /* Send a form feed. */
14: fprintf(stdprn, "\f");
15:
16: return 0;
17: }
This message is printed.
And now some numbers:
The square of 2.013400 is 4.053780.

This output is printed by the printer. It won’t appear on-screen If DOS system has a printer
connected to port LPT1:, we can compile and run this program. It prints three lines on the
page. Line 14 sends an “\f” to the printer. \f is the escape sequence for a form feed, the
command that causes the printer to advance a page (or, in the case of a laser printer, to eject
the current page).
DOs and DON?Ts
1. DO use fprintf() to create programs that can send output to stdout, stderr, stdprn, or
any other stream.
2. DO use fprintf() with stderr to print error messages to the screen.
3. DO take advantage of the standard input/output streams that C provides.
4. DO understand the difference between echoed and nonechoed input.
5. DO understand the difference between buffered and unbuffered input
6. DO create functions such as error_message to make your code more structured and
maintainable.
7. DO take advantage of extended characters in your programs. When using extended
characters, you should try to be consistent with other programs.
8. DO use the gets() and scanf() functions instead of the fgets() and fscanf() functions
if you’re using the standard input file (stdin) only.
9. DON’T use stderr for purposes other than printing error messages or warnings.
10. DON’T ever try to redirect stderr.
11. DON’T use non-ANSI standard functions if portability is a concern
12. DON’T rename or change the standard streams unnecessarily.
13. DON’T try to use an input stream such as stdin for an output function such as
fprintf().
14. DON’T forget to check the input stream for extra characters.

Input & Output in C Language – Final Words


This tutorial taught you about how C uses streams, treating all input and output as a
sequence of bytes. You also learned that C has five predefined streams:

stdin The keyboard


stdout The screen
stderr The screen
stdprn The printer
stdaux The communications port

Input from the keyboard arrives from the stream stdin. Using C’s standard library functions,
you can accept keyboard input character by character, a line at a time, or as formatted
numbers and strings. Character input can be buffered or unbuffered, echoed or unechoed.

Output to the display screen is normally done with the stdout stream. Like input, program
output can be by character, by line, or as formatted numbers and strings. For output to the
printer, you use fprintf() to send data to the stream stdprn.

When you use stdin and stdout, you can redirect program input and output. Input can come
from a disk file rather than the keyboard, and output can go to a disk file or to the printer
rather than to the display screen.
Finally, you learned why error messages should be sent to the stream stderr instead of
stdout. Because stderr is usually connected to the display screen, you are assured of seeing
error messages even when the program output is redirected.

Loops and Decision – if else, for and while


C language programes are executed in a sequence, but we can control the execution of C
program by using any control mechanism by which we can compare things and come to a
decision. This involves using some operations called Relational Operators, conditional
statements called if-else and loops. We have fundamental operators to compare two values.

These relational operators compare two values and return true or false after comparison.
We can use the relational operators to compare values of any basic data type, so all we need
is to modify the behavior of the program.

“The relational operators compare two values of any basic data type and return true or false
after comparison.”

Here are the examples of Conditional Operators


1. < Less than
2. > Greater than
3. == Equal to
4. <= Less than or equal to
5. >= Greater than or equal to
6. != Not equal to

The decision control structure in C can be implemented


using
1. The if statement
2. The if – else statement
3. The conditional operators

The if statement by itself will execute a single statement or a group of statements when the
condition following if is true

If the condition is false then a group of statements can be executed using else statement

The simple example of an if statement is:

if(varName == 20)
printf (&quot;Value of the variable is 20&quot;);
We can use the block to specify the statements to pre executed if the given condition is true

if(varName == 20){
printf (&quot;Value of the variable is 20&quot;);
printf (&quot;Print what ever you want!!!&quot;);
}

These are three methods by way of which we can repeat a


part of a program in C programming
1. Using a for statement
2. Using a while statement
3. Using a do-while statement

The for statement is started with the keyword for . There are three expressions which
appear with in a for statement.

1. Initializing Expression
2. Test Expression
3. Increment Expression

It has the following standard form.

for (int i=0;i&lt;= min; i++)


ans += i;

The while loop continues untill the specified condition is true. The general form of while
loop is

while(condition)
loop statement

The do-while loop is similar to the while loop in that the loop continues as long as the
specified loop condition remains true. The main difference is that the condition is checked
at the end of the do-while statement. So do-while loop is always executed at least once. Its
general form is

do{
loop statement
}while(condition)

Loops & Decision Control Structure


The decision control structure in C can be implemented in C using
1. The if statement
2. The if – else statement
3. The conditional operators

The if Statement
The general form of if statement looks like this:

if (this condition is true)


execute this statement;

Here the keyword if tells the compiler that what follows, is a decision control instruction.
The condition following the keyword if is always enclosed within a pair of parentheses. If
the condition, whatever it is true, then the statement is executed. It the condition is not true
then the statement is not executed instead the program skips past it. The condition in C is
evaluated using C?s relational operators. The relational operators help us to build
expression which are either true or false

for e.q

This expression is true if

X == Y X is equal to Y
X != Y X is not equal to Y
X &gt;Y X is greater than Y
X &lt;= Y X is less than or equal to Y
X &gt;= Y X is greater than or equal to Y

Demonstration of if statement
main( )
{
int num;
Printf("Enter a number less than 10");
Scanf("%d", &amp; num);
if(num &lt; = 10)
Printf("The number is less than 10");
}

Multiple Statements within if


If it is desired that more than one statement is to be executed if the condition following if is
satisfied, then such statements must be placed within pair of braces. for e.g.
The following program demonstrate that if year of service greater than 3 then a bonus of
Rs. 2500 is given to employee. The program illustrates the multiple statements used within
if

/* calculation of bonus */
main( )
{
int bonus, CY, Yoj, yr-of-ser;
Printf("Enter current year and year of joining");
Scanf("%d %d", Scy, Syoj);
yr-of-ser = CY-Yoj;
if(yr-ofser &gt; 3)
{
bonus = 2500;
Printf("Bonus = Rs. %d", bonus);
}
}

If – Else statement
The if statement by itself will execute a single statement or a group of statements when the
condition following if is true. it does nothing when the condition is false. It the condition is
false then a group of statements can be executed using else statement. The following
program illustrates this

/* Calculation of gross salary */


main( )
{
float bs, gs, da, hra;
Printf("Enter basic salary");
Scanf("/.f", &amp; bs);
if(bs &lt;1500)
{
hra = bs * 10/100;
da = bs * 90/100;
}
else
{
hra = 500;
da = bs * 98/100;
}
gs = bs+hra+da;
Printf("gross salary = Rs. /.f ", gs);
}

Nested if – else statement


It we write an entire if – else construct within the body of the if statement or the body of an
else statement. This is called ?nesting? of if. For e.g.

if (condition)
{
if (condition)
{
do this;
else
{
do this;
and this;
}
}
else
do this;

The Loop Control Structure


These are three methods by way of which we can repeat a part of a program. They are:

1. Using a for statement


2. Using a while statement
3. Using a do-while statement

The While Loop


The general from of while is as shown below:

initialise loop counter;

while (test loop counter using a condition)


{
do this;
and this;
increment loop counter;
}

The parentheses after the while contains a condition so long as this condition remains true
all statements within the body of the while loop keep getting executed repeatedly for e.g.

/* calculate simple interest for 3 sets of p, n and r */


main( )
{
int p,n, count;
float r, si;
count = 1;
while(count &lt; = 3 )
{
printf("Enter values of p, n and r");
scanf("%d %d %f", &amp; p, &amp; n, &amp; r);
si = p*n*r/100;
printf("simple interest = Rs. %f ", si);
count = count +1;
}
}

The do-while Loop


The do-while loop takes the following form

do
{
this;
and this;
and this;
and this;
} while (this condition is true);

There is a minor difference between the working of while and do-while loops. The
difference is the place where the condition is tested. The while tests the condition before
executing any of the statements within the while loop. As against this the do-while tests the
condition after having executed the statements within the loop. for e.g.

main( )
{
while(5&lt;1)
printf("Hello ");
}

In the above e.q. the printf will not get executed at all since the condition fails at the first
time itself. Now let?s now write the same program using a do-while loop.

main( ) {
do {
Printf ("itello ");
}
while
(5&lt;1);
}
In the above program the printf( ) would be executed once, since first the body of the loop
us executed and then the condition is tested.

The for Loop


The general form of for statement is as under:

for( initialise counter; test counter; increment counter){


do this;
and this;
and this;
}

Now let us write the simple interest problem using the for loop

/* calculate simple interest for 3 sets of p,n and r*/


main( )
{
int p,n, count;
float r, si;
for(count = 1; count &lt;=3; count = count +1)
{
printf("Enter values of p,n and r");
scanf("%d %d %f", &amp; p, &amp; n, &amp; r);
si = p * n * r / 100;
printf("Simple interest = Rs %f ", si);
}
}

The Break Statement


The keyword break allows us to jump out of a loop instantly without waiting to get back to
the conditional test. When the keyword break is encountered inside any C loop, control
automati-cally passes to the first statement after the loop. For e.g. the following program is
to determine whether a number is prime or not.

Logic: To test a number is prime or not, is to divide it successively by all numbers from 2
to one less than itself. It the remainder of any of the divisions is zero, the number is not a
prime. Following program implements this logic

main( )
{
int num, i;
printf("Enter a number");
scanf("%d", &amp;num);
i=2
while (i &lt; = num -1)
{
if (num%i= = 0)
{
printf("Not a prime number");
break;
}
i++
}
if(i = = num)
printf("Prime number");
}

The Continue Statement


The keyword continue allows us to take the control to the beginning of the loop bypassing
the statements inside the loop which have not yet been executed. When the keyword
continue is encountered inside any C loop control automatically passes to the beginning of
the loop. for e.g.

main( )
{
int i,j;
for(i = 1; i&lt; = 2; i++)
{
for(j=1; j&lt;=2; j++)
{
if (i= =j)
continue;
printf("%d%d", i,j);
}
}
}

The output of the above program would be….

12

21

when the value of i equal to that of j, the continue statement takes the control to the for loop
(inner) bypassing rest of the statements pending execution in the for loop (inner).

The Case Control Structure


Switch Statement:

-The switch statement causes a particular group of statements to be chosen


from several available groups. The selection is based upon the current value
of an expression that is in-cluded within the switch statement.

The form of switch statement is.

switch (integer expression)


{ case constant 1:
do this;
case constant 2:
do this;
case constant 3:
do this;
default;
do this;
}
File Handling in C Language
File stores information for many purposes and retrieve whenever required by our programs.
A file represents a sequence of bytes on the disk where a group of related data is stored.
File is created for permanent storage of data. C programming language can handle files as
Stream-oriented data (Text) files and System oriented data Binary) files.

What is a File?
Abstractly, a file is a collection of bytes stored on a secondary storage device, which is
generally a disk of some kind. The collection of bytes may be interpreted, for example, as
characters, words, lines, paragraphs and pages from a textual document; fields and records
belonging to a database; or pixels from a graphical image. The meaning attached to a
particular file is determined entirely by the data structures and operations used by a
program to process the file. It is conceivable (and it sometimes happens) that a graphics file
will be read and displayed by a program designed to process textual data. The result is that
no meaningful output occurs (probably) and this is to be expected. A file is simply a
machine decipherable storage media where programs and data are stored for machine
usage.

Essentially there are two kinds of files that programmers deal with text files and binary
files. These two classes of files will be discussed in the following sections.

ASCII Text files


A text file can be a stream of characters that a computer can process sequentially. It is not
only processed sequentially but only in forward direction. For this reason a text file is
usually opened for only one kind of operation (reading, writing, or appending) at any given
time.

Similarly, since text files only process characters, they can only read or write data one
character at a time. (In C Programming Language, Functions are provided that deal with
lines of text, but these still essentially process data one character at a time.) A text stream in
C is a special kind of file. Depending on the requirements of the operating system, newline
characters may be converted to or from carriage-return/linefeed combinations depending on
whether data is being written to, or read from, the file. Other character conversions may
also occur to satisfy the storage requirements of the operating system. These translations
occur transparently and they occur because the programmer has signalled the intention to
process a text file.
Binary files
A binary file is no different to a text file. It is a collection of bytes. In C Programming
Language a byte and a character are equivalent. Hence a binary file is also referred to as a
character stream, but there are two essential differences.

1. No special processing of the data occurs and each byte of data is transferred to or
from the disk unprocessed.
2. C Programming Language places no constructs on the file, and it may be read from,
or written to, in any manner chosen by the programmer.

Binary files can be either processed sequentially or, depending on the needs of the
application, they can be processed using random access techniques. In C Programming
Language, processing a file using random access techniques involves moving the current
file position to an appropriate place in the file before reading or writing data. This indicates
a second characteristic of binary files.
They a generally processed using read and write operations simultaneously.

For example, a database file will be created and processed as a binary file. A record update
operation will involve locating the appropriate record, reading the record into memory,
modifying it in some way, and finally writing the record back to disk at its appropriate
location in the file. These kinds of operations are common to many binary files, but are
rarely found in applications that process text files.

Creating a file and output some data


In order to create files we have to learn about File I/O i.e. how to write data into a file and
how to read data from a file. We will start this section with an example of writing data to a
file. We begin as before with the include statement for stdio.h, then define some variables
for use in the example including a rather strange looking new type.

/* Program to create a file and write some data the file */


#include <stdio.h>
#include <stdio.h>
main( )
{
FILE *fp;
char stuff[25];
int index;
fp = fopen("TENLINES.TXT","w"); /* open for writing */
strcpy(stuff,"This is an example line.");
for (index = 1; index <= 10; index++)
fprintf(fp,"%s Line number %d\n", stuff, index);
fclose(fp); /* close the file before ending program */
}
The type FILE is used for a file variable and is defined in the stdio.h file. It is used to define
a file pointer for use in file operations. Before we can write to a file, we must open it. What
this really means is that we must tell the system that we want to write to a file and what the
file name is. We do this with the fopen() function illustrated in the first line of the program.
The file pointer, fp in our case, points to the file and two arguments are required in the
parentheses, the file name first, followed by the file type.

The file name is any valid DOS file name, and can be expressed in upper or lower case
letters, or even mixed if you so desire. It is enclosed in double quotes. For this example we
have chosen the name TENLINES.TXT. This file should not exist on your disk at this time.
If you have a file with this name, you should change its name or move it because when we
execute this program, its contents will be erased. If you don’t have a file by this name,
that is good because we will create one and put some data into it. You are permitted to
include a directory with the file name.The directory must, of course, be a valid directory
otherwise an error will occur. Also, because of the way C handles literal strings, the
directory separation character \ must be written twice. For example, if the file is to be stored
in the \PROJECTS sub directory then the file name should be entered as
“\\PROJECTS\\TENLINES.TXT”. The second parameter is the file attribute and can be
any of three letters, r, w, or a, and must be lower case.

Reading (r)

When an r is used, the file is opened for reading, a w is used to indicate a file to be used for
writing, and an a indicates that you desire to append additional data to the data already in an
existing file. Most C compilers have other file attributes available; check your Reference
Manual for details. Using the r indicates that the file is assumed to be a text file. Opening a
file for reading requires that the file already exist. If it does not exist, the file pointer will be
set to NULL and can be checked by the program.

Here is a small program that reads a file and display its contents on screen.

/* Program to display the contents of a file on screen */


#include <stdio.h>
void main()
{
FILE *fopen(), *fp;
int c;
fp = fopen("prog.c","r");
c = getc(fp) ;
while (c!= EOF)
{
putchar(c);
c = getc(fp);
}
fclose(fp);
}
Writing (w)

When a file is opened for writing, it will be created if it does not already exist and it will be
reset if it does, resulting in the deletion of any data already there. Using the w indicates that
the file is assumed to be a text file.

Here is the program to create a file and write some data into the file.

#include <stdio.h>
int main()
{
FILE *fp;
file = fopen("file.txt","w");
/*Create a file and add text*/
fprintf(fp,"%s","This is just an example :)"); /*writes data to the file*/
fclose(fp); /*done!*/
return 0;
}

Appending (a)

When a file is opened for appending, it will be created if it does not already exist and it will
be initially empty. If it does exist, the data input point will be positioned at the end of the
present data so that any new data will be added to any data that already exists in the file.
Using the a indicates that the file is assumed to be a text file.

Here is a program that will add text to a file which already exists and there is some text in
the file.

#include <stdio.h>
int main()
{
FILE *fp
file = fopen("file.txt","a");
fprintf(fp,"%s","This is just an example :)"); /*append some text*/
fclose(fp);
return 0;
}

Outputting to the file


The job of actually outputting to the file is nearly identical to the outputting we have
already done to the standard output device. The only real differences are the new function
names and the addition of the file pointer as one of the function arguments. In the example
program, fprintf replaces our familiar printf function name, and the file pointer defined
earlier is the first argument within the parentheses. The remainder of the statement looks
like, and in fact is identical to, the printf statement.

Closing a file
To close a file you simply use the function fclose with the file pointer in the parentheses.
Actually, in this simple program, it is not necessary to close the file because the system will
close all open files before returning to DOS, but it is good programming practice for you to
close all files in spite of the fact that they will be closed automatically, because that would
act as a reminder to you of what files are open at the end of each program.

You can open a file for writing, close it, and reopen it for reading, then close it, and open it
again for appending, etc. Each time you open it, you could use the same file pointer, or you
could use a different one. The file pointer is simply a tool that you use to point to a file and
you decide what file it will point to. Compile and run this program. When you run it, you
will not get any output to the monitor because it doesn’t generate any. After running it,
look at your directory for a file named TENLINES.TXT and type it; that is where your
output will be. Compare the output with that specified in the program; they should agree!
Do not erase the file named TENLINES.TXT yet; we will use it in
some of the other examples in this section.

Reading from a text file

Now for our first program that reads from a file. This program begins with the familiar
include, some data definitions, and the file opening statement which should require no
explanation except for the fact that an r is used here because we want to read it.

#include <stdio.h>
main( )
{
FILE *fp;
char c;
funny = fopen("TENLINES.TXT", "r");
if (fp == NULL)
printf("File doesn't exist\n");
else {
do {
c = getc(fp); /* get one character from the file
*/
putchar(c); /* display it on the monitor
*/
} while (c != EOF); /* repeat until EOF (end of file)
*/
}
fclose(fp);
}
In this program we check to see that the file exists, and if it does, we execute the main body
of the program. If it doesn’t, we print a message and quit. If the file does not exist, the
system will set the pointer equal to NULL which we can test. The main body of the
program is one do while loop in which a single character is read from the file and output to
the monitor until an EOF (end of file) is detected from the input file. The file is then closed
and the program is terminated. At this point, we have the potential for one of the most
common and most perplexing problems of programming in C. The variable returned from
the getc function is a character, so we can use a char variable for this purpose. There is a
problem that could develop here if we happened to use an unsigned char however, because
C usually returns a minus one for an EOF – which an unsigned char type variable is not
capable of containing. An unsigned char type variable can only have the values of zero to
255, so it will return a 255 for a minus one in C. This is a very frustrating problem to try to
find. The program can never find the EOF and will therefore never terminate the loop. This
is easy to prevent: always have a char or int type variable for use in returning an EOF.
There is another problem with this program but we will worry about it when we get to the
next program and solve it with the one following that.

After you compile and run this program and are satisfied with the results, it would be a
good exercise to change the name of TENLINES.TXT and run the program again to see
that the NULL test actually works as stated. Be sure to change the name back because we
are still not finished with TENLINES.TXT.

File Handling
In C++ we say data flows as streams into and out of programs. There are different kinds of
streams of data flow for input and output. Each stream is associated with a class, which
contains member functions and definitions for dealing with that particular kind of flow. For
example, the if stream class represents the input disc files,. Thus each file in C++ is an
object of a particular stream class.

The stream class hierarchy


The stream classes are arranged in a rather complex hierarchy. You do not need to
understand this hierarchy in detail to program basic file I/O, but a brief overview may be
helpful. We have already made extensive use of some of these classes. The extraction
operator >> is a member of istream class and the insertion operator is a member of ostream
class. Both of these classes are derived from the ios class. The cout object is a predefined
object of the ostream with assign class. It is in turn derived from ostream class. The classes
used for input and output to the video display and keyboard are declared in the header file
IOSTREAM.H, which we have routinely included in all our programs.

Stream classes
The ios class is the base class for the entire I/O hierarchy. It contains many constants and
member functions common to input and output operations of all kinds. The istream and
ostream classes are derived from ios and are dedicated to input and output respectively
Their member functions perform both formatted and unformatted operations. The iostream
class is derived from both istream and ostream by multiple inheritance, so that other classes
can inherit both of these classes from it. The classes in which we are most interested for file
I/O are ifstream for input files ofsteam for output files and fstream for files that will be used
for both input and output the ifstream and ofsteam classes are declared in the FSTREAM.H.
file.

The isteam class contains input functions such as

 getline( )
 getine( )
 read( )

and overloaded extraction operators.

The ostream class contains functions such as

 Put( )
 write( )

and overloaded insertor.

Writing strings into a file


Let us now consider a program which writes strings in a file.

//program for writing a string in a file


#include <fstream.h>
void main( )
{
ofstream outfile("fl.fil");//create a file for output
outfile <<"harmlessness, truthfulness, calm" <<endl;
outfile <<"renunciation, absence of wrath and fault-finding" <<endl;
outfile <<"compassion for all, non-covetousness, gentleness, modesty" <<endl;
outfile <<"stability. vigour, forgiveness, endurance, cleanliness" <<endl;
outfile <<"absence of malice and of excessive self-esteem" <<endl;
outfile <<"these are the qualities of godmen" <<endl;
}

In the above program, we create an object called outfile, which is a member of the output
file stream class. We initialise it to the filename “fl.fil”. You can think of outfile as a user-
chosen logical name which is associated with the real file on disc called “fl.fil”. When any
automatic object (outfile is automatic) is defined in a function, it is created in the function
and automatically destroyed when the function terminates. When our main ( ) function
ends, outfile goes out of scope. This automatically calls the destructor, which closes the
file. It may be noticed that we do not need to close the file explicitly by any close-file
command. The insertion operator << is overloaded in ofsteam and works with objects
defined from ofstream. Thus, we can use it to output txt to the file. The strings are written
in the file “fl. fil? in the ASCII mode. One can see it from DOS by giving the type
command. The file “fl. fil” looks as shown below

harmlessness, truthfulness, calm renunciation, absence of wrath and fault-finding


compassion for all, non-covetousness, gentleness, modesty stability, vigour, forgiveness,
endurance, cleanliness absence of malice and of excessive self-esteem these are the
qualities of godmen.

Reading strings from file


The program below illustrates the creation of an object of ifstream class for reading
purpose.

//program of reading strings

#include <fstream.h> //for file functions


void main( )
{
const int max = 80; //size of buffer
char buffer[max]; //character buffer
ifstream. infile("fl.fil")- //create file for input
while (infile) //until end-of-file
{
infile.getline(buffer,max); //read a line of text
cout<<buffer
}
}
We define infile as an ifstream object to input records from the file “fl.fil”. The insertion
operator does not work here. Instead, we read the text from the file, one line at a time, using
the getline( ) function. The getline ( ) function reads characters until it encounters the ? \n?
character. It places the resulting string in the buffer supplied as an argument. The maximum
size of the buffer is given as the second argument. The contents of each line are displayed
after each line is input. Our ifstream object called infile has a value that can be tested for
various error conditions -one is the end-of-file. The program checks for the EOF in the
while loop so that it can stop reading after the last string.

What is a buffer?
A buffer is a temporary holding area in memory which acts as an intermediary between a
program and a file or other I/0 device. Information can be transferred between a buffer and
a file using large chunks of data of the size most efficiently handled by devices like disc
drives. Typically, devices like discs transfer information in blocks of 512 bytes or more,
while program often processes information one byte at a time. The buffer helps match these
two desperate rates of information transfer. On output, a program first fills the buffer and
then transfers the entire block of data to a hard disc, thus clearing the buffer for the next
batch of output. C++ handles input by connecting a buffered stream to a program and to its
source of input. similarly, C++ handles output by connecting a buffered stream to a
program and to its output target.

Using put( ) and get( ) for writing and reading characters

The put ( ) and get( ) functions are also members of ostream and istream. These are used to
output and input a single character at a time. The program shown below is intended to
illustrate the use of writing one character at a time in a file.

//program for writing characters


#Include <fstream.h>
#include <string.h>
void main( ){
charstr[] = "do unto others as you would be done by ;
ofstream outfile("f2.fil");
for(int i =0; i<strlen(str); i++)
outfile put(str[i]);
}

In this program, the length of the string is found by the strlen( ) function, and the characters
are output using put( function in a for loop. This file is also an ASCII file.

Reading Characters
The program shown below illustrates the reading of characters from a file.

//program for reading characters of a string


#Include <fstream.h>
void main( )
{
char ch;
ifstream in file("f2.fil")?
while(infile)
infile.get(ch);
cout<<ch;
}
The program uses the get( ) and continues to read until eof is reached. Each character read
from the file is displayed using cout. The contents of file f2.fil created in the last program
will be displayed on the screen.
Writing an object in a files
Since C++ is an object-oriented language, it is reasonable to wonder how objects can be
written to and read from the disc. The program given below is intended to write an object in
a file.

//program for writing objects in files


#include <fstream.h>
class employees
{
protected:
int empno;
char name[10];
char dept[5];
char desig[5];
double basic;
double deds;
public:
void getdata(void)
{
coul<<endl<<"enter empno";cin>>empno;"
cout<<endl<<"enter empname";cin>>name;
cout<<endl<<"enter department ";
cin>>dept; cout<<endl<<"enter designation ";
cin>>desig; cout<<endl<<"enter basic pay ";cin>>basic:
cout<<endl<<"enter deds ";cin>>deds;
}
void main(void){
employees emp;
emp.getdata( );
ofstream outfile("f3.fil");
outfile. write((char * )&emp,sizeof(emp));
}

This program uses a class by name employees and an object by name emp. Data can be
written only by the function inside the object. This program creates a binary data file by
name f3.fil.The write( ) function is used for writing. The write( ) function requires two
arguments, the address of the object to be written, and the size of the object in bytes. We
use the size of operator to find the length of the emp object. The address of the object must
be cast to type pointer to char.

Binary vs. Character files


You might have noticed that write( ) was used to output binary values, not just characters.
To clarify, let us examine this further. Our emp object contained one int data member, three
string data members and two double data members. The total number of bytes occupied by
the data members comes to 38. It is as if write( ) took a mirror image of the bytes of
information in memory and copied them directly to disc, without bothering any intervening
translation or formatting. By contrast, the character based functions take some liberties with
the data. for example, they expand the? \n ?character into a carriage return and a line feed
before storing it to disk.

Reading object from file


The program given below is intended to read the file created in the above program.

//program for reading data files


#include <istream.h>
class employees
{
protected:
int empno;
char name[I0];
char dept[5];
char desig[5];
double basic;
double deds;
public:
void showdata(void)
{
cout<<endl<<"employeenumber: "<<empno;
cout<<endl<<"empname "<<name;
cout<<endl<<"department "<<dept;
cout<<endl<<"designation "<<desig;
cout<<endl<<"basic pay "<<basic:
cout<<endl<<"deds "<<deds;
}
void main(void){
employees empl;
ifstream infile("f3.fil");
infile.read((char*)&empl, sizeof(empl));
empl.showdata( );
}
}

It may be noticed that both read( )and write( functions have similar argument. we must
specify the address in which the disc input will be placed. We also use size of to indicate
the number of bytes to be read.

The sample output looks as shown below:


employeenumber; 123
empname venkatesa
department elec
designation prog
basic pay 567.89
deds 45.76

Das könnte Ihnen auch gefallen