PROGRAMMING CONCEPT ON C



Contents:

  • Features of C-Pre-Processor and Macro Expantion.
  • Compilation.
  • Linker.
  • Storage Classes.

Features of C Pre-processor:



Pre-processor:  

After writing program in IDE before compilation it first preprocess the source code for any macros in the program, if it there then it replaces the macros with macro definition, and also excludes the white spaces and comments in the source code, copy’s the content of header file and placed in source file then create temporary modified source code file, but not modifies the source file, before hand over to compilation.

     Macro Expansion

Have a look at the following program.
#define UPPER 25
main( )
{
int i ;
for ( i = 1 ; i <= UPPER ; i++ )
printf ( "\n%d", i ) ;
}
In this program instead of writing 25 in the for loop we are writing it in the form of UPPER, which has already been defined before main( ) through the statement,
#define UPPER 25
This statement is called ‘macro definition’ or more commonly, just a ‘macro’. What purpose does it serve? During preprocessing, the preprocessor replaces every occurrence of UPPER in the program with 25. Here is another example of macro definition.
#define PI 3.1415
main( )
{
float r = 6.25 ;
float area ;
area = PI * r * r ;
printf ( "\nArea of circle = %f", area ) ;
}
UPPER and PI in the above programs are often called ‘macro templates’, whereas, 25 and 3.1415 are called their corresponding ‘macro expansions’.

Compilation

            Compiler generally refers to creation of object file form the processing of source code file.
            The compiler merely translates a program into assembly languages, assembler then translates to machine language, the file generate by name source file with extension .o or .obj
           If the compiled program is to run on a different CPU architecture from the one on which the compiler runs, the compiler is known as cross-compiler.

Compiler performs the following:


 Lexical Analysis (converts sequence of characters into tokens based on the set of rules of the language)

Parsing (break down the words into functional unit that can be converted into machine language)

Semantic Analysis (translating a string into sequence of action, each set of symbol generated will have an attribute)

Code Generation (above intermediate code representation is converted into linear sequence of machine instruction).

Code Optimization.


Linker


          Linker is a tool that merges the object files produced by separate compilation or assembly and creates an executable file (.exe).
The linker has two functions. The first, as the name implies, is to combine (link) various pieces of object code.


The second is to resolve the addresses of call and load instructions found in the object files that it is combining.

Storage Classes:

There are four storage classes in C:
(a) Automatic storage class
(b) Register storage class
(c) Static storage class
(d) External storage class

Let us examine these storage classes one by one.

Automatic Storage Class

Storage

− Memory.

Default initial value

− An unpredictable value, which is often called a garbage value.

Scope

− Local to the block in which the variable is defined.

Life

− Till the control remains within the block in which the variable is defined.


             
Following program shows how an automatic storage class variable is declared, and the fact that if the variable is not initialized it contains a garbage value.
main( )
{
auto int i, j ;
printf ( "\n%d %d", i, j ) ;
}
The output of the above program could be...
1211 221
where, 1211 and 221 are garbage values of and j. When you run this program you may get different values, since garbage values.

Register Storage Class:


Storage

CPU registers.

Default initial value

Garbage value.

Scope

Local to the block in which the variable is defined.

Life

Till the control remains within the block in which the variable is defined.

A value stored in a CPU register can always be accessed faster than the one that is stored in memory. Therefore, if a variable is used at many places in a program it is better to declare its storage class as register. A good example of frequently used variables is loop counters. We can name their storage class as register.
main( )
{
register int i ;
for ( i = 1 ; i <= 10 ; i++ )
printf ( "\n%d", i ) ;
}
Here, even though we have declared the storage class of as register, we cannot say for sure that the value of would be stored in a CPU register. Why? Because the number of CPU registers are limited, and they may be busy doing some other task. What happens in such an event... the variable works as if its storage class is auto.


Static Storage Class:

Storage

− Memory.

Default initial value

− Zero.

Scope

− Local to the block in which the variable is defined.

Life

− Value of the variable persists between different function calls.

Let’s see the example program:

Using Auto Storage Class:


main( )
 {
increment( ) ;
 increment( ) ;
 increment( ) ;
 }
increment( )
 {
 auto int i = 1 ;
 printf ( "%d\n", i ) ;
 i = i + 1 ;
 }

Output :
1
1
1

Using Static Storage Class:


main( )
{
increment( ) ;
increment( ) ;
increment( ) ;
}
increment( ) { static int i = 1 ;
printf ( "%d\n", i ) ;
i = i + 1 ;
}
Output :
1
2
3


The programs above consist of two functions main( ) and increment( ). The function increment( ) gets called from main( ) thrice. Each time it increments the value of and prints it. The only difference in the two programs is that one uses an auto storage class for variable i, whereas the other uses static storage class.

Like auto variables, static variables are also local to the block in which they are declared. The difference between them is that static variables don’t disappear when the function is no longer active. Their values persist. If the control comes back to the same function again the static variables have the same values they had last time around.

External Storage Class:

   Storage

− Memory.

   Default initial value

− Zero.

   Scope

− Global.


   Life



− As long as the program’s execution doesn’t come to an end.


External variables differ from those we have already discussed in that their scope is global, not local. External variables are declared outside all functions, yet are available to all functions that care to use them. Here is an example to illustrate this fact.

For Example:
int i ;
main( )
{
printf ( "\ni = %d", i ) ;
increment( ) ;
increment( ) ;
decrement( ) ;
decrement( ) ;
}
increment( )
{
i = i + 1 ;
printf ( "\non incrementing i = %d", i ) ;
}
decrement( )
{
i = i - 1 ;
printf ( "\non decrementing i = %d", i ) ;
}

The output would be:
i = 0
on incrementing i = 1
on incrementing i = 2
on decrementing i = 1
on decrementing i = 0

As is obvious from the above output, the value of is available to the functions increment( ) and 
decrement( ) since has been declared outside all functions.



Notes for C Programming

1. History and introduction to C .
C was developed at Bell Labs USA in 1972 by Dennis Ritchie. Dennis Ritchie is also called "father of C". The C language was developed from its predecessor language called B by Ken Thomson. The B language was developed from BCPL and in turn BCPL was developed from ALGOL.


ALGOL ------- > BCPL ----------- > B ----------------- > C -------------- > C++.

The C language was then developed into Object Oriented C++. There are 2 more languages which also come into the family of C, they are called Java, C# (C Sharp).

C was developed for writing low level or system level programs like operating system, compiler, interpreter etc. which were earlier written mostly in assembly language. The C was used to write the world famous and popular operating system called UNIX. The most modern operating system Linux is also written in C. C is the only language used for developing the system software.

2. Features of C :
There  are large number of features and advantages of C.
1. C is considered as fastest language i.e. c programs run very fast.
2. C has rich set of data types.
3. C has very large collection of library functions.
4. C has a powerful support for graphics. Most of the computer games are written is C.


3. Fundamentals of C :

a. Character set
b. Data Types
c. Words in C
d. Operators in C


a. Character set in C -
C has 3 types of characters....
     1. Alphabetic Characters - A - Z or a - z
     2. Numeric characters - 0 - 9
     3. Special Characters    - + - * / { } [ ] ( ) , . ; : ? ' " % # ! > < =
b. Data types in C -
C has 2 categories of data types...
                1. Basic Data Type.
                2. Derived Data Type.

1. Basic Data Type:
It is the original or native or fundamental data type of C language. The BDT are of 3 types...
        a. int or integer
        b. float or real data
        c. char or character data.

a. int data -
Any numeric data without decimal point or fractional point is called an int data. Optionally it may have + or - sign.
ex. 100, -456, 9000, +2626
The int again has 4 types of data....
                1. short signed int - Any number between  -32768 to 32767 is called short signed int.
                2. short unsigned int - Its range is between 0 to 65535.
                3. long signed int - it has a range from -2035654838 to 2035654837. The long int is 10 digit data.
                4. long unsigned int - it has range from 0 to  4070309675

2. float data -
Any numeric data having digits from 0 to 9 and with a decimal point is called a float data. It may have + or - sign.

ex.   0.56,  15.29293,   -200.00, 00.567, +20.456

3. char - (character)
Any single character enclosed in single quotes (' ') is called a character data. The character can be alphabet or a number or special character.

ex.  'a', '9', '+'

b. Derived data types :
The DDT are created from the basic data types. They are modifications or derivations of BDT. There are 3 types of Derived data types.
1. String
2. Array
3. Structure

1. string - A string is any single character or a collection of characters enclosed in double quotes (" ").
ex. "a", "9", "abcd", "999", "A/23", "444 602", "VijayPatil"
2. Array - an array is a collection of data of similar data types declared by a common array name.
ex.     a = {10,20,30,40,46,68}   int array
         x = {7.8,9,10,24,78} float array
3. Structure : a structure is also a collection of data but can be of different data types declared by a common structure name.
ex.   student  { int rollno, float per, char name }
        student = { 10, 78.90,"Vijay" }

E. Words in C :
There are 2 types in C language.
1. Reserved words or key words.
2. User defined words or variables.

1. Reserved words : These words are also called as key words. These are standard language words and there is set of 32 words in C. Each words has a special meaning to C compiler. The reserved words must be used with correct spellings. They are the dictionary words of C language.

ex.  int, float, char, unsigned, singed, for, while, do, goto, if, else, switch, break, case, default, struct, typedef, enum, union, void, return, sizeof, double, const, long, short etc.

2. User defined words or variables :

The User defined words are also popularly called variables. These words are created by the user or programmer in a program. A user can create any number of variables in a program. The variable is used to store some value and the value may change during the program execution. (run)

        int a;
ex    a=10     where a is a variable name and 10 is its value.
                a=a+10
        a=a-5
Rules of creating variable names....

1. A variable name must have at least one alphabet.
                ex   float r=6.9
2. The maximum length is 16 characters.
3. A blank space is not allowed in variable name.
                ex.  float  area of circle;     -   not allowed.
4. Instead of blank space an under score ( _ )
                ex.  float area_of_circle  - allowed
5. No other special symbols are allowed except underscore
 ( _ )
                ex.   area&^  - not allowed
6. A reserved word should not be used as a variable.
                ex.  for=10  - not allowed.
7. The variable name should small and easy to remember.

F. Comments in C :
A comment is a not executable statement written in a C program. The C compiler does not compile or ignores a comment. The comment is by-passed by the compiler or the comment is not treated as a part of C program. The comments are not compulsory and may not be written in a program, the program still runs. But writing comments is good habit which gives you guidelines of the program and provides documentation. A comment begins with /* and ends */.

ex.

/* this is a comments */
-------------
--------------
---------------
---------
-------------
---------------
/* this is also a comments */
--------------
---------------
------------
-------------
/* one more comment */

You can write anything in a comment. A comment may have multiple lines.

/* Program Name: Area of circle
   Date of Writing: 16-03-2004
   Author               : Alok */


G. Special codes in C :
The special codes are used to input data from keyboard and print data on screen in proper format and position. There are 2 types of special codes in C.

1. escape codes
2. format codes

  1. Escape codes in C (also called as Escape Sequence) :

The escape codes are used to print data on the screen in a proper position. Each escape code has a \ (back slash and / slash)  character and an escape character.

\n           -           newline        - to print data on newline.

                ex.   printf(" \n Welcome to C programming ");
                                printf(" \n\n\n\n Welcome to C programming ");

                                printf(" \n\n\n\n Welcome \n to \n C \n programming  ");
                                printf(" Happy programming ");              
\t                   -            tab of 6 spaces  - to print data after 6 spaces.

                ex.   printf("\n Welcome \t to \t C \t programming");       

                        printf("\n Welcome \t to \t C \t programming \t");    
                printf(" and Have fun ");

\a        -   sound a bell           -     to sound a bell from PC speaker.

                ex    printf("\n Welcome to C \a ");    
                The bell sound is used for user alerts.
\r – carriage return of return key
                ex    printf("\n Welcome to C \r ");     

\b – backspace key to effect pressing of backspace key
                ex    printf("\n Welcome to C\b ");     
\f – form feed – it is printer code to print data on the printer
                fprintf(stdprn,”\f Welcome to C programming”);
\\
\’
\”
\%   All are used to print a \ or ‘ or “ or % as a part of data

                ex    printf("\n percentage of student is 78.67\%");       
                                                percentage of student is 78.67%


2. Format codes :
These codes are also important and very regularly used in C programs to print data in proper format depending on the data type. The data types  in C....

signed int                              ( int)
unsigned int              (unsigned)
signed long                           (long)
unsigned long                      (long unsigned or unsigned long)
float                                                        (float)
char                                                        (char)

Each format code has % symbol and format character.

%d       - to input or print an int

ex   a=10;
      b=20;
      c=a+b;
     printf("\n The sum of %d and %d = %d ", a,b,c);

output :    The sum of 10 and 20 = 30

%u        - to input or print unsigned int.

ex    printf("\n Factorial   of %d = %u ",n,fact);

fact of 5 = 1*2*3*4*5

%ld   -  long int
%ul   -  long unsigned
%f    -   float

ex .  printf("\n Radius of circle = %d and area = %f ",rad, area);
%c     -  char    - to print or input character data

ex.   printf("\n Student batch code = %c ",code);

%s  - string data  -   to input or print a string data - a string is collection of characters in "  ".

name="ADITYA"
printf("\n Hello Mr. %s ",name);
               
The most commonly used format codes are .....
%d, %u, %f, %c, %s
The most commonly used escape codes are .....
\n, \t, \a

Structure of a  C program

/* This is my first C program */
# include <stdio.h>
void main( )
{
    int a,b,c;
    a=10;
    b=20;
    c=a+b;   /* ADDITION HERE */
    printf(" \n THE SUM of %d + %d = %d ",a,b,c);  /* PRINT ON THE SCREEN */
}

1. A C program should start with a comment though not necessary, it is a good habit to write comment.
2. # include statement is used to include a header file or .h file. Each header file contains large number of ready to use library functions. There are more than 25 header files in a C compiler. The most common header is stdio.h or standard input output header file.
3. Every C program must have the void main( ) function. The compiler gives serious error if main ( ) is not written.
4. The entire program is enclosed in curly brackets or braces { }.
5. A program is collection of statement or sentences each end with ; (semi colon).
6. All program variables must be declared immediately after the program starts i.e. in the beginning.
7. The C program must be written in small letters only.

Programming with C.

1. Input-output Functions :
The I/O functions are used to enter or input data from keyboard and print data on the screen. All I/O function come from the header file stdio.h or standard input/output header file. There are 8 I/O functions generally used in C programs...

1. getchar( ) and putchar( )
2. getch( ) and putch( )
3. gets() and puts()
4. printf( ) and scanf ( )

All C functions have ( ).
Out of 8 above function the first 6 functions i.e. getchar( ), putchar ( ) and getch( ) and putch() are called Non-formatted I/O functions because the format codes ( %d, %u, %f etc ) are not allowed in these functions. And the printf( ) and scanf( ) functions are called formatted I/O functions since they use format codes.

1. getchar() and putchar() -
These functions are used to enter one character data at a time from keyboard and display or print one character on the screen.

ex.

char ch;
ch=getchar();  ------------ input one character from keyboard & store into ch variable
putchar(ch);    ------------ print the value of ch variable on the screen.


program ex.

#include <stdio.h>
void main()
{
    char ch;
    ch=getchar();
    putchar(ch);
}

How to write and run a C program :
A C program is written in the C compiler' IDE (Integrated Development Environment). The most commonly used C compiler is Turbo C compiler developed by Borland Inc (American Software company).

Important commands in Turbo C compiler....

1. File - New ---- to start a new program
2. File - Save ---- To save the program on the disk  ( name.c )
3. File - Open ---- to open an already saved program ( name.c)
4. Compile - to compile the program
5. Run -  to execute the program
6. Alt - F5  -  to observe the output of the program.

2. getch( ) and putch( ) - These 2 functions are exactly same as the getchar ( ) and the putchar () functions i.e. the getch() is used to enter one character and putch() prints one character on the screen. The getch() function does not display the character at the time of input and  the putch() displays the character.

ex.

char ch;
ch=getch();
putch(ch);

3. gets() and puts () -
These 2 functions are the string functions. The gets() function inputs a string from keyboard and puts() prints a string on the screen. The gets() and puts() are the functions to be used only with string. A string is a collection of characters in double quotes "  ".

ex.

char name[20];  ---- a string is declared by char data and size of string in [ ].
puts("Enter Your Name");
gets(name);
puts("Hello Mr.");
puts(name);


1. clrscr()  - The clrscr() or clear screen function is used to clear the screen and display, display data of fresh screen. This function comes from conio.h header file.
2. getch() - This function is used to hold the screen till the user hits a key on the keyboard.


B. Formatted I/O functions :
These are most commonly and widely used functions in C program. They are called formatted I/O functions because the format codes are allowed and used in these functions. The common format codes are.....

%d  -  int data
%u  -  unsigned int
%f   -  float
%c  -  char
%s  - string

There are 2 formatted I/O function.
1. printf() - it is used to display data on screen.
2. scanf() - it is used to accept data from keyboard.

ex.
int rno;
char name[20];
float per;
printf(" \n Enter Your rollno, name, per ");
scanf(" %d \n %s \n %f ", &rno, name, &per);

The int and float and char variables must start with & symbol in the scanf( ) function when the data is to be entered from keyboard. After the data is entered the & symbol is not needed. The & symbol is not applied to a string variable.

The %f code prints 5 digits after decimal point which is incorrect in many situations like displaying percentage of a student,
%4.2f - displays data in the format of 0000.00
%6.4f  -    000000.0000
The positional format should be used only for printf() and not for scanf().

HW programs on printf() and scanf() :

1. WAP to calculate simple interest.
                sim = (pa*no*rate)/100
        total = pa+sim
        pyear = total / no
        pmonth = pyear / 12
2. WAP to convert cent to far
                f = (c-32) * (5/9)
3. WAP Area of cylinder
                area = 3.14 * (rad*rad) * ht
4. WAP program Dollars to Rupees.
5. WAP program to find energy from Einstein formula
                e = (m*c*c)

B. Programming Constructs in C
The programming constructs are vital and important part of C program and used for various purpose, depending on the type of program. There are 4 programming constructs.
                1. Loops in C
                2. Conditional constructs in C
                3. switch structure in C
                4. Control breaks in C

1. Loops in C
A loop is a set or series of statements repeated for a given number of times or till some program condition is satisfied. A loop forms an important in many C programs. There are 2 types of loops ....
a. Numeric loop - which starts from a number and ends at a number.
b. Logical loop   - which repeat till a logical condition is satisfied (Yes or No)

There are 3 loops in C...
1. for loop
2. while loop
3. do loop or do...while loop

1. for loop - It is very important and common loop for numeric processing. The for loop has 3 statements written in one line, The statements are enclosed in ( ) and separated by ;

ex.
for(i=1; i<=10; i++)
     --------------------- ;
If the repeating statements under the for loop, are more than one , then they must be enclosed in a separate { } (curly brackets).

ex.
for(i=1;i<=10;i++)
{
    ------
    ------
}


HW programs on for loop:
1. WAP to print, sum and find average of 1 to n numbers.
2. WAP to print all odd numbers from 1 to n.
3. WAP to print a multiplication table of n number.
4. WAP to print a series  1  3  2  4  3  5  4  6  5  7 ........
5. WAP to print factorial of n (5)

fact = 1*2*3*4*5

1. Logic of Fibonacci numbers ...


a=0   1    1    2    3     5
b=1   1     2   3    5     8
c=1   2     3   5    8     13

a=b
b=c
c=a+b

0 1  1  2  3  5

2. Triangular number series.

1   1
2   3
3   6
4   10
5   15
6   21
7   28

5 *  1   = 5
5 * 2    = 10
5 *  10  = 50



Variations of for loop :

Nested for loops :

When the for loops are written in 2 more or more numbers, one inside another, it becomes a nested for loop. The inner loop completes first and then the control goes to the outer and the outer loop continues...

ex.

for(i=1;i<=5;i++)                          outer loop
{
    for(j=1;j<=4;j++)                                                  inner loop          
     {
            -----
            -----
      }
}

i=1  j=1-----4  (i1j1, i1j2,i1j3,i1j4)
i=2  j=1-----4  (i2j1,i2j2,i2j3,i2j4)
.
.
.
.
i=5 j=1------4 (i5j1,i5j2,i5j3,i5j4)

for(i=1;i<=4;i++)
{
   for(j=1;j<=3;j++)
   {
       for(k=1;k<=2;k++)
        {
              -------
              -------
         }
    }
}

The nested for loops are ideally used for all types matrix or 2 dimensional array programs, the nested for loops are also used for number pyramid programs.

ex.




cccc
c
c
c
c1
1  2
1  2   3
1  2   3   4
1  2   3   4   5

1
2  2
3  3  3
4  4  4  4
5  5  5  5  5

5 5 5 5 5
4 4 4 4
3 3 3
2 2
1



1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1


                                                                                                1
                                                                                         1     2
                                                                                     1     2      3
                                                                                   1    2     3      4
                                                                                1   2     3      4     5

                                                                                                1
                                                                                         1     2
                                                                                     1     2      3
                                                                                   1    2     3      4
                                                                                1   2     3      4     5
                                                                                   1    2     3      4        
                                                                             1    2     3     
                                                                          1     2
                                                                             1

2. While loop -
The while loop is the second loop of C language. It is more commonly used as a logical loop, though this loop can also be used as a numeric loop. The ideal loop for numeric and repetitive processing is the for loop. The while loop is a numeric as well as a logical loop.

ex.

1. while as a numeric loop.

i=1;
while(i<=10)                                         for(i=1;i<=10;i++)
{                                                                                               printf("%d ",i);
    printf("%d ",i);
    i++;
}

As a numeric loop the while exactly behaves like a for loop.

1. WAP to print n Fibonacci nos using while loop.
2. WAP to print multiplication table of n with while loop.

2. while as a logical loop.
In this type, the while loop executes till some logical condition is satisfied. The logical condition can be met or satisfied by Y or N, T or F, 1 or 0 status. The loop gets executed till the condition becomes logical Y or logical N.

char ans='n';
while(ans!='y')
{
   ----
   ----
   ----
}

3. Conditional constructs in C :

C has the most commonly used if .... else conditional constructs. The constructs form an important part in C program. The if statement is followed by a condition and based on the condition some statement is executed.

ex.   if ( a > 10)
                  --------------1 ;
       -------- ;

There are 4 types of conditional constructs used in C programs.

1. Simple condition.
2. Multiple condition.
3. Complex Condition.
4. Nested condition.

1. Simple condition:
The simple condition has only one if statement followed by a condition in ( ) and if the condition becomes true a statement is executed. If there are 2 or more statements to be executed on some condition, they must be enclosed in separate { } (curly brackets).

ex.
a. if( a > 10)
       ----------

b. if (a > 10)
    {
        ------
        ------
    }

1. WAP Find largest per. in n student
2. WAP to find largest and smallest age in a group of n student and calculate average age.

addition of all even numbers in n different and find the average.

2. Multiple condition:
When a conditional construct has 2 executing statements or 2 sets of executing statement one on condition true and the second on the condition not true, it becomes a multiple condition. It is also known as 2 way condition.

ex.

if ( a > 10)
   ------- 1;
else
   ------- 2;

if ( a > 10 )
{
   -----
   -----
   ------
}
else
{
   -----
   -----
   -----
}

WAP to print eligibility for voting on the input age.
WAP to count all students who have scored 70 and above percentage and find average,
                and all students who have scored less tha 70 and its average in n number of student.

3. Complex condition:
When a logical operator is used in a condition like && ,  | |  the condition becomes the logical condition. The logical operators are used to combine 2 or more conditions.

ex.

if( a>b && a>c)
   -------------- 1;

if( a>b || a>c)
    ------------- 1;

if( (a>b && a>c ) || (x<y && x<z) )
   --------------------------;

4. switch structure in C :
A switch structure is a better alternative to nested conditions. The nested conditions may
become confusing if they enter into large number of levels, hence the ideal replacement for nested conditions is the switch structure. The switch structure is easy to handle and understand. The switch structure is a combination of 4 statements.
1. switch
2. case
3. break
4. default
A switch statement is followed by switch variable, each case is executed by a separate case statement, the case block ends by a break statement. When al possible case option are over, a default statement may be written to display an error message. The default statement is not compulsory and may not be written.

ex.
switch(var)
{
   case 1 :
       {  ----------- break; }
   case 2 :
       {  ---------- break; }
   case n :
       {   ---------- break; }
   default : ------------------------ ;
}

1. WAP to print n Fibonacci numbers, factorial of n, multiplication table of n in one program with choice a,b,c.
2. WAP to calculate area of circle, area of triangle, area of cylinder, area of square based on 1,2,3,4 choices.

5. Arrays in C :
An array is a collection of data of same data type declared by a common array name. Each data in the array is called as Element. Every element has a unique array address staring from 0 to n-1 (where n is total number of array elements).

There are 2 types of arrays....
1. Single Dimension Array
2. Multi Dimension Arrays.

1. Single Dimension Array :
In the SDA the elements are stored or represented on one dimension only. The SDA can be either int, float or char array. Array address starts from 0 to n-1 and left to right.
The SDA can be declared by the data type, name of array and the size of array in [ ].

ex.
int a[10];  -- a is an array of int type which can store max 10 numbers.
float x[5];
char name[50];
Finally an array can be processed by using a for loop that runs from 0 to n-1 where n is the size of array.

2. Multi Dimension Arrays:
When the elements of an array are represented in more than one dimensions, the array becomes a MDA. The most popular MDA are 2 - Dimensional arrays. In mathematics they are also known as Matrix. Each element in the matrix has a row and column address, each start with 0 to n-1. The rows are horizontal and columns are vertical. A matrix is declared  by the data type, name of matrix and total rows and columns in 2 [ ].

ex.

int a[3][3];   the first number is for rows and second for columns.
float  x[5][6];

A matrix is processed using 2 nested loops. The outer loop represents the rows and inner loop is foe columns.

- WAP to find the smallest and largest and average number in a matrix r,c

most common 2D Array program .

1. Addition of rows in matrix
2. addition of diagonal elements in matrix
3. transpose a matrix
4. identity matrix

- WAP to print an identity matrix ...

1  0  0  1
0  1  1  0
0  1  1  0
1  0  0  1

- WAP to print addition of diagonal elements.

1  2  3 
4  5  6
7  8  9
            15






Structures in C

1. Simple Structure:
2.  Array of structures:

In this combination of structure and array, the data members of the structure are ordinary i.e. without an array. But the variable created from the structure is in the form of an array. This combination of array & structure can hold many data records of the structure.

ex.

struct student
{
  int rno,ph,ch,ma,gt;
  char name[20];
  float per;
  char grade;
};

struct student s[10];  array of structures.
struct student r;         simple structure

The array of structures can be processed using a for loop which starts with 0 to n-1. The variable to access each data member of the structure will be ......

                ex    s[ i ].rno, s[ i ].name, s[ i ].gt        etc.

- WAP to create a saving account bank structure and print report.
struct saving
{
   int acno;
   char name[20];
   float opbal, depo, with, clbal;
};

struct saving s[20];

opbal = opening balance                   10000
depo = deposit                                                        5000   
with = withdrawal                                                    4000
clbal = closing balance                      clbal=(opbal+depo)-with


3. Structure of arrays :
In this type of array-structure combination, one more members of the structure are declared as arrays. However the variable created from the structure is non-array or ordinary.

ex.

struct student
{
   int rno,marks[3],gt;
   float per;
   char name[20];
};

stuct student s;

4. Array of structure of array :
When one or more members of a structure are declared as array and the variable created from the structure is also in the form of an array,  the entire structure is known as A of S of A. It is also called 2 dimensional structure.

struct student
{
  int rno, thmarks[3],prmarks[3],gt;
  float per;
  char name,grade;
};
struct student s[100];
int a,c,b;
float avg;

avg = (float) a+ b+ c / 3;     ====== 8.49  (8.00)


- WAP of saving bank account
 struct bank
 {
    int acno;
    char name[20];
    float opbal,with[10],depo[10],clbal;
}
struct bank b[100];


ABC Bank Ltd.
--------------------------------------------------------------------------
Acno       Name     Opbal        Depo       With     ClBal
---------------------------------------------------------------------------
1                   
2   
3
4
5
---------------------------------------------------------------------------


5. Nested structure :
It is also an important structure and makes a big data structure easier to handle. A nested structure refers to creating a structure variable as a data member in another structure. A structure may have many variables of different already defined structures.

struct address
{
     char addr[20],city[20];
     int pincode, teno;
};

struct student
{
     int rno;
     char name[20];
     struct address pa,la;
 };
struct student s;

variables:
s.rno, a.name, s.pa.telno,s.pa.city, s.la.city, s.la.addr

struct address
{
     char addr[20],city[20];
     int pincode, teno;
};
struct student
{
     int rno;
     char name[20];
     struct address pa,la;
 };
struct result
{
     struct student s;
     int ph,ch,ma,gt;
     float per;
};
struct result r;
r.ph,r.ch,r.gt ....
r.s.rno, r.s.name.....
r.s.pa.city. r.s.la.telno

While accepting (from keyboard) a string which contains blank spaces, the %s format code should not be used. The %s format code can store all characters upto first blank space and others are truncated (not stored).

scanf(%s",name);   anil  - ok
                                                    anil patil             - not ok  (anil)

%[^\n] - code can accept any number characters including blank spaces.
when the data is entered through the struct variables always flush the keyboard buffer.
fflush(stdin);
Functions in C :
A function is a small procedure or module or sub-routine or sub-program written along with the main( ) function. A function has a function name and a function body, the function contains set of statements. The function may return of pass variables or parameters. Once a functions is declared, then it ca be CALLed or invoked any number of times from other functions. A C program must contain only one main( ) function.

void main( )
{
    display( ); ------ CALL
}

void display( )   ----- function declaration
{
    printf("\n Hello and welcome to function");
}

An C program start running or executing from main( ) function. At the point of a function CALL the control passes to a function by its name. The function gets executed and at the end passes the control back to CALLing function.
Advantages of using functions
1.  The programs becomes easier to handle, maintain, debug (find and remove errors).
2.  Once a function is declared it can be invoked or CALLed any number of times.
3.  The functions improve program modularity and the functions can be easily added or removed.

If the functions are declared after the main( ) then the function prototypes (names) must be written before main( ). If the functions are declared before main( ), then the prototypes are not needed. The prototypes are like index of text book.




Pointers:
Example program : POINTER.C

 
#include <stdio.h>

int main()                         /* illustration of pointer use */
{
int index, *pt1, *pt2;

   index = 39;                             /* any numerical value */
   pt1 = &index;                          /* the address of index */
   pt2 = pt1;
   printf("The value is %d %d %d\n", index, *pt1, *pt2);
   *pt1 = 13;                  /* this changes the value of index */
   printf("The value is %d %d %d\n", index, *pt1, *pt2);

   return 0;
}

/* Result of execution

The value is 39 39 39
The value is 13 13 13

*/
 
 Simply stated, a pointer is an address. Instead of being a variable, it is a pointer to a variable stored somewhere in the address space of the program. It is always best to use an example so load the file named POINTER.C and display it on your monitor for an example of a program with some pointers in it.

For the moment, ignore the data definition statement where we define index and two other fields beginning with a star. It is properly called an asterisk, but for reasons we will see later, let's agree to call it a star. If you observe the statement in line 8, it should be clear that we assign the value of 39 to the variable named index. This is no surprise, we have been doing it for several programs now. The statement in line 9 however, says to assign to pt1 a strange looking value, namely the variable index with an ampersand in front of it. In this example, pt1 and pt2 are pointers, and the variable named index is a simple variable. Now we have a problem similar to the old chicken and egg problem. We need to learn how to use pointers in a program, but to do so requires that first we define the means of using the pointers in the program.

The following two rules will be somewhat confusing to you at first, but we need to state the definitions before we can use them. Take your time, and the whole thing will clear up very quickly.

TWO VERY IMPORTANT RULES

The following two rules are very important when using pointers and must be thoroughly understood.

A variable name with an ampersand in front of it defines the address of the variable and therefore points to the variable. You can therefore read line nine as "pt1is assigned the value of the address of index".
A pointer with a star in front of it refers to the value of the variable pointed to by the pointer. Line twelve of the program can be read as "The stored (starred) value to which the pointer pt1 points is assigned the value 13". This is commonly referred to as dereferencing the pointer. Now you can see why it is convenient to think of the asterisk as a star, it sort of sounds like the word store.
MEMORY AIDS

Think of & as an address.
Think of * as a star referring to stored.

 
 Assume for the moment that pt1 andpt2 are pointers (we will see how to define pointers shortly). As pointers, they do not contain a variable value but an address of a variable and can be used to point to a variable. Figure 8-1 is a graphical representation of the data space as it is configured just prior to executing line 8. A box represents a variable, and a box with a dot in it represents a pointer. At this time the pointers are not pointing at anything, so they have no arrows emanating from the boxes. Executing line 8 stores the value 39 in index.

Continuing execution of the program, we come to line 9 which assigns the address of the variable indexto the pointer pt1 which causes pt1 to point toindex. Since we have a pointer to index, we can manipulate the value of index by using either the variable name itself, or the pointer. Figure 8-2 depicts the condition of the data space after executing line 9 of the program.

Jumping ahead a little in the program, line 12 modifies the value of index by using the pointer. Since the pointer pt1points to the variable named index, putting a star in front of the pointer name refers to the memory location to which it is pointing. Line 12 therefore assigns the value of 13 to index. Anyplace in the program where it is permissible to use the variable name index, it is also permissible to use the name *pt1 since they are identical in meaning until the pointer is reassigned to some other variable.

ANOTHER POINTER

Just to add a little intrigue to the system, we have another pointer defined in this program, pt2. Since pt2 has not been assigned a value prior to statement 10, it doesn't point to anything, it contains garbage. Of course, that is also true of any local variable until a value is assigned to it. The statement in line 10 assigns pt2 the same address as pt1, so that now pt2 also points to the variable named index. We have copied the address from one pointer to another pointer. To continue the definition from the last paragraph, anyplace in the program where it is permissible to use the variable index, it is also permissible to use the name *pt2 because they are now identical in meaning. This fact is illustrated in the printf() statement in line 11 since this statement uses the three means of identifying the same variable to print out the same variable three times. Refer to figure 8-3 for the representation of the data space at this time.

THERE IS ONLY ONE VARIABLE

Note carefully that, even though it appears that there are three variables, there is really only one variable. The two pointers each point to the single variable. This is illustrated in the statement in line 12 which assigns the value of 13 to the variable index, because that is where the pointer pt1 is pointing. The printf() statement in line 13 causes the new value of 13 to be printed out three times. Keep in mind that there is really only one variable to be changed or printed, not three. We do have three aliases for one variable, index, *pt1, and *pt2. Figure 8-4 is the graphical representation of the data space at this time.

This is admittedly a very difficult concept, but since it is used extensively in all but the most trivial C programs, it is well worth your time to stay with this material until you understand it thoroughly.

HOW DO YOU DEFINE A POINTER?

Now to keep a promise and tell you how to define a pointer. Refer to line 6 of the program and you will see our old familiar way of defining the variable index, followed by two more definitions. The second definition can be read as "the storage location to which pt1 points will be an int type variable". Therefore, pt1 is a pointer to an int type variable. Likewise, pt2 is another pointer to an int type variable, because it has a star (asterisk) in front of it. These two pointers can point to the same int variable or to two different int variables.

A pointer must be defined to point to a specific type of variable. Following a proper definition, it cannot be used to point to any other type of variable or it will result in a type incompatibility error.

Compile and run this program and observe that there is only one variable and the single statement in line 12 changes the one variable which is displayed three times. This material is so important that you should review it carefully if you do not fully understand it at this time. It would be a good exercise for you to draw the graphics yourself as you review the code for this program.

THE SECOND PROGRAM WITH POINTERS

Example program : POINTER2.C

 
 /* POINTER2.C */

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

int main()
{
char strg[40], *there, one, two;
int  *pt, list[100], index;

   strcpy(strg, "This is a character string.");

   one = strg[0];                    /* one and two are identical */
   two = *strg;
   printf("The first output is %c %c\n", one, two);

   one = strg[8];                   /* one and two are indentical */
   two = *(strg+8);
   printf("The second output is %c %c\n", one, two);

   there = strg+10;          /* strg+10 is identical to &strg[10] */
   printf("The third output is %c\n", strg[10]);
   printf("The fourth output is %c\n", *there);

   for (index = 0 ; index < 100 ; index++)
      list[index] = index + 100;
   pt = list + 27;
   printf("The fifth output is %d\n", list[27]);
   printf("The sixth output is %d\n", *pt);

   return 0;
}

/* Result of execution

The first output is T T
The second output is a a
The third output is c
The fourth output is c
The fifth output is 127
The sixth output is 127

*/

 
 In these few pages so far on pointers, we have covered a lot of territory, but it is important territory. We still have a lot of material to cover so stay in tune as we continue this important aspect of C. Load the next file named POINTER2.C and display it on your monitor so we can continue our study.

In this program we have defined several variables and two pointers. The first pointer named there is a pointer to a char type variable and the second named ptpoints to an int type variable. Notice also that we have defined two array variables named strg and list. We will use them to show the correspondence between pointers and array names.

 
 Figure 8-5 depicts the data just prior to executing line 10. There are three variables, two pointers, a string, and an array of ints, or we could say there are three variables, two pointers, and two arrays. Each array is composed of the array itself and a pointer which points to the beginning of the array according to the definition of an array in C. This will be completely defined in the next paragraph. Each array is composed of a number of identical elements of which only a few at the beginning and a few at the end are depicted graphically for convenience.

AN ARRAY NAME IS ACTUALLY A POINTER

In the C programming language, an array name is defined to be a constant pointer to the beginning of the array. This will take some explaining. Refer to the example program on your monitor. You will notice that in line 10 we assign a string constant to the string variable named strg so we will have some data to work with. Next, we assign the value of the first element to the variable one, a simple char variable. Next, since the string name is a constant pointer to the first element of the string, by definition of the C language, we can assign the same value to two by using the star and the string name (*strg). Observe that the box with a dot pointing to a variable can be used to access the variable just like in the last program. The result of the two assignments are such that one now has the same value as two, and both contain the character T, the first character in the string. Note that it would be incorrect to write line 10 as two = *strg[0]; because the star takes the place of the square brackets, or does the same job.

For all practical purposes, strg is a pointer to a chartype variable. It does, however, have one restriction that a true pointer does not have. It cannot be changed like a variable, but must always contain the address of the first element of the string and therefore always points to the beginning of its string. It is a pointer constant. Even though it cannot be changed, it can be used to refer to other values than the one it is defined to point to, as we will see in the next section of the program.

Moving ahead to line 16, the variable one is assigned the value of the ninth character in the string (since the indexing starts at zero) and two is assigned the same value because we are allowed to index a pointer to get to values farther ahead in the string. Both variables now contain the character 'a'. Line 17 says to add 8 to the value of the pointer strg, then get the value stored at that location and store it in the variable two.

 POINTER INDEXING

The C programming language takes care of indexing for us automatically by adjusting the indexing for the type of variable the pointer is pointing to. In this case, the index of 8 is simply added to the pointer value before looking up the desired result because a char type variable is one byte long. If we were using a pointer to an int type variable, the index would be doubled and added to the pointer before looking up the value because an int type variable uses two bytes per value on most 16 bit microcomputers. It would multiply the index value by 4 before adding it to the pointer if an int used four bytes, as it does on most 32 bit systems. When we get to the chapter on structures, we will see that a variable can have many, even into the hundreds or thousands, of bytes per variable, but the indexing will be handled automatically for us by the system.

The data space is now in the state defined graphically in figure 8-6. The string named strg has been filled and the two variables named one and two have the letter "a" stored in them. Since the pointer variable there is already a pointer, it can be assigned the address of the 11th element of strg by the statement in line 20 of this program. Remember that since there is a pointer to type char, it can be assigned any value as long as that value represents a char type of address. It should be clear that the pointers must be typed in order to allow the pointer arithmetic described in the last paragraph to be done properly. The third and fourth outputs will be the same, namely the letter c.


 POINTER ARITHMETIC

Not all forms of arithmetic are permissible on a pointer. Only those things that make sense, considering that a pointer is an address somewhere in the computer. It would make sense to add a constant to an address, thereby moving it ahead in memory that number of places. Likewise, subtraction is permissible, moving it back some number of locations. Adding two pointers together would not make sense because absolute memory addresses are not additive. Pointer multiplication is also not allowed, as that would be a funny number. If you think about what you are actually doing, it will make sense to you what is allowed, and what is not.

NOW FOR AN INTEGER POINTER

The array named list is assigned a series of values from 100 to 199 in order to have some data to work with in lines 24 and 25. Next, we assign the pointer pt the address of the 28th element of the list and print out the same value both ways to illustrate that the system truly will adjust the index for the int type variable. You should spend some time in this program until you feel you fairly well understand these lessons on pointers.

Compile and execute POINTER2.C and study the output. At the termination of execution, the data space will be as depicted in figure 8-7. Once again, it would be a good exercise for you to attempt to draw the graphic for this program as you review the code.


 FUNCTION DATA RETURN WITH A POINTER

Example program :TWOWAY.C

 
/*TWOWAY.C */

#include <stdio.h>
void fixup(int nuts, int *fruit);

int main()
{
int pecans, apples;

   pecans = 100;
   apples = 101;
   printf("The starting values are %d %d\n", pecans, apples);

                                /* when we call "fixup"          */
   fixup(pecans, &apples);      /* we take the value of pecans   */
                                /* we take the address of apples */

   printf("The ending values are %d %d\n", pecans, apples);

   return 0;
}


void fixup(int nuts, int *fruit)   /* nuts is an integer value   */
                                   /* fruit points to an integer */
{
   printf("The values are %d %d\n", nuts, *fruit);
   nuts = 135;
   *fruit = 172;
   printf("The values are %d %d\n" ,nuts, *fruit);
}



/* Result of execution

The starting values are 100 101
The values are 100 101
The values are 135 172
The ending values are 100 172

*/

 
 You may recall that back in the lesson on functions we mentioned that there were two ways to get variable data back from a function. One way is through use of the array, and you should be right on the verge of guessing the other way. If your guess is through use of a pointer, you are correct. Load and display the example program named TWOWAY.C for an example of this.

In TWOWAY.C, there are two variables defined in the main program, pecans and apples. Notice that neither of these is defined as a pointer. We assign values to both of these and print them out, then call the function named fixup() taking both of these values along with us. The variable pecans is simply sent to the function, but the address of the variable applesis sent to the function. Now we have a problem. The two arguments are not the same, the second is a pointer to a variable. We must somehow alert the function to the fact that it is supposed to receive an integer variable and a pointer to an integer variable. This turns out to be very simple. Notice that the parameter definitions in line 23 defines nuts as an integer, and fruit as a pointer to an integer. The call in the main program therefore is now in agreement with the function heading and the program interface will work just fine.

 
 In the body of the function, we print the two values sent to the function, then modify them and print the new values out. This should be perfectly clear to you by now. The surprise occurs when we return to the main() function and print out the two values again. We will find that the value of pecans will be restored to the value it had prior to the function call because the C language makes a copy of the item in question and takes the copy to the called function, leaving the original intact as we explained earlier. In the case of the variable apples, we made a copy of a pointer to the variable and took the copy of the pointer to the function. Since we had a pointer to the original variable, even though the pointer was a local copy, it pointed to the original variable and we could change the value of apples from within the function. When we returned to the main program, we found a changed value in apples when we printed it out.

This is illustrated graphically in figure 8-8. The state of the system is illustrated following execution of line 27 of the program. The observant student will notice the prototype in line 3. This allows the compiler to check the type of both parameters when it gets to line 14 where the function is called.

By using a pointer in a function call, we can have access to the original data while excuting code within the function and change it in such a way that when we return to the calling program, we have a changed value of the original variable. In this example, there was no pointer in the main program because we simply sent the address to the function, but in many programs you will use pointers in function calls. One of the places you will find need for pointers in function calls will be when you request data input using standard input/output routines. These will be covered in the next two chapters. Compile and run TWOWAY.C and observe the output.

POINTERS ARE VALUABLE

Even though you are probably somewhat intimidated by this time about the proper use of pointers, you will find that after you gain experience, you will use them profusely in many ways. You will also use pointers in every program you write other than the most trivial because they are so useful. You should probably go over this material carefully several times until you feel comfortable with it because it is very important in the area of input/output which is next on the agenda.




A POINTER TO A FUNCTION


Example program : FUNCPNT.C

#include <stdio.h>

void print_stuff(float data_to_ignore);
void print_message(float list_this_data);
void print_float(float data_to_print);

void (*function_pointer)(float);

int main()
{
float pi = 3.14159;
float two_pi = 2.0 * pi;

   print_stuff(pi);
   function_pointer = print_stuff;
   function_pointer(pi);
   function_pointer = print_message;
   function_pointer(two_pi);
   function_pointer(13.0);
   function_pointer = print_float;
   function_pointer(pi);
   print_float(pi);

   return 0;
}


void print_stuff(float data_to_ignore)
{
   printf("This is the print stuff function.\n");
}


void print_message(float list_this_data)
{
   printf("The data to be listed is %f\n", list_this_data);
}


void print_float(float data_to_print)
{
   printf("The data to be printed is %f\n", data_to_print);
}


/* Result of execution

   This is the print stuff function.
   This is the print stuff function.
   The data to be listed is 6.283180
   The data to be listed is 13.000000
   The data to be printed is 3.141590
   The data to be printed is 3.141590

*/

 
 Examine the example program named FUNCPNT.C for the most unusual pointer yet. This program contains a pointer to a function, and illustrates how to use it.

Line 8 of this program defines function_pointer as a pointer to a function and not to just any function, it points to a function with a single formal parameter of type float. The function must also return nothing because of the void before the pointer definition. The parentheses are required around the pointer name as illustrated or the system will think it is a prototype definition for a function that returns a pointer to void.

You will note the prototypes given in lines 4 through 6 that declare three functions that use the same parameter and return type as the pointer. Since they are the same as the pointer, the pointer can be used to refer to them as is illustrated in the executable part of the program. Line 15 contains a call to the print_stuff() function, and line 16 assigns the value of print_stuff to function_pointer. Because the name of a function is defined as a pointer to that function, its name can be assigned to a function pointer variable. You will recall that the name of an array is actually a pointer constant to the first element of the array. In like manner, a function name is actually a pointer constant which is pointing to the function itself. The pointer is successively assigned the address of each of the three functions and each is called once or twice as an illustration of how a pointer to a function can be used.

A function pointer can be passed to another function as a parameter and can be used within the function to call the function which is pointed to. You are not permitted to increment or add a constant to a function pointer, it can only be assigned the value of a function with the same parameters and return with which it was initially declared. It may take you a little time to appreciate the value of this construct, but when you do understand it, you will see the flexibility built into the C programming language.

A pointer to a function is not used very often but it is a very powerful construct when needed. You should plan to do a lot of C programming before you find a need for this technique. I mention it here only to prevent you being unduly intimidated by this difficult concept. We will continue to study pointers by examining their use in additional example programs.

 PROGRAMMING EXERCISES

Define a character array and use strcpy() to copy a string into it. Print the string out by using a loop with a pointer to print out one character at a time. Initialize the pointer to the first element and use the double plus sign to increment the pointer. Use a separate integer variable to count the characters to print.
Modify the program from programming exercise 1 to print out the string backwards by pointing to the end and using a decrementing pointer.





OUTPUT TO A FILE

Example program : FORMOUT.C
/* FORMOUT.C */

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

int 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 */

   return 0;
}

/* Result of execution

(The following is written to the file named TENLINES.TXT)

This is an example line.  Line number 1
This is an example line.  Line number 2
This is an example line.  Line number 3
This is an example line.  Line number 4
This is an example line.  Line number 5
This is an example line.  Line number 6
This is an example line.  Line number 7
This is an example line.  Line number 8
This is an example line.  Line number 9
This is an example line.  Line number 10
*/
 
 Load and display the file named FORMOUT.C for your first example of writing data to a file. We begin as before with the include statement for stdio.h, and include the header for the string functions. Then we define some variables for use in the example including a rather strange looking new type.

The type FILE is a structure (we will study structures in the next chapter) and is defined in the stdio.h file. It is used to define a file pointer for use in file operations. The definition of C requires a pointer to a FILE type to access a file, and as usual, the name can be any valid variable name. Many writers use fp for the name of this first example file pointer so I suppose we should start with it too.
 
 OPENING A FILE

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 filename is. We do this with the
 fopen() function illustrated in line 11 of the program. The file pointer,fp in our case, will
}point to the structure for the file and two arguments are required for this function, the
 filename first, followed by the file attribute. The filename is any valid filename for your
operating system, 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 overwritten. If you don't have a file by this name, this program will create
one and write some data into it.

Note that we are not forced to use a string constant for the file name as we have done here. This is only done here for convenience. We can use a string variable which contains the filename then use any method we wish to fill in the name of the file to open. This will be illustrated later in this chapter.
 
 READING ("r")

The second parameter is the file attribute and can be any of three letters, "r", "w", or "a", and must be lower case. There are actually additional attributes available in C to allow more flexible I/O, and after you complete your study of this chapter, you should check the documentation for your compiler to study the additional file opening attributes. 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. 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. It is not checked in this program, but could be easily checked as follows.

     if (fp == NULL) {
        printf("File failed to open\n");
        exit (1);
     }


Good programming practice would dictate that all file pointers be checked to assure proper file opening in a manner similar to the above code. The value of 1 used as the parameter of exit() will be explained shortly.

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 deletion of any data already there. If the file fails to open for any reason, a NULL will be returned so the pointer should be tested as above.




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 set to the end of the data already contained in the file so that new data will be added to any data that already exists in the file. Once again, the return value can and should be checked for proper opening.

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, 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 the operating system. It would be good programming practice for you to get in the habit of closing 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 in your current directory for a file named TENLINES.TXT and examine it's contents. That is where your output will be. Compare the output with that specified in the program. It should agree. If you add the pointer test code described above, and if the file couldn't be opened for any reason, there will be one line of text on the monitor and the file will be empty.

Do not erase the file named TENLINES.TXT yet. We will use it in some of the other examples in this chapter.
 
 OUTPUTTING A SINGLE CHARACTER AT A TIME

Example program : CHAROUT.C

/* CHAROUT.C */

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

int main()
{
FILE *point;
char others[35];
int  indexer, count;

   strcpy(others, "Additional lines.");
   point = fopen("tenlines.txt", "a");     /* open for appending   */
   if (point == NULL)
   {
      printf("File failed to open\n");
      exit (EXIT_FAILURE);
   }

   for (count = 1 ; count <= 10 ; count++)
   {
      for (indexer = 0 ; others[indexer] ; indexer++)
         putc(others[indexer], point);     /* output one character */
      putc('\n', point);                   /* output a linefeed    */
   }
   fclose(point);

   return EXIT_SUCCESS;
}

/* Result of output (appended to TENLINES.TXT)

Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.

*/

Load the next example file, CHAROUT.C, and display it on your monitor. This program will illustrate how to output a single character at a time.

The program begins with the include statements, then defines some variables including a file pointer. The file pointer is named point this time, but we could have used any other valid variable name. We then define a string of characters to use in the output function using a strcpy() function. We are ready to open the file for appending and we do so with the fopen() function, except this time we use the lower cases for the filename. This is done simply to illustrate that some operating systems don't care about the case of the filename. Some operating systems, including UNIX, are case sensitive for filenames, so you will need to fix the case before compiling and executing this program. Notice that the file will be opened for appending so we will add to the lines inserted during the last program. If the file could not be opened properly, a NULL value is returned by the fopen() function.

Lines 14 through 18 check to see if the file opened properly and returns an error indication to the operating system if it did not. The constant named EXIT_FAILURE is defined in the stdlib.h file and is usually defined to have the value of 1. The constant named EXIT_SUCCESS is also defined in the stdlib.h file and is usually defined to have the value of 0. The operating system can use the returned value to determine if the program operated normally and can take appropriate action if neccessary. For example, if a two part program is to be executed and the first part returns an error indication, there is no need to execute the second part of the program. Your compiler probably executes in several passes with each successive pass depending on successful completion of the previous pass.

The program is actually two nested for loops. The outer loop is simply a count to ten so that we will go through the inner loop ten times. The inner loop calls the function putc() repeatedly until a character in the string named others is detected to be a zero. This is the terminating null for the string.

THE putc() FUNCTION

The part of the program we are interested in is the putc() function in line 23. It outputs one character at a time, the character being the first argument in the parentheses and the file pointer being the second and last argument. Why the designer of C made the pointer first in the fprintf() function, and last in the putc() function is a good question for which there may be no answer. It seems like this would have been a good place to have used some consistency.

When the textline others is exhausted, a newline is needed because a newline was not included in the definition above. A single putc() is then executed which outputs the \n character to return the carriage and do a linefeed.

When the outer loop has been executed ten times, the program closes the file and terminates. Compile and run this program but once again there will be no output to the monitor. You need to assure that TENLINES.TXT is in the current directory prior to execution.

Following execution of the program, examine the contents of the file named TENLINES.TXT and you will see that the 10 new lines were added to the end of the 10 that already existed. If you run it again, yet another 10 lines will be added. Once again, do not erase this file because we are still not finished with it.
 
 READING A FILE

Example program : READCHAR.C

/* READCHAR.C */

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

int main()
{
FILE *funny;
int c;

   funny = fopen("TENLINES.TXT", "r");

   if (funny == NULL)
   {
      printf("File doesn't exist\n");
      exit (EXIT_FAILURE);
   }
   else
   {
      do
      {
         c = getc(funny);    /* get one character from the file */
         putchar(c);         /* display it on the monitor       */
      } while (c != EOF);    /* repeat until EOF (end of file)  */
   }
   fclose(funny);

   return EXIT_SUCCESS;
}

/* Result of execution

This is an example line.  Line number 1
This is an example line.  Line number 2
This is an example line.  Line number 3
This is an example line.  Line number 4
This is an example line.  Line number 5
This is an example line.  Line number 6
This is an example line.  Line number 7
This is an example line.  Line number 8
This is an example line.  Line number 9
This is an example line.  Line number 10
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.

*/

 
 Load the file named READCHAR.C and display it on your monitor. This is our first program which can read from a file. This program begins with the familiar include statements, 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 from this file. 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 exist, we print a message and quit. If the file does not exist, the system will set the pointer equal to NULL which we test in line 12. If the pointer is NULL we display a message and terminate the program.

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.


CAUTION

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 returns a minus one for an EOF. An unsigned char type variable is not capable of containing a negative value. An unsigned char type variable can only have the values of zero to 255, so it will return a 255 for a minus one which can never compare to the EOF. 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 use a int type variable when the return can be an EOF, because an int is always signed. According to the ANSI-C standard, a char can be implemented as either a signed or an unsigned type by any particular compiler.

Some compilers use a char type that is not 8 bits long. If your compiler uses other than 8 bits for a char type variable, the same arguments apply. Do not use an unsigned type if you need to check for an EOF returned by the function, because an EOF is usually defined as -1 which cannot be returned in an unsigned type variable.

There is yet 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. In a real production program, you would not actually terminate the program. You would give the user the opportunity to enter another filename for input. We are interested in illustrating the basic file handling techniques here, so we are using a very simple error handling method.
 


READING A WORD AT A TIME

Example program : READTEXT.C

/* READTEXT.C */

#include <stdio.h>

int main()
{
FILE *fp1;
char oneword[100];
int c;

   fp1 = fopen("TENLINES.TXT", "r");

   do
   {
      c = fscanf(fp1, "%s", oneword); /* get one word from file    */
      printf("%s\n", oneword);        /* display it on the monitor */
   } while (c != EOF);                /* repeat until EOF          */

   fclose(fp1);

   return 0;
}



/* Result of execution

This
is
an
example
line.
Line
number
1
This
is
an
 ... (Many other lines) ...
Additional
lines.
Additional
lines.
lines.

*/

 
 Load and display the file named READTEXT.C for an example of how to read a word at a time. This program is nearly identical to the last except that this program uses the fscanf() function to read in a string at a time. Because the fscanf() function stops reading when it finds a space or a newline character, it will read a word at a time, and display the results one word to a line. You will see this when you compile and run it, but first we must examine a programming problem.

It is left as an exercise for the student to include a check for proper file opening and performing a meaningful response if it does not open. A meaningful response is to simply output an error message and exit to the operating system.

THIS IS A PROBLEM

Inspection of the program will reveal that when we read data in and detect the EOF, we print out something before we check for the EOF resulting in an extra line of printout. What we usually print out is the same thing printed on the prior pass through the loop because it is still in the buffer named oneword. We therefore must check for EOF before we execute the printf() function. This has been done in READGOOD.C, which you will shortly examine, compile, and execute.

Compile and execute the program we have been studying, READTEXT.C and observe the output. If you haven't changed TENLINES.TXT you will end up with "Additional" and "lines." on two separate lines with an extra "lines." displayed at the end of the output because of the printf() before checking for EOF. Note that some compilers apparently clear the buffer after printing so you may get an extra blank line instead of two lines with "lines." on them.

Notice that we failed to check that the file opened properly. This is very poor practice, and it will be left as an exercise for you to add the required code to do so in a fashion similar to that used in the READCHAR.C example program.

NOW LET'S FIX THE PROBLEM

Example program : READGOOD.C


 
 /* READGOOD.C */ 

#include <stdio.h>

int main()
{
FILE *fp1;
char oneword[100];
int c;

   fp1 = fopen("TENLINES.TXT", "r");

   do
   {
      c = fscanf(fp1, "%s", oneword); /* get one word from file    */
      if (c != EOF)
         printf("%s\n", oneword);     /* display it on the monitor */
   } while (c != EOF);                /* repeat until EOF          */

   fclose(fp1);

   return 0;
}



/* Result of execution

This
is
an
example
line.
Line
number
1
This
is
 ... (Many other lines.) ...
Additional
lines.
Additional
lines.

*/

 
 Compile and execute READGOOD.C and observe that the extra "lines." does not get displayed because of the extra check for the EOF in the middle of the loop. This was also the problem referred to when we looked at READCHAR.C, but I chose not to expound on it there because the error in the output was not so obvious.

Once again there is no check for the file opening properly, but you know how to fix it by now and you should do so as an exercise.

We should point out that an experienced C programmer would not write the code as given in this example because it compares c to EOF twice during each pass through the loop and this is inefficient. We have been using code that works and is very easy to understand, but as you gain experience with C, you will begin to use more efficient coding methods, even if they tend to become harder to read and understand. An experienced C programmer would code lines 12 through 17 of READGOOD.C in the following manner;

   while((c = fscanf(fp1, "%s", oneword) != EOF)
   {
      printf("%s\n", oneword);
   }

There is no question that this code is more difficult to read, but if you spend some time studying it, you will find that it is identical to the code in the example program. Even though is is more efficient, it is not clear whether the slight gain in efficiency is worth the reduced readability. If the program saves ten milliseconds when reading in a file once a day, and it takes a programmer an hour longer to make a modification to the code a year after the program is released, there is not much savings in using such code. Even though the time assumptions are all judgement calls in the above text, it is plain to see that there are often tradeoffs when writing a program. You will make many decisions concerning execution efficiency and readability when you are writing non-trivial programs.

This is a rather contrived example, because most experienced C programmers would not think this code is at all cryptic, but is written in a standard C notation. As you gain experience, you will come to accept this as clearly written C code. The philosophical argument about code complexity and readability has been made however, and should be considered for all software development.

FINALLY, WE READ A FULL LINE

Example program : READLINE.C

/* READLINE.C */

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

int main()
{
FILE *fp1;
char oneword[100];
char *c;

   fp1 = fopen("TENLINES.TXT", "r");
   if (fp1 == NULL)
   {
      printf("File failed to open\n");
      exit (EXIT_FAILURE);
   }

   do
   {
      c = fgets(oneword, 100, fp1);  /* get one line from the file */
      if (c != NULL)
         printf("%s", oneword);      /* display it on the monitor  */
   } while (c != NULL);              /* repeat until NULL          */

   fclose(fp1);

   return EXIT_SUCCESS;
}

/* Result of execution

This is an example line.  Line number 1
This is an example line.  Line number 2
This is an example line.  Line number 3
This is an example line.  Line number 4
This is an example line.  Line number 5
This is an example line.  Line number 6
This is an example line.  Line number 7
This is an example line.  Line number 8
This is an example line.  Line number 9
This is an example line.  Line number 10
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.
Additional lines.

*/
Load and display the file READLINE.C for an example of reading a complete line. This program is very similar to those we have been studying except that we read a complete line in this example program.

We are using fgets() which reads an entire line, including the newline character, into a buffer. The buffer to be read into is the first argument in the function call, and the maximum number of characters to read is the second argument, followed by the file pointer. This function will read characters into the input buffer until it either finds a newline character, or it reads the maximum number of characters allowed minus one. It leaves one character for the end of string null character. In addition, if it finds an EOF, it will return a value of NULL. In our example, when the EOF is found, the pointer named c will be assigned the value of NULL. NULL is defined as zero in your stdio.h file.

When we find that the pointer named c has been assigned the value of NULL, we can stop processing data, but we must check before we print just like in the last program. Last of course, we close the file.

HOW TO USE A VARIABLE FILENAME

Example propgram : ANYFILE.C

/* ANYFILE.C */

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

int main()
{
FILE *fp1;
char oneword[100], filename[25];
char *c;

   printf("Enter filename -> ");
   scanf("%s", filename);            /* read the desired filename  */
   fp1 = fopen(filename, "r");
   if (fp1 == NULL)
   {
      printf("File failed to open\n");
      exit (EXIT_FAILURE);
   }

   do
   {
      c = fgets(oneword, 100, fp1);  /* get one line from the file */
      if (c != NULL)               
         printf("%s", oneword);      /* display it on the monitor  */
   } while (c != NULL);              /* repeat until NULL          */

   fclose(fp1);

   return EXIT_SUCCESS;
}



/* Result of execution

(The file selected is listed on the monitor)

*/

 
 Load and display the program ANYFILE.C for an example of reading from any file. This program asks the user for the filename desired, and reads in the filename, storing it in a string. Then it opens that file for reading. The entire file is then read and displayed on the monitor. It should pose no problems to your understanding so no additional comments will be made.

Compile and run this program. When it requests a filename, enter the name and extension of any text file available, even one of the example C programs.

Enter an invalid file name to see what the system does when it cannot open the file. If you were a user of this program, and possibly not very computer literate, would you prefer that the program gave you a cryptic message of some sort, or would you prefer that the program displayed a neat message such as "The file you have asked for is not available. Would you like to enter another filename?". Of course this is the message that you can emit when you find that the file did not open properly. Your users will appreciate the effort you put into error handling for their program.

HOW DO WE PRINT?

Example program : PRINTDAT.C
/* PRINTDAT.C */

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

int main()
{
FILE *funny, *printer;
int c;

   funny = fopen("TENLINES.TXT", "r");   /* open input file        */
   if (funny == NULL)
   {
      printf("File failed to open\n");
      exit (EXIT_FAILURE);
   }

   printer = fopen("PRN", "w");          /* open printer file      */
   if (printer == NULL)
   {
      printf("Printer not available for use\n");
      exit (EXIT_FAILURE);
   }

   do
   {
      c = getc(funny);       /* get one character from the file    */
      if (c != EOF)
      {
         putchar(c);         /* display it on the monitor          */
         putc(c, printer);   /* print the character                */
      }
   } while (c != EOF);       /* repeat until EOF (end of file)     */

   fclose(funny);
   fclose(printer);

   return 0;
}

/* Result of execution

(The file named TENLINES.TXT is listed
            on the printer, and it is listed on the monitor.)

*/

 
 Load the last example program in this chapter, the one named PRINTDAT.C for an example of how to print. This program should not present any surprises to you, so we will move very quickly through it.

Once again, we open TENLINES.TXT for reading and we open PRN for writing. Printing is identical to writing data to a disk file except that we use a standard name for the filename. Many C compilers use the reserved filename of PRN that instructs the compiler to send the output to the printer. There are other names that are used occasionally such as LPT, LPT1, or LPT2. Check the documentation for your particular compiler. Some of the newest compilers use a predefined file pointer such as stdprn for the print file. Once again, check your documentation.

The program is simply a loop in which a character is read, and if it is not the EOF, it is displayed and printed. When the EOF is found, the input file and the printer output files are both closed. Note that good programming practice includes checking both file pointers to assure that the files opened properly. You can now erase TENLINES.TXT from your disk. We will not be using it in any of the later chapters.

A READING ASSIGNMENT

Spend some time studying the documentation for your compiler and reading about the following functions. You will not understand everything about them but you will get a good idea of how the library functions are documented.

fopen(), fclose(), putc(), putchar(), printf(), fprintf(), scanf(), fgets()

Also spend some time studying stdio.h, looking for prototypes for the above functions and for the declaration of FILE.

PROGRAMMING EXERCISES

Write a program that will prompt for a filename for an input file, prompt for a filename for a write file, and open both plus a file to the printer. Enter a loop that will read a character, and output it to the file, the printer, and the monitor. Stop at EOF.
Prompt for a filename to read. Read the file a line at a time and display it on the monitor with line numbers.
Modify ANYFILE.C to test if the file exists and print a message if it doesn't. Use a method similar to that used in READCHAR.C.




We'll keep on updating the information regularly please fallow the blog...!!!

1 comment:

  1. Hi Guys I was searcing for previous years IBPS and other bank exams. It was available online but solutions was not there. But now you can find all recent bank solved papers here - http://www.kidsfront.com/govt-jobs-exams/sbi-PO.html

    ReplyDelete