SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
C Programming
by Mani Sridharan

All Rights Reserved. No part of this material may be reproduced or modified by any means without written permission from
Sridharan Mani.

Warning and Disclaimer:
This material is designed to provide information about „C‟ Language. Every effort has been made to make this material as
complete and as accurate as possible, but no warranty or fitness is implied.

The information is provided on an “as is” basis. The authors, distributors and publishers shall have neither liability nor
responsibility to any person or entity with respect to any loss or damages arising from the information contained in this book or
from the use of the programs that may accompany it.




                                             Mani Sridharan – bdmsts@gmail.com
Welcome to the Land of 'C'
       'C' is a programming language developed by Dennis Richie & Kerningham. It standards between 2nd
     rd
and 3 generation languages. It is a powerful language for Business & Scientific applications. It can be used
for writing commercial applications like financial accounting, banking operations as well as scientific
applications like controlling a robot, electrical furnaces, nuclear reactors and so on. Some of the popular
packages written out of 'C' are

                 UNIX    - Operating System.
                 C++     - Compiler.
                 SYBASE,ORACLE - RDBMS.

        Before we start looking at 'C' as a language, let us have a look over the generation of languages. Let
us understand the term language. Language is a method for communication. Assume an Indian wants to
discuss about building construction with a Mexican. Here the Indian and the Mexican should have some
standards for discussions. Basically they have to communicate by means of a common channel which both
of them can understand. Assume the Spaniard knows only 'Spanish' and the Indian knows only 'Hindi'. There
will be a lot of misunderstanding during the communication.

      The computer understands only Zeroes and Ones and we need to communicate in Zeroes and Ones.
Hence, the MACHINE Language was introduced and it forms the First Generation Language. Machine
Language instructions were made of ones & zeroes that could be easily understand by the computer.

Exercise:
Why a computer can understand only Zeroes & Ones and not other numbers ?

                                     GENERATION OF LANGUAGES

First Generation Language:
       First Generation Language is also known MACHINE LANGUAGE. Instructions are in binary
format. All the instructions were in zeroes and ones. For Example if you want to add two numbers, say 5 &
6, in MACHINE LANGUAGE for Intel 80586 processor. You need to type the instruction as
101110000000010100000000 101110110000011000000000 0000000111011000

        Machine Language is highly complex to write. It is also processor dependant. No conversion of
instructions is required as it is in the host language and faster in execution.

Second Generation Language:
        It is also known as Assembly Language. Here the instruction set is in simple English. For each
instruction in Machine Language a mnemonic code is given.

          For example 10111000 -> MOV AX,
                     00000001 11011000-> Add AX,BX

          For adding 5 + 6, the instructions in assembly language would be

                 MOV AX, 0005
                 MOV BX, 0006
                 ADD AX, BX

          Now AX will contain 000B(in hex) -> 00000000000010011(in binary)



                                        Mani Sridharan – bdmsts@gmail.com
Assembly Language was easy to write. But it required a lot of skills in writing programs, since
accessing of memory and device interfacing had be done directly. The language is also processor dependant.
If we write a program for the Motorola 68020 processor, the program cannot be compiled and executed in
80486 Intel processor. Similarly, if we write a program for 80286 processor with advanced instructions of
80286, it is not possible to run the same program in the 8088 processor. Even though it is as faster as
Machine Language, it is not portable across the system.

       Conversion from Mnemonic code to Machine code should be done before executing the program.
The programmer‟s language is in simple English Mnemonic codes and the host language is in Bits. For
converting Assembly code to Machine an Assembler is used.

       Two of the popular Assemblers are the TASM(Turbo Assembler) and the MASM(Macro Assembler).

Third Generation Language:
       As we saw earlier, it is difficult to program using Machine language and assembly language is
machine dependant. Computer professionals started looking at a language that was machine independent and
could provide a satisfactory amount of performance.

       Third Generation languages are machine independent and easy to program. They have the methods
of defining the data as number, character, date and so on. Here data definition statements and looping
constructs were provided to help the programmers to develop applications easily.

       The software is like a book and resembles the English language. Let us have a look over a book
(Software) written in English („C‟) with a Third Generation Language.

       Each book (software) is made of multiple chapters (programs). Each chapter (program) is made of
paragraphs (functions) and each paragraph (function) is made of statements terminated by a period(;) and
each statement is made of words (keywords and operators).

       Keywords and operators are specific to a language. Keywords & operators can be compared to the 26
alphabets of English Language.

       Third Generation languages are easy to write, but the performance is comparatively lower than
FIRST & SECOND generation languages. Conversion is required because Third Generation languages are
English like, whereas, the computer knows only binary instructions. To overcome this problem each
language comes out with its own converter to convert their code into machine code. The converter used in
conversions is known as a "COMPILER" or "INTEPRETOR", depending on the method of conversion. If
we write a program in third generation language, we need to have the compiler for that language to convert
into machine code. So Source code is machine independent whereas, the Compiler is processor dependant.

     In simple terms, assume you (SOURCE) have a servant (COMPILER) who can talk in any language
(PROCESOR). Let us assume that you want to convey "How are you?" to a Spaniard, Polish, Tamilian &
Mumbaite.

       In third generation language your will say "HOW ARE YOU?".

        Your servant will convert this to “Que te pasa” in Spanish, “Jak Sie mast” in Polish, "eppadi
irrukirai?" in Tamil and "Thum kaisa ho?" in Hindi to allow different people to understand and proceed with
their normal operations. Here, you are the Source code and your servant is the compiler that converts the
code according to the system.

Examples of Third Generation Languages are: C, C++, JAVA, FORTRAN, PASCAL and BASIC.



                                     Mani Sridharan – bdmsts@gmail.com
INTEPRETORS are used for converting the source program line by line while the COMPILER
converts in one stroke. BASIC is an example of an INTEPRETOR based language and all the rest of them in
the example are COMPILER based.

Exercise:

       Discuss the advantages and disadvantages of a Compiler and an Intepretor in detail. Identify their
application areas.

Fourth Generation Languages:

       As time passed, we wanted to have our lives to be made much simpler. It so happened that a
programmer needs to understand the basis of a programming language to work with the systems.
Professionals wanted to break this barrier. They wanted a language that resembles English and was easy for
the end user to use without having any knowledge of hardware and system.

       The language that evolved out of this research is known as SQL (STRUCTURED QUERY
LANGUAGE). It is an easy language and simple to use. It is easy to write programs in this language as it
does not contain any device or memory operations as in the other generations of languages.

        Here we do not worry about the location of the data or the format of the data for querying. We do not
bother to initialize printer or open a file to get reports as per requirements.

      SQL is the language set of RDBMS. SYBASE's SQL is known as TSQL(Transact Structured Query
Language). ORACLE's SQL is known as PLSQL.

        I hope this would give you a general idea of computer languages. Now we will look at a specific
third generation language 'C'.




                                      Mani Sridharan – bdmsts@gmail.com
„C‟ LANGUAGE

        “C” lies between SECOND & THIRD generation languages. Using 'C' we can interface with devices
directly with the help of hardware interrupts; like a second generation language; or we can use standard
functions of 'C' to access peripherals without a knowledge of the device interfacing
mechanism(ABSTRACTION of the earlier).

        Let us have a look over this example to have a clear idea of the statements made. Assume we want to
print "C" on the Screen.

LIKE A 2GL:

Method 1:

char far *scr[]=0xB8000000L;         refers to Video RAM Memory in VGA monitors.
scr[0]='C';                          Writing a character 'C' on the memory area which causes
                                       interrupt 10 to happen and the character is printed on monitor.

Method 2:

       asm mov al,46                 assigning al register with ascii value of 'C' in hex.
       asm mov ah,0A                 assigning ah register with the function no.
       asm mov cx,01                 counter set to indicate only one character
       asm int 10h                   invoking interrupt 10 to call the necessary BIOS
                                      routines to handle the situation.
       asm int 20h                   Exiting normally after printing the character on VDU


LIKE A 3GL:
     printf("C");                    printf does all the operations above said and it is a
                                      part of Standard 'C' library.

       Don't concentrate much on the code as it is just an example. The example illustrates that „C‟ language
can behave either as a 2GL to directly interact with the devices or like a 3GL by using the standard library
functions of it.

       The Computer can be defined as an electronic device that is capable of storing and processing
data. A Computer is a data oriented machine but not knowledge oriented. It cannot think or perform any
actions on its own. As professionals we need to program the way we want it to work.

       From the above statements we could infer that we need to provide a mechanism for storing and
processing data. So a third generation language should provide means for storing and processing data. To
provide a clear picture, any third generation language should contain the following components.

                                  COMPONENTS OF A LANGUAGE:

       1. KEYWORDS.
       2. OPERATORS.

       Keywords & Operators are like alphabets to English language. They forms the words, sentences &
paragraphs of a language. „C‟ Language is made of 32 reserve words.

Keywords provides the mechanism for
      1. Defining data (as String, Number, Date,...).

                                      Mani Sridharan – bdmsts@gmail.com
2. Iteration (Repeated operations).

Operators provides the method for doing arithmetic and logical operations.
       Assume we are interested in printing the sum of 5,6. The computer is a dumb fellow. It doesn't know
what a number is or how to add numbers. So the language has to educate the computer and tell what the
number is and how to find the sum of it.

       For defining the number we use KEYWORDS. For calculation we use OPERATORS.
       In 'C' it would be

              int no;
              no=5+6;

              here "int" keyword defining "no" as number.
              "=" is the assignment operator defined by the language.
              "+" is the addition operator defined by the language.

       Understand that "=","+" are like normal characters to a computer. The language has to associate the
appropriate meaning to it for usage.

Exercise:
       1. Can you identify the differences between a LANGUAGE and a COMPILER and how a
          LANGUAGE and COMPILER are related?

       2. Define your own language say 'D‟. Identify the data defining keywords and the operations possible
          with those datatypes with the symbol of the operator in the format shown below.

          Data Type          Type of Data            Operation      Symbol

KEYWORDS:
       The 'C' language is made of 32 keywords. Keywords are the alphabets to a language. They keywords
are used for:

        defining the type of data they are going hold
        decision making
        iteration operations.

              Computer stores data in terms of bits.

                     1 bit           --> 0 or 1 (Binary Digit).
                     4 bits          --> Nibble (Hex).
                     8 bits          --> Byte (1 character (one alphabet in English)).
                  1024 bytes                 --> 1 Kilobyte.
                  1024 Kilobytes     --> 1 Megabyte.
                  1024 Megabytes     --> 1 Gigabyte.
                  1024 Gigabytes     --> 1 terabyte.

Each and every symbol in the keyboard is associated with a number. The number is allotted by
ASCII(American Standard Code for Information Interchange), an international organization.

The number associated with 'A' is 65.
The number associated with 'a' is 97.
The number associated with '0' is 48.


                                        Mani Sridharan – bdmsts@gmail.com
When we want to represent 'A' in the computer, it would be represented as 65. 65 is converted into binary
format and represented in a byte. We will have a look at keywords and operators when we start
programming.

Exercise:

      1. How many Bytes & Hex the following data would require?
         a. “God is Love”
         b. “Hello World”
            c. “Y”
            d. “No defeat is final, until we stop trying”
            e. “Tough times never last but tough people do”

      2. Express 67 in binary format and justify how it accommodates in a byte.
      3. How many characters can be represented using a byte? Justify your answer.
      4. What are the other standards defined for representing characters in Computer? Illustrate with
         examples.
      5. Statement : 'T' is equal to 't' in Computers. Is the statement true? Justify.

PROGRAMMING in C:-

A 'C' program contains the following parts.
        1. Header file --> contains information about the functions called.
        2. main() --> Starting Point of 'C' program.
        3. Statements --> The statements to be executed.
        3. exit() --> Exit point of 'C' program.


NOTE:- 'C' program file names should always terminate with .c extension.

A sample 'C' program "first.c". Use vi for typing the code.

first.c
#include <stdio.h>

main()
{
         puts("Welcome to C");
         exit(0);
}

#include is a keyword is used for including a header file. Here we are using a header file by name "stdio.h"
which contains the declaration of puts function.

main() is a function that indicates the starting point of execution.

puts() is a function that takes "Welcome to C" as parameter for printing on to screen.

exit() is a function that is used for terminating the 'C' program execution.

Note: Each and Every Statement is terminated by ';' like '.' in English. { } is used for representing the
beginning of function (or) paragraph and end of function (or) paragraph.


                                        Mani Sridharan – bdmsts@gmail.com
main is the name of the function(in English - paragraph title) which is made of 2 statements(in English -
lines). '{' indicates the beginning and '}' indicates the end of the paragraph.

COMPILING & EXECUTING.

After saving the file, compile using cc as shown below.

$ cc first.c -ofirst

Then execute first and see what happens.

$first

Exercise.

         1. Write a program to print your name 5 times on Screen.

         2. Write a program to print the following designs.

         a) *******          b)*******        c)    *
            ******              ******            ***
            *****                *****           *****
            ****                  ****          *******
            ***                    ***           *****
            **                      **             ***
            *                        *               *

         3. In puts function instead of enclosing the parameter in double quotes, enclose in single quotes and
            see what happens.
         4. Use puts to print the value 5 on the screen without using quotes . Justify the reasons for error.




                                         Mani Sridharan – bdmsts@gmail.com
COMPILER & COMPILATION

Before we proceed further with the constructs of Language, let us try to figure out what a compiler does. We
have multi pass compilers and Single pass compilers. A pass refers to the scanning of Source Code from top
to bottom. 'C' Compilers are usually 2 pass compilers.

A compiler is a software program is used for converting the source code(Native Language) either into an
object code(Machine Language) for execution or Assembly code(2GL,Assembly language) for Assembler to
convert into Machine Code.

The compiler is made of following components.
      1. Lexical Analyzer.
      2. Syntactic & Semantic Analyzer.
      3. Intermediate Code Generator.
      4. Intermediate Code Optimizer.
      5. Final Code Generator.
      6. Error handler.
      7. Symbol table.


                                                SOURCE CODE


                                                 Lexical Analyzer



                                                Syntactic Analyzer

                 Symbol Table                                                       Error Handler

                                                Semantic Analyzer


                                            Intermediate Code Generator



                                            Intermediate Code Optimizer


                                               Final Code Generator



                                                 OBJECT CODE

Any process that has to be executed in a computer should be loaded in the primary memory of the
Computer(RAM). Computers can understand only ONE‟s & ZERO's. The Machine code contains the
variables, functions in the form of address loaded on the main memory. A compiler converts all the variables
and functions into the machine's memory addresses for proper execution. Each and every variable name and
function name in the source code is known as a symbol.

LEXICAL ANALYSER.

      This component of a Compiler divides the source program into a set of tokens. A token could be a
keyword, or an identifier, or an operator or a constant value.


                                      Mani Sridharan – bdmsts@gmail.com
Let us have a look at this example.

                char alpha='A';
                puts(str);

Lexical Analyzer would split this as

                char--> keyword.
                alpha--> identifier
                = -----> operator.
                'A' ---> Value.

                puts ---> function(identifier).
                str ---> identifier

The statement is made of four tokens. The identifiers would be stored in the symbol table for future
reference.

SYMBOL TABLE:

The Symbol table contains the name, type, size and virtual address of the identifier. Virtual address are
usually represented in hex. To provide clarity in understanding the addresses are represented as
numbers in the entire book.

SYMBOL NAME                    TYPE               Size   MEMORY ADDRESS
                                                         (start) (end)
        alpha                  character           1      400     400
        puts                   function            4      600     603
                               (int)
        str                    character           25    700          724

Symbol table contains the information of all the variables and function defined in the program. It contains
the memory address pointed by the symbol. Any operation made with the symbol would be made in that
memory address pointed by it.

When we refer to variable 'alpha' in a program, it means we are operating memory address 400. Let us look
at this small piece of Code.

                alpha='A';

                A -> 65 (ASCII value) = 01000001 Binary.

                'alpha' is pointing to 400th byte in Memory Location.

As we know earlier a byte can hold 8 bits. 01000001 is stored in memory location 400 which is equivalent
of storing 'A' in that location.

Exercise:
What does the following statement do ? How does it operates on memory ?
       Assume alpha containing 'C' in all cases.
       alpha=alpha + 2
       alpha=alpha / (2 * alpha)
       alpha=alpha - 1


                                         Mani Sridharan – bdmsts@gmail.com
SYNTATIC & SEMANTIC ANALYSER:

It is used for checking the syntax and semantics of the code as defined by the language. Syntax and
Semantics are predefined by the language. Syntax refers to the way the statements are to be framed.

For example: Syntax of 'if' is
                     if <condition>
                     {
                     }

In the program if use 'if' as
                       <condition> if
                       {
                       }

it is syntactically wrong.

Semantics refers to the grammar of the language.

For example: 'puts' is a function used for printing a stream of characters on Screen.

                       puts("Welcome") ---> valid usage.
                       puts(4000) ---> Grammatically wrong.

The above statement is syntactically correct but semantically wrong. It has been defined so that puts can
print a stream of characters on screen and not a number.

The Syntactic and Semantic analyzer creates a parse tree after scanning the tokes passed by Lexical
Analyzer. LR parsing, Canonical Parsing, Bottom-up parsing, top-down parsing are some of the methods
used for parsing.

Refer to Compiler Construction of Aho Ullman for more details on Parsing.

Exercise:

How a Compiler knows that puts can take only a string and not a number is an interesting question ? It is
very true that puts is not a part of 'C' language and arguments that it takes is not defined in the language
part. Can you tell me how the Compiler identifies the arguments passed to the functions are valid or not ?

INTERMEDIATE CODE GENERATION:

Using the parse trees an intermediate object code is generated. It is one to one conversion of Source code
into machine language. All the Symbols are replaced by virtual machine addresses.

INTERMEDIATE CODE OPTIMISER:

This part of the compiler optimizes the code that was generated earlier. For example consider the following
piece of source code.

               if a == b goto Lab1
               if a < b goto Lab2
               if a > b goto Lab1


                                        Mani Sridharan – bdmsts@gmail.com
Object code generated after Intermediate Code Generation will also contain same steps. The Intermediate
code Optimizer would optimize it to

                if a < b        goto I2
                goto I1

Now have a look over the no. of steps.(CPU operations are reduced drastically and hence improves
performance).

Intermediate Code Optimizer, Optimizes for Speed & Size.

FINAL CODE GENERATION:

The code generated after Optimization is the final object code. Object contains the one to one conversion of
source code.

LINKING

The final code generated by the compiler contains the equivalent statements of source language in machine
code. In our program, if we have puts("welcome"), the same statement would be written as machine code in
object FILE. Now our object file doesn't know what it has to do when it encounters the puts
function.(???)The Source program doesn't contain the instructions of puts function and it not a part of 'C' the
language.

'puts' is an external symbol(function) with respect to this program. So if our program has to run successfully
the code of puts should be also included in our program. So a linker is used for attaching the code of the
external functions used in our program.

So whenever we use cc compiler, first it creates an object code and then it creates an executable code.

Example :
                $cc first.c -ofirst
                         is equivalent to
                $cc -c first.c                   ---> COMPILATION
                $cc -l first.o -ofirst           ---> LINKING

Try this out:

       Type a.c and b.c using vi and answer the questions.

Program 1: a.c

       #include <stdio.h>

       main()
       {
                puts("Welcome");
                b();
       }


Program 2: b.c

       #include <stdio.h>

                                            Mani Sridharan – bdmsts@gmail.com
b()
       {
                puts("In Program B");
       }

Exercise:

Compile as
      1. $ cc a.c b.c -oa
         $a

       2. $ rm a
          $ cc a.c -oa
          $a

Analyze the output and give reasons.

DATA TYPES IN 'C'

C has following data types for defining data. Size of data type int is machine dependant and it is equal to
the size of “word” of the processor. The size of the datatypes are enclosed in brackets.

    Data Type        Size(in bytes)                                        Storage
char                 1                    alpha-numeric character
int                  2 or 4               Integers
float                4                    exponents(real numbers).
long                 4                    Long Integers (can store numbers beyond the width of int)
double               8                    Long exponents (can store numbers beyond the width of float)
short                2                    Short Integers(small integers).

Exercise:

1. Assume our machine has a memory of 640K out which 300K is available for us. Our Program code
occupies 200K in memory. Considering the situation and answer the following questions?

       1. Max no. of Integer variables that can be defined in program.
       2. Max no. of Character Variables that can be defined.
       3. Max no. of Double variables that can be defined.

2. Assume virtual address for the following variables. Create a Symbol table and draw memory maps for
them.
        char first;
        int number=25;
        char name[30];
        float basic;
        double squareroot;
        short empno;
        long pointer;
3. Integer & float occupies 4 bytes of memory in „C‟. But how, float can store decimals which integer can‟t.
Explain.




                                       Mani Sridharan – bdmsts@gmail.com
CONSTRUCTS IN „C‟

IF CONSTRUCT.
     Usage:
            if ( <condition> )
            {
                    statement;
                    statement;
            }
            else
            {
                    statement;
                    statement;
            }

If we have only one statement to processed after checking for the conditions, the {} braces are not required.

NOTE: „=‟ is used for assignment and „==‟ is used for checking. Any zero assignment in condition is
considered to be False and non-zero assigment is considered to be True. All the operators returns a zero
or a non-zero value in „C‟ to indicate True or False states.

Let us write a small program which accepts a character and checks whether it is '1' or '0'.

       getchar, fflush, putchar & puts are standard library functions of C.
       getchar() -> used for accepting character.
       fflush() -> clearing the buffer (here input buffer).
       putchar() -> printing a character on Screen.
       puts() -> printing a stream of characters on Screen.

Note: “stdin” refers to the buffer associated with standard input device - keyboard. “stdout” refers to the
buffer associated with standard output device - usually Visual display unit. “stderr” refers to the buffer
associated with standard error device - usually Visual display unit. “stdin, stdout & stderr” are #defined
variables in „stdio.h‟

Second.c
      #include <stdio.h>
      main()
      {
             char alpha;

               alpha=getchar();
               fflush(stdin);
               if ( alpha == '1' )
               {
                       putchar('1');
               }

               if (alpha == '0' )
               {
                       putchar('0');
               }
       }



                                       Mani Sridharan – bdmsts@gmail.com
WHILE & DO WHILE CONSTRUCT
    While Construct:
    while ( <condition> )
    {
            statement;
            statement;
            statement;
    }

       Do While Construct:
            do
            {
                   statement;
                   statement;
                   statement;
            } while( <condition>);

Note: The difference between while and do while construct is in while, it checks the condition and
executes the statements and in the case of do while it executes the statements and checks the condition.

Example:
Third.c - To display menu.(using while construct)
       #include <stdio.h>
       main()
       {
               char choice=„1‟;
               while ( choice != „0‟ )
               {
                      puts(“1. Add”); puts(“2. Mod”); puts(“3. Del”);
                       puts(“0.Exit”);
                      choice=getchar();fflush(stdin);
                      /* do something/
               }
       }


Third.c - To display menu.(using do while construct)

       #include <stdio.h>
       main()
       {      char choice;
              do
              {      puts(“1. Add”); puts(“2. Mod”); puts(“3. Del”);
                     puts(“0.Exit”);
                     choice=getchar();fflush(stdin);
                     /* do something */
              }while(choice != „0‟);
       }

Note: In the above example we have initialized choice to „1‟ whene using while construct to ensure that it
enters the loop(in while it checks the condition and enters loop). But it in the case of do while(2 nd method)
choice is not initialized because, it enters the loop and then checks the condition.



                                      Mani Sridharan – bdmsts@gmail.com
Exercise.

1. Write a program to check whether the entered character is an alphabet, or digit or a special symbol. The
   program should continue functioning till '0' is entered.

2. Write a program to accept 2 characters and print the greatest of them. ( using if and without using if or
   any constructs)

3. Write a program to accept 3 characters and print the least of them.

4. Write a program to accept a character and it has to check with the previous character. It is has to display
   whether the current character entered is greater or lesser or equal to the earlier character entered. The
   program should continue till the user enters '0'.

5. Write a program that reverses the case of the character entered and prints on the screen. The program
   should terminate when user enters '0'. It should take care of all possible errors.

3. Write a program to swap two characters using a temporary variable and without using a temporary
   variable. The program should terminate when user enters '0'. It should take care of all possible errors.




                                       Mani Sridharan – bdmsts@gmail.com
FOR CONSTRUCT

       for ( <initialization>;<condition>;<new assignment> )
       {
               statement;
               statement;
               statement;
       }

Example:

Fourth.c - To print from 1 to 100.
      #include <stdio.h>
      main()
      {       int i;
              for(i=1;i<101;i++)
                      { printf(“%dn”,i); }
      }

In the above example we are printing the first 100 natural numbers. Here we are using the for construct for
achieving the same. for construct is made of three parts
Part 1 is for initialization
Part 2 is for condition checking
Part 3 is for assigning new values;

In this example it assigns 1 to „i‟ (Part 1) and checks whether it is less than 101(part 2), then it executes the
statements enclosed in parenthesis which is “printf(“%dn”,i)” and then increments „i‟ by 1(Part 3).

Then it goes to Part 2 for checking. If the condition is satisfied statements are executed and does the action
specified in Part 3 and hands the control to Part 2. This loop continues and the statements are executed till
the condition is satisfied.

Break Reserve Word

break is a reserve word used for exiting from a loop(while, do while & for).

Example: To illustrate the usage of „break reserve word‟

Fifth.c - To print from 1 to 100.
        #include <stdio.h>
        main()
        {       int ctr=1;
                while(ctr)
                {
                  if (ctr > 100) break;
                  printf(“%dn”,ctr);
                  ctr=ctr+1;
                }
        }

In the above example, the while loop terminates when the ctr contains the value 100. The termination is
made possible by the break reserve word.
Continue Reserve Word.

                                          Mani Sridharan – bdmsts@gmail.com
continue is a reserve word used to place control to the top of the loop (while ,do while & for).

Example: To illustrate the usage of „continue reserve word‟

Sixth.c - To print from 1 to 100.
       #include <stdio.h>
       main()
       {       int ctr=0;
               do
               {
                 ctr++;
                 printf(“%dn”,ctr);
                 if (ctr < 101) continue;
                 break;
                }while(1);
       }

In the above example, the do while loop continues till the ctr reaches 101. When ctr contains 101, the
condition in the „if‟ statement fails and executes the break reserve word to terminate from the loop. When ctr
is less than 101, the reserve word continue takes the control back to the top of the loop (i.e) ctr++ to
increment ctr by 1 and to proceed with rest of the operations.

Return Reserve Word.

return is a reserve word used for return the control back to the calling routine from the sub routine.

Example: To illustrate the usage of „return reserve word‟

Seventh.c - To return the character entered by the user to the shell
      #include <stdio.h>
      main()
      {       char alpha;
              puts(“Enter a character”);
              alpha=getchar();
              fflush(stdin);
              puts(“Entered Character is “);
              putchar(alpha);
              puts(“At Shell prompt type „echo $?‟ to print the ascii value of the character”);
              return alpha;
      }

In the above example, return reserve word causes the ascii value of the character entered to be returned to
the shell.

SWITCH CONSTRUCT

       Switch is used as a substitute to “if”. In a situation if we have different operations to be performed
depending on the value on a variable, the switch construct is usually replaced with “if” construct to reduce
the complexity of the code.


switch(variable)
{

                                       Mani Sridharan – bdmsts@gmail.com
case value1: statement;
                      statement;
                      break;
       case value2: statement;
                      break;
       case value3:
       case value4: statement; /* for value3 & value 4 same set of statements are executed */
                   statement; break;
       default : statement;
                 statement;
                 break; /* if none of the values tally */
}

Eight.c - To display menu & use switch case.

       #include <stdio.h>
       main()
       {
              char choice;
              do
              {
                     puts(“1. Add”);
                     puts(“2. Mod”);
                     puts(“3. Del”);
                     puts(“0.Exit”);
                     choice=getchar();fflush(stdin);

               switch(choice)
               {
               case „1‟: printf(“In Add option”); break;
               case „2‟: printf(“In Mod option”); break;
               case „3‟: printf(“In Del option”); break;
               case „0‟: return;
               default : printf(“Invalid Choice: Range[0-3]”);break;
               }

               }while(1);
       }

A look at library functions printf & scanf

printf: printf is a library function used for displaying a character or a stream of characters, integer, float,
double or long on the standard output device.

Syntax : int printf(const char *, arg1,arg2,....);
         first parameter (const char *) refers to format.
              Format                 Used for
          %c               Character
          %d               Integers, short int, long int
          %s               String
          %ld              Long
          %x               Hexa-decimal
          %o               Octal

                                        Mani Sridharan – bdmsts@gmail.com
%h              Short
          %f              Float
          %L              Long Double
          %e, %E, %g      Float
          %p              Address of the variable

Example :
                  printf(“%s”,”Hello World”);
                  printf(“%d”, 234);
                  printf(“%s%d”,”Hello World”,234);
                  printf(“%d%s%d”,234,”Ramesh”,2342);
                  printf(“%p”, “Hello World”);
                  printf(“%02d”,5);
                  printf(“%*.*s”, 15,15, “Hello World”);
                  printf(“%h”, 23);
                  printf(“%o”, 94);
                  printf(“%x”, 12);
                  printf(“%d”, 0x0004);

scanf: scanf is a library function used for accepting a character or a stream of characters, integer, float,
double or long from the standard input device.

Syntax : int scanf (const char *, (address of arg1),(address of arg2),....);
         first parameter (const char *) refers to format.
         Format can specify the sequence of characters to be accepted using [], ^ .
              Format                 Used for
          %c               Character
          %d               Integers, short int, long int
          %s               String
          %ld              Long
          %x               Hexa-decimal
          %o               Octal
          %f               Float
          %h               Short
          %L               Long Double
          %e, %E, %g Float
          %p               Address of the variable

Example :
                  char c; char str[50]; int j; float f;
                  scanf(“%c”,&c);
                  scanf(“%s”, &str); or scanf(“%s”,str);
                  scanf(“%c%s”,&c,&str);
                  scanf(“%25s”,str); / * Accept a max of 25 characters */
                  scanf(“%c%s%d”,&c,&str,&j);
                  scanf(“%f”,&f);
                  scanf(“%[A-Z]”,str); /* Valid Characters are only A to Z */
                  scanf(“%[^!]”,str); /* Accepts till factorial is entered */
                  scanf(“%d%s%f”,&j,&str,&f);

NOTE: If we refer to the variable name, it refers to the content of the variable. If we want know the
address of the variable, we must put „&‟ before the variable name. When we use printf we are printing the
content and we just refer the variable name and in the case of scanf we have to store the details at the

                                      Mani Sridharan – bdmsts@gmail.com
location of the variable and hence we should specific „&‟ before the variable. Exception to this rule is in
the case of array, variable name and &variable name refers to the address. Arrays are vector quantities
and all base types are scalar quantities.


EXERCISE:

1. What would be the output of i,j at the end of each and every case:
     a. for(i=0;i<100;j=i,i++);
     b. for(i=0;i<100;j=i++);
     c. for(i=0;i<100;j=++i);
     d. for(i=j=5;(i<100) && (j < 200);i=i-5,j+=i);
     e. for(i=j=5;(i<100) || (j< 200);i=i-5;j+=i);

2. Identify the errors (if there are any)
      Assume „i‟ to an integer variable in all cases.

       a. for(i=0, i<100, i++)
       b. for( ; ; );
       c. for(;i<100;);
       d. for(;; i+=2);
                e. for(;;i-=2) { printf(“hello”); }
                f. for(i=0;i<100;printf(“%dn”,i+1),i++);
                g. for(i=0;;);

3. Write a program to print first 100 even numbers in reverse order.
4. Write a program to print first 100 prime numbers.
5. Write a program to print first 3 Armstrong number.
6. Write a program to print first 3 Perfect numbers.
7. Write a program to accept a number and check it is a prime.
8. Write a program to accept a number and find square-root of that no.
9. Write a program to accept a number and find cube-root of that no.
10. Write a program to accept a number and check it is perfect no.
11. Write a program to accept 30 floats and find the sum, max, min and avg.
12. Write a program to accept the first term(a) and the difference (d) and display the value of n th term in the
    Arithmetic Progression. [formula: Term n = a + (n - 1)d ]
13. Accept n & m.(m >= n) Write a program to print the sum of the series for
       1 + 2 + 3 + …. n                             [formula: Sn=(n(n+1))/2]
       n + (n+1) + (n+2 ) + (n+3) …. m
       1 + 3 + 5 + .… n                             [formula: Sn=((n+1)/2)2]
       n + (n+2) + (n+4) + (n+6) … m (m is odd )
       12+ 22 + 32 + … n2                           [formula: Sn=(n(n+1)(2n+1)) / 6]
       n2 + (n+1)2 + (n+2)2 + (n+3)2 …. m2
       13 + 23 + 33 + … n3                          [formula: Sn=(n(n+1)/2)2]
        n3 + (n+1)3 + (n+2)3 + (n+3)3 …. m3
14. Write a program to accept length of Square (could be decimals) and print
        a. Area of the Square         b. Diagonal c. Perimeter.
15. Write a program to accept circumference of a circle and print
        a. Area of the circle         b. Diameter of the circle




                                       Mani Sridharan – bdmsts@gmail.com
USER DEFINED FUNCTIONS

       This chapter introduces the concept of creating our own functions in „C‟. A user defined function
should be declared and then it has to be defined.

DECLARATION:
       Declaration is to indicate the name of the function, arguments taken by the function and the type of
value returned by the function. The template for declaring a function is

       <Return Type> <Function name> ( <arguments>) ;

Examples :

a. int Sum (int , int);
Here Sum is the name of the function that returns an int and takes two int as arguments.

b. float reminder(long, int);
„reminder‟ is the name of the function that returns a float and takes a long and int as parameter.

c. void display(int,char[]);
„display‟ is the name of the function that returns nothing(void) and takes a int and character array as
arguments.

d. void Header(void);
„Header‟ is the name of the function that returns nothing(void) and takes nothing.

e. void setX(int *x);
„setX‟ is the name of the function that returns nothing(void) and takes a pointer to an integer. Pointers will
be discussed later in this material.

DEFINING :
       While defining the function we actually specify what the function has to do when it is invoked.
return statement is used for returning the value from the function.

Examples:(the code for functions declared earlier are given below:)
     a.     int sum(number1,number2)
            int number1,number2;
            {
                    return (number1 + number2);
            }

       b.      float reminder(divident,divisor)
               long divident;
               int divisor;
               {
                       float remind;
                       remind=(divisor>0)?(divident/divisor):-1;
                       return remind;
               }



       c. void display(empcode,empname)

                                       Mani Sridharan – bdmsts@gmail.com
int empcode;
          char empname[];
          {
               printf(“Employee Code :- %d n”,empcode);
               printf(“Employee Name:- %s n”,empname);
               return;
           }

       d. void Header(void)
          {
              printf(“ntttSoftTech Consultants”);
              printf(“ntttC Programmers”);
              printf(“nnn”);
              return;
           }

nine.c To illustrate the usage of user defined functions.
Write a program to accept 2 numbers and print the minimum of two numbers.

#include <stdio.h>
int minimum(int,int); /* Declaring the function */

int main(void)
{      int no1, no2;
       int minvalue;

       printf(“Enter Number 1: ”);
       scanf(“%d”,&no1);fflush(stdin);

       printf(“Enter Number 2: ”);
       scanf(“%d”,&no2);fflush(stdin);

       minvalue=minimum(no1,no2); /* Invoking the function */

       printf(“The minimum value is %dn”,minvalue);
}

       int minimum(number1, number2) /* Defining the function */
       int number1,number2;
       {      if (number1 < number2) return number1;
              return number2;
       }

Note: Some of the compilers doesn‟t support the argument declarations while declaring the function. In
that case, we can declare the function with out arguments by having dummy ( ) followed by „;‟. By default
„C‟ compiler automatically declares the functions which returns an integer and hence they could be
defined without declaring.




                                       Mani Sridharan – bdmsts@gmail.com
Exercise:

1. Write a user defined function to return absolute value of a number.

2. Write a user defined function Greater that takes four numbers as arguments and returns the maximum of
   the four.

3. Write a user defined function CheckUpper to take a character as an argument and returns 1 if it is in
   upper case else zero.

4. Write a user defined function CheckDigit to take a character as an argument and returns 1 if it is a digit
   else zero.

5. Write a user defined function CheckLower to take a character as an argument and returns 1 if it is in
   lower case else zero.

6. Write a program to check whether the entered character is an alphabet, or digit or a special symbol. The
   program should continue functioning till '0' is entered. Use the functions that you have created earlier.

7. Write a user defined function SI to calculate simple interest. The function should take principal, rate of
   interest and no. of years and returns the SI value.

8. Write a user defined function check_right_angled_triangle. It should take the length of opposite side,
   adjacent side and hypotenuse and returns 0 if it matches the sides of a right angled triangle or 1 if not.

9. Write a user defined function Area_of_a_triangle. It should take length of 3 sides as parameters and
   returns the area of the triangle.

10. Write a user defined function FACTORIAL that returns the factorial of the number passed as parameter.

11. Write a user defined function GCD (Greatest Common Divisor) that takes 3 numbers as arguments and
    returns the GCD of the three.

12. Write a user defined function LCM (Least Common Divisor) that takes 2 numbers as arguments and
    returns the LCM of the two.

13. Write a user defined function that prints the multiplication table. It should take the table no. and
    multiplication value till a no.
    Example: multable(16,8)
    Output Should be from 16 x 1 = 16 to 16 x 8 = 128

13. Write a user defined function that returns Square root of a number.(don‟t use sqrt library function).

14. Write a user defined function that returns Cube root of a number.

15. Implement user defined functions for SIN, COS and TAN.




                                       Mani Sridharan – bdmsts@gmail.com
ARRAYS:

        Arrays are rectangular arrangement of elements of the same type. Each and every element in the
array is referred using the subscript of the element.

Syntax for creating a single dimensional array:

       <Storage identifier> <variable name>[<no_of_elements>];

Example:

char alphabet[26];
Creates a single dimensional character array under the variable name alphabet to hold 26 characters.

int marks[5];
Creates a single dimensional integer array marks to hold 5 subject marks.

float rate[12];
Creates a single dimensional floating point array to hold rate of 12 items.

Referring elements in an array:

        Elements in the array are referred using the subscript, the subscript starts from zero. Thus if we want
to refer to element no. 5, the subscript should be 4. If we want to refer to first item, the subscript should be
zero.

Let us assign alphabet array with all alphabets.

Method 1:

       We can initialize each and every array element by referring to subscript

       char alphabet[26];

       alphabet[0]=„a‟;
       alphabet[1]=„b‟;
       alphabet[2]=„c‟;
              :
              :
       alphabet[25]=„z‟;

Method 2:

The better way of doing could be.
       char alphabet[26];
       int i;
       for(i=0;i<26;alphabet[i]=„a‟+i, i++);




                                       Mani Sridharan – bdmsts@gmail.com
Accepting data on to array.

       Let us define array “name” to store the name of an individual(max of 30 characters). Let us see how
to accept the name in different ways. If we want to store 30 characters we need to define an array of 31
characters, simply because „0‟ is used as a string terminator in most of the „C‟ functions. The String
Terminator „0‟ is defined as NULL in stdio.h include file. In our code, we can check for String
Terminator by comparing with „0‟ or with NULL.

Method 1:

       char name[31];
       int i=0;
       printf(“Name : “);
       for(;i<30;i++)
       {
                name[i]=getchar();
                fflush(stdin);
       }
       name[30]=„0‟;             /*Placing the terminator to specify the end of the string. printf looks for
                                 string terminator when %s is specified as argument. The other way of doing
                                 the same is name[30]=NULL*/

       printf(“Your name is %sn”,name);

Method 2:

       char name[31];
       printf(“Enter Name(max 30 chars) : “);
       gets(name); /* we can use scanf(“%s”,name); also*/
       fflush(stdin);

       /*gets & scanf are library functions of „C‟ */
       /*gets & scanf takes care of putting „0‟ at the end of the stream */
       /*fflush is a library function used for clearing the buffer associated with it */

       printf(“Your name is %s n”, name);

Note: In „C‟ single quotes and double quotes have different meaning. Single quotes is used for enclosing
one single character where as double quotes is used for enclosing an array of characters known as string.
For example in puts if enclose the argument in single quotes, it generate a compilation error as it requires
stream of characters as input. In general, single quotes refers to the value to be stored and the double
quotes returns the address of the location of the data in memory.

The subscript is again used for referring to elements in Integer and Float arrays. The format “%d” is
used for integer and “%f” is used for float while accepting and printing data using “scanf” and
“printf” functions. “gets” function cannot be used for accepting a float or an integer. It can be used
only for accepting a stream of characters(strings).

ARRAY Referencing in MEMORY

The memory address of an array element is found by

(Starting address + (subscript * sizeof(data type));


                                        Mani Sridharan – bdmsts@gmail.com
sizeof is a reserved word in „C‟ used for calculating the total bytes associated with that datatype.

Example 1:

       Let us define an array by name Alphabet to hold 26 characters.
       char Alphabet[26];
       let us assume Alphabet is memory location 300.

       Alphabet[0] will be location 300.
       Alphabet[1] will be location 301.
       Alphabet[2] will be location 302.
       Hence location of Alphabet[n]=(Starting address + (n * sizeof(char));
       Alphabet[5]=(300 + (5*1)) ==> 305.

Example 2:

       Let us define an array by name Rate to hold 5 characters.
       int Rate[5];
       let us assume Rate is pointing to memory location 400.

       Rate[0] will be location 400 - 403.
       Rate[1] will be location 404 - 407.
       Hence location of Rate[n]=(Starting address + (n * sizeof(int));
       Rate[3]=(400 + (3*4)) ==> 412.

EXERCISE

For Exercises 2 to 9, you need incorporate by writing your own functions.

1. Identify the output of the following programming.

       #include <stdio.h>
       main()
       {
       char alphabet[26]; /* alphabet is location 125 in memory */
       int marks[5];      /* marks is location 200 in memory */
       alphabet[6]=„f‟;
       alphabet[5]=alphabet[6]-1;
       marks[0]=100;
       marks[2]=marks[0]-24;
       marks[4]=marks[0]-marks[2]+20;
       marks[3]=36;
       marks[1]=marks[0]%(marks[2]-marks[3])
       alphabet[0]=alphabet[1]=alphabet[7]=„0‟;

       printf(“%d”,alphabet[5]);
       printf(“%d”,&alphabet);
       printf(“%d”,&alphabet[0]);
       printf(“%d”,&alphabet[21]);
       printf(“%d%d%d%d%d”,marks[0],marks[1],marks[2],marks[3],marks[4])
       printf(“%d %d”, &marks[3],&marks[1]);
       }



                                       Mani Sridharan – bdmsts@gmail.com
2. Write a program to accept 30 characters and print the no of vowels, consonants, digits & special
   characters in the group.

3. Write a program to accept 30 characters and print the length of the string.

4. Write a program to accept 30 characters and convert all uppercase to lowercase and print.

5. Write a program to accept 30 characters and convert all lowercase to uppercase and print.

6. Write a program to accept a string of 50 characters long and check whether it is palindrome or not.

7. Write a program to accept two strings (assume size) and check whether they are same or not.

8. Write a program to accept two strings(assume size), print both the strings and append the string string to
   the first and print both.

9. Implement substring, ltrim, rtrim, left, right functions.

10. Write user defined functions ASortC, ASortI, ASortF to sort Character, Integer & Float arrays.

11. Write user defined functions ACopyI, AFloatF to copy contents of Integer to Integer, Float to Float
    arrays.

12. Write a program to accept 25 integers on to array. While Storing store it in ascending order.

13. Write a program to accept details of 5 items. Details are itemcode integer, rate integer, quantity as float
    type variable. Incorporate the following options.
                    a. To print the details of all items.
                    b. To print the details of an item specified by the user.
                    c. To print the details of all items whose rate < accepted rate.

14. Implement a user defined function REVERSE, that takes a character array ( assume size) and reverses
    and writes the string to the second character array passed as parameters.

15. Implement a user defined function to encrypt and decrypt a string. (one possible logic is to add 40 to
    each character while encrypting and subtracting 40 while decrypting).




                                        Mani Sridharan – bdmsts@gmail.com
Syntax for creating a Two dimensional array:

<Storage identifier> <variable name>[<no_of_rows>][<no_of_columns>];

Example:
char names[5][31];
Creates a two dimensional character array under the variable name “names” to hold 5 names each 30
characters long assuming 1 byte for „0‟(String Terminator).

int matrix [3][3];
Creates a two dimensional integer array “matrix” to hold integers for a 3x3 matrix.

Referring elements in an two dimensional array:

Elements in the two dimensional array are referred using the row subscript and column subscript, the
subscript starts from zero. Thus if we want to refer to third row, second element, it should be (2,1).

Let us initialize matrix array with unit matrix.

We can initialize each and every array element by referring to row, column subscript

       int matrix[3][3]; int i=0; int j=0;

       for(;i<3;i++)
               for ( ; j<3;j++)
                        matrix[i][j]=0;

       matrix[0][0]=matrix[1][1]=matrix[2][2]=1;

Accepting and Accessing data on a two dimensional array.

       Let us define array matrix to store a 3x3 matrix.

       int matrix[3][3];
       int i,j;

       /* Accepting Details */
       for(i=0;i< 3; i++)
       {      for(j=0; j < 3; j++)
              {
                       printf(“Enter value for row %02d, column %02d ”, i+1,j+1);
                       scanf(“%d”,&matrix[i][j]); fflush(stdin);
              }
       }

       /*Accessing Details & Printing */
       for(i=0;i<3;i++)
       {      for(j=0;j<3;j++)      printf(“%dt”,matrix[i][j]);
                      printf(“n”);
       }

Note: Similar method can be used for Accepting and Accessing details on to a character two dimensional
array. The library functions scanf and gets can be used for accepting details.


                                          Mani Sridharan – bdmsts@gmail.com
EXERCISE:

1.Assume two 3x3 matrices A& B. Write programs for
      a. Addition of 3x3 matrices
      b. Subtraction of 3x3 matrices.
      c. Multiplication of 3x3 matrices.
      d. Inverse of a 3x3 matrix.

2. “The PLAYGROUP NURSERY” is one of the famous nursery in Bombay. They teach the kids with the
   help of PLAYWAY method. The nursery current consists of 25 kids. They wanted to store the following
   details in order to prepare a grade sheet for the kids. They have approached you to automate their
   process. The task includes:

        1. Accepting and storing details for 25 students. Details include, their name, age, ranking out of 10
           in playing, grasping, listening, hearing, reading & writing.

        2. Prepare a grade sheet and print the appropriate grade. Valid grades are Outstanding, Excellent,
           Good, Average & Poor.

                 Total ranking      Grade
                 out of 10
                 9.0 and Above      Outstanding
                 8.0 - 8.9          Excellent
                 7.0 - 7.9          Good
                 5.0 - 6.9          Average
                 less than 5.0      Poor.

        You need to prepare the report in the following format.

                                        THE PLAYGROUP NURSERY
                                             Graded Mark Sheet

S.No.   Name                     Age         Total Ranking           Grade
1.      Ramesh                     3            8.3               Excellent
2.      Rajesh                     4            9.1               Outstanding
..      ...........              ....           ....                 .....




                                        Mani Sridharan – bdmsts@gmail.com
STRING HANDLING FUNCTIONS IN STANDARD „C‟ LIBRARY

All the string handling library functions are prototyped in „string.h‟. So whenever we use string handling
functions the file „string.h‟ should be included along with „stdio.h‟ in our program. This can be included to
our program with the help of „#include‟ preprocessor statement and it is shown below.

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


Appending One String to Another:

       a. char *strcat(char *s1, const char *s2); - Appends a copy of string s2 to the end of string s1. It
           automatically terminates s1 with NULL(„0‟) - String Terminator.

       b. char *strncat(char *s1, const char *s2, size_t n); - Appends a maximum of n characters. It
           copies fewer if s2 is shorter than n characters. Returns a pointer to the null-terminated result (the
           value of s1).

Copying One String to Another:

       a. char *strcpy(char *s1, const char *s2); - Copies the s2 on to s1 by overwriting the contents of
           s1. Copying stops when it encounters a NULL byte. Returns a pointer to the null-terminated
           result (the value of s1).

       b. char *strncpy(char *s1, const char *s2,size_t n); - Copies a maximum of n characters. It
           copies fewer if s2 is shorter than n characters. Copying stops when it encounters a NULL byte.
           Returns a pointer to the null-terminated result (the value of s1).

       c. char *strdup(const char *s); - creates a duplicate of s and returns the memory location of the
           duplicate copy.

Comparing Strings:

       a. int strcmp(const char *s1, const char *s2);- Compares its arguments and returns an integer less
           than, equal to, or greater than zero, depending on whether s1 is lexicographically less than, equal
           to, or greater than s2.

       b. int strncmp(const char *s1, const char *s2, size_t n);- makes the comparison like strcmp but
           examines a maximum of n characters (n less than or equal to zero yields equality).

Length of a String:

       a. size_t strlen(const char *s); -Returns the number of characters in s, not including the
          terminating null byte.




                                       Mani Sridharan – bdmsts@gmail.com
POINTERS

Pointers are variables in „C‟ whose contents are addresses. Pointers are the backbone of „C‟. They are
used to refer to a particular memory address to change its contents. Any Pointer variable occupies 4
bytes of memory. To point to character type memory address, character pointers are used. For integer
type memory address, integer pointers are used. In specific, if the memory location of a storage type is
to be accessed using a pointer, the pointer needs to be defined of that type. Exception to this rule is
“void” pointers, they can point to any storage types memory location. In the case of a Pointer variable,
we don‟t know the exact size of data it is pointing to.


      Pointers can be used for pointing to scalar and vector types.

      Pointer variable refers to memory address it is containing i.e. the content of a pointer variable
       is an address.

      „*‟Pointer variable refers to the content in the memory address it is containing.

      „&‟Variable refers to the address of the variable .

DECLARING A POINTER:

       char    *ptr;       /* Declaring a Character Pointer */
       int     *ijk;      /* Declaring a Integer Pointer */
       float   *x;       /* Declaring a Float Pointer */
       void    *v;      /* Declaring a Void Pointer */

POINTER MANIPULATIONS:

Let us define two variables „a‟ & „ptr‟. „ptr‟ is a pointer type variable. Assume „a‟ is memory location 300
and „ptr‟ is memory location 400.

       char a,*ptr;           /* Declaring Variables */
       a=„x‟;                 /* Assigning the value „x‟ to variable „a‟ */
                              /* At memory location 300, „x‟ is written as
                                 Variable „a‟ is address 300 */

       ptr=&a;               /* Assigning the address of variable „a‟ to „ptr‟ */
                            /* At memory location 400, the address (300) of „a‟
                               is written */

       printf(“%p”,ptr); /* Printing the content of ptr --- > 300 */
       printf(“%c”,*ptr);  /* Printing the content of content of ptr.
                                   ==> content of content of 400
                                   ==> content of 300
                                   ==> „x‟ */

       (*ptr)++;       /*Incrementing the content of content of ptr by 1
                              ==> incrementing the content of content of 400 by 1
                              ==> incrementing the content of 300 by 1
                              ==> incrementing the value „x‟ by 1
                              ==> at 300, the value would be „y‟ */



                                       Mani Sridharan – bdmsts@gmail.com
printf(“%c”,*ptr);    /* would be printing „y‟ */
       printf(“%c”,a);      /* variable „a‟ refers to 300 and hence prints „y‟ */

Note: In the above example, „ptr‟ refers to the content of the variable „ptr‟ which is the memory address of
variable „a‟ and „*ptr‟ refers to the content of content of ptr which is the value in memory location 300
and it is „x‟ initially then incremented to „y‟.

EXERCISE:
       Assume the character variable „myvar‟ is memory address 500 and character type pointer variable
„myptr‟ is memory address 625. With reference to this explain each & every line in the code and errors (if
any).

              myvar=„p‟;
              printf(“%p”,&myvar);
              printf(“%c”,myvar);
              printf(“%p”,&myptr);
              printf(“%c”,myptr);
              printf(“%c”,*myvar);
              printf(“%c”,*myptr);

              myptr=myvar;
              printf(“%p”,&myvar);
              printf(“%c”,myvar);
              printf(“%p”,&myptr);
              printf(“%c”,myptr);
              printf(“%c”,*myvar);
              printf(“%c”,*myptr);

              myptr=&myvar;
              printf(“%p”,&myvar);
              printf(“%c”,myvar);
              printf(“%p”,&myptr);
              printf(“%c”,myptr);
              printf(“%c”,*myvar);
              printf(“%c”,*myptr);

              (*myptr)++;
              printf(“%p”,&myvar);
              printf(“%c”,myvar);
              printf(“%p”,&myptr);
              printf(“%c”,myptr);
              printf(“%c”,*myvar);
              printf(“%c”,*myptr);

              myptr++;
              printf(“%p”,&myvar);
              printf(“%c”,myvar);
              printf(“%p”,&myptr);
              printf(“%c”,myptr);
              printf(“%c”,*myvar);
              printf(“%c”,*myptr);

One might raise the question like, if pointers contents are memory address, why we need different
kind of pointers ?

                                      Mani Sridharan – bdmsts@gmail.com
To answer this question, let us get back to arrays. Let us take up our same old example character
array „Alphabet‟ and integer array „Rate‟. Assume Alphabet is memory location 400 and Rate is memory
location 500.

       char Alphabet[26];         /* Alphabet is location 400 */
       int Rate[5];             /* Rate is location 500 */

       &Alphabet[0] is location 400,
       &Alphabet[1] is location 401 and
       &Alphabet[subscript]=(starting address+(subscript * sizeof(storage type))
       Here &Alphabet[subscript]=(400+(subscript * 1)). (Since sizeof(char) is 1).
       Hence &Alphabet[1]=(400+(1*1)) = 401.

       Similarly,
       &Rate[0] is location 500,
       &Rate[1] is location 504,
       &Rate[subscript] = (starting address +(subscript * sizeof(storage type))
       Here &Rate[subscript] = ( 500 +(subscript * 4)). (Since sizeof(int) is 4).
       Hence &Rate[1]=(500+(1*4)) = 504.

Let us have two pointer variables „MyCharPtr‟ and „MyIntPtr‟. „MyCharPtr‟ is a char type pointer varible
and „MyIntPtr‟ is a int type pointer variable. Let us make this pointers point to our earlier variables Alphabet
& Rate. With the help of this we shall identify the need of different types of pointer variables.

       char Alphabet[26];            /* Alphabet is location 400 */
       int Rate[5];                  /* Rate is location 500 */
       char *MyCharPtr;              /* Character Pointer */
       int *MyIntPtr;                /* Integer Pointer */
       MyCharPtr = &Alphabet;        /* Storing 400 in MyCharPtr */
       MyIntPtr = &Rate;             /* Storing 500 in MyIntPtr */

Now the Pointer variable MyCharPtr is pointing to the address of Alphabet[0]. We want MyCharPtr to point
to the address of Alphabet[1]. As we know the sizeof (char) is one, we are incrementing the content of
MyCharPtr by 1 hence it will contain the memory address as 401 and that is &Alphabet[1].

       MyCharPtr++;           /*Increases the content of MyCharPtr by 1 */

Similarly, we want MyIntPtr to point to the address of Rate[1]. As we know the sizeof(int), we will
increment the content of MyIntPtr by sizeof(int) assuming “4”.

       MyIntPtr=MyIntPtr + sizeof(int);

To check whether it has increment correctly, let us print the new memory address stored in MyIntPtr. It
should be 504.

       printf(“%p”,MyIntPtr);

We would be wondered to see the content is printed as 516 refering to Rate[4] instead of Rate[1]. The reason
is the scaling factor of int is „4‟ and hence when we say MyIntPtr + 4, it increments the content of MyIntPtr
by 4 times 4 and hence containing the address of Rate[4]. In our script we should have increment MyIntPtr
by 1 instead of 4 to point to Rate[1].



                                       Mani Sridharan – bdmsts@gmail.com
What we need to identify here is whenever we define a character pointer and any mathematical
operation is carried with it will be interms of sizeof(char) (i.e 1). Incase of integer pointers, it will be
in terms of sizeof(int) (i.e. assumed as 4).

In Specific whenever we carry a mathematical operation with the pointers, the operation will be
carried in terms of sizeof(storage type).

Secondly, the way in which the char, int & float data stored in memory differs and hence we can‟t
have integer type pointer pointing to char and char type pointer pointing to int as the scaling factor
and the data conversion technique differs.

Note: Pointer variable++ and „*‟Pointer variable ++ are not the same. Pointer variable++ increases the
content of the pointer variable by the scaling factor and „*‟Pointer variable ++ increments the content of
the content of Pointer variable by 1 in the case of single dimensional pointers. Scaling factor is value
required for skipping that element to move to next element in the sequence.

Example: Convert all UpperCase to LowerCase using Pointers.
Method 1: Without User defined Function.

       #include <stdio.h>
       main()
       {      char string[101];
              char *ptr;

              printf(“String (max 100 chars) : “);
              gets(string);

              ptr=string;
              printf(“The Entered String is %s n”,ptr);

              for(ptr=string;(*ptr != „0‟); ptr++)
              {
                     if ((*ptr) > „A‟ && (*ptr) < „Z‟))
                             (*ptr)=(*ptr) + 32;
              }
              printf(“The String in lowercase is %s”,string);

              /*
                   We cannot use ptr to print because, ptr is moved to the address
                   of „0‟. If we want to print using ptr, again assign the address of
                   string to ptr and print
              */
       }

Method 2: With User defined Function.
     #include <stdio.h>
     void toLowerCase();
     main()
     {      char string[101];

              printf(“String (max 100 chars) : “);
              gets(string);

              toLowerCase(string);

                                       Mani Sridharan – bdmsts@gmail.com
printf(“The String in lowercase is %s”,string);
       }

       void toLowerCase(ptr)
       char *ptr;
       {
              for(ptr=string;(*ptr != „0‟); ptr++)
              {
                     if ((*ptr) > „A‟ && (*ptr) < „Z‟))
                             (*ptr)=(*ptr) + 32;
              }
       }

Note: Method 2 has great advantage as method 1 because, the size of the array is not taken into
consideration in Method 2 and it is modular.


EXERCISE

 1. Try the exercise 2 to 9 given for arrays using pointers.(refer to earlier example (Method 2) for
    implementation).
 2. Implement a user defined function SearchReplace which takes the Main String, Search String &
    Replace String and replaces all occurrences of Search String in MainString with Replace String.

MEMORY HANDLING:

        Any variable (non Pointer Variables) defined in the program by default assumes maximum size of
the data it is containing. For example, if we define int j, we know j is going to occupy four bytes of
memory. If say, char name[31], it is very well known that name is going to occupy 31 bytes of memory.
Since these variables assume a define size of data they are going to store, they are created in STACK.
The Executable file contains the virtual memory layout of these variables in memory as the compiler
knows the size & type of these variables at the time of Compilation. All the non-pointer variables are
initialized variables.

        Pointers are the technique used in „C‟ to point to a memory location and to manipulate the data in it.
If we take applications like word processor or spreadsheet the size of the data and the data it is holding is
known only at the run-time. Hence the memory allocation to be done dynamically at the run-time.
Dynamically Memory is allocated from HEAP. HEAP is the global memory and doesn‟t form a part of
current running process. Using Pointers and Standard „C‟ library functions, we allocate memory from
HEAP for processing. HEAP memory area can be pointed only by Pointers. Pointer variables are not
initialised variables. Pointers can refer to STACK and HEAP memory areas.

DYNAMIC ALLOCATION OF MEMORY FROM HEAP

void *malloc(int);

The function used for allocating memory dynamically from HEAP. „malloc‟ takes the no_of_bytes required
from Heap as an argument and allocates that many bytes from Heap by returning a valid memory address
else returns NULL(or Zero). Since malloc returns a void pointer it can be type-casted to any storage type by
enclosing the storage type pointer in brackets.




                                      Mani Sridharan – bdmsts@gmail.com
Examples:
1.   char *str;
     str=(char *)malloc(16);          /* Since malloc returns a void pointer and str is
                                          a character pointer, we are type-casting the
                                          void address returned by malloc to
                                         char pointer by enclosing (char *) in brackets.
                                         We are taking 16 bytes from heap to store 15
                                          characters and „0‟(String Terminator)
                                         ---> look the example */

2.     int *iptr;
       iptr=(iptr *)malloc(sizeof(int));      /* Since malloc returns a void pointer
                                               and iptr is a integer pointer, we are
                                               type-casting the void address returned by
                                               malloc to integer pointer by enclosing
                                              (int *) in brackets. Since any int requires
                                              four bytes of memory, we are passing the
                                              sizeof(int) as arguement.
                                              ---> look the example */

RE-ALLOCATING MEMORY ASSIGNED BY MALLOC.

void *realloc(void *ptr, size_t size);

It is used for changing the size of memory allocated by earlier malloc function and returns a pointer to
the block(possibly new) where it is allocated. If ptr is a NULL pointer, realloc() behaves like malloc()for
the specified size. If size is zero and ptr is not a NULL pointer, the object it points to is freed and NULL is
returned.

Example:
1.   char *str;
     str=(char *)malloc(16);          /* Since malloc returns a void pointer and str is
                                          a character pointer, we are type-casting the
                                          void address returned by malloc to
                                         char pointer by enclosing (char *) in brackets.
                                         We are taking 16 bytes from heap to store 15
                                          characters and „0‟(String Terminator)
                                         ---> look the example */

       str=(char *)realloc(str,10);   /* Re-initialising str to point to a location for
                                        storing 10 bytes instead of 16 */

RELEASING MEMORY ASSIGNED BY MALLOC.
void free(void *ptr);
       It is used for releasing the memory earlier allocated by malloc function.

Example:
1.   char *str;
     str=(char *)malloc(16);
     free(str);                       /* Releasing memory thus allotted by malloc */




                                         Mani Sridharan – bdmsts@gmail.com
GOOD PROGRAMING PRACTICES:
Whenever we allocate memory from HEAP using „malloc‟ function, check whether it returns NULL or
not. If it returns a NULL that means it has failed the operation due to memory insufficiency. You need to
handle these errors.

It is a good programming practice to release the memory used by a pointer using „free‟ function as soon
as the operation with the variable is complete. This increases the HEAP memory area size and help other
processes to utilize it.

EXERCISE:

1. Write a program to accept a number, allocate memory to hold that many no. of characters. Accept data
from the user and print the details.

2. Allow the user to enter a text of unlimited size and print it in reverse order.

MULTI DIMENSIONAL POINTERS:

      Like Multi-dimensional arrays we can have multi-dimensional pointers. This is an example of two
dimensional integer pointer to hold details of an 4x4 matrix. In the example, explanations are given in
normal comment entries and other method of doing the same operation in bold comment entries.

#include <stdio.h>
main()
{
       int **p;                        /*declaring a two dimensional integer pointer */
       int i,j;

       p=(int **)malloc(4*sizeof(int));    /*allocating memory to hold four rows */
                                   /*allocating 16 bytes for 4 integers (4x4)*/
                                   /*assume malloc returns 400, hence „p‟ points
                                     from 400 - 415, and that could be divided as
                                    400-403 for p[0],
                                    404-407 for p[1],
                                    408-411 for p[2],
                                    412-415 for p[3]
                                  */
       if(p==NULL)
       {
              printf(“Memory Not Available... Aborting “);
              exit(-1);
       }

       /*p[0] = p      [points to 400-403],
         p[1]= (p+1) [points to 404 - 407, simply because, scaling factor for
         a integer is 4, hence „p+1‟ refers to next location of pointer „p‟ (i.e. 404).
         p[2]=(p+2) [points to 408 - 411]
         p[3]=(p+3) [points to 412-415] */

       /* Since the p[0] - p[4] is pointing to junk, we need to initialize with a valid
          memory area address. Again allocating 16 bytes for each subscript to ensure
          proper storage of 4 bytes in each case. */

       /* Let us assume p[0][0] is pointing to 500 - 515

                                         Mani Sridharan – bdmsts@gmail.com
p[1][0] is pointing to 600 - 615
                  p[2][0] is pointing to 700 - 715
                  p[3][0] is pointing to 800 - 815 */

*p=(int *)malloc(4*sizeof(int)); /* (p[0])=(int *)malloc(16); */
if((*p)==NULL)
{       printf(“Memory Not Available for p[0] ... Aborting “);
        free(p);
        exit(-1);
}

*(p+1)=(int *)malloc(4*sizeof(int));       /* (p[1])=(int *)malloc(16); */
if((*(p+1))==NULL)
{       printf(“Memory Not Available for p[1] ... Aborting “);
        free(p[0]);                /* freeing memory in descending order */
        free(p);
        exit(-1);
}

*(p+2)=(int *)malloc(4*sizeof(int));              /* (p[2])=(int *)malloc(16); */
if((*(p+2))==NULL)
{       printf(“Memory Not Available for p[2] ... Aborting “);
        free(p[1]);
        free(p[0]);
        free(p);
        exit(-1);
}

*(p+3)=(int *)malloc(4*sizeof(int));        /* (p[3])=(int *)malloc(16);*/
if((*(p+3))==NULL)
{       printf(“Memory Not Available for p[3] ... Aborting “);
        free(p[2]);
        free(p[1]);
        free(p[0]);
        free(p);
        exit(-1);
}

**p=100; /*p[0][0]=100*/ /* we are initializing **p with 100
                         ==> initializing content of content of 400
                         ==> initializing content of 500 - 503 with 100 */

/* similarly compute for others */
*((*p)+1)=200;                /*     p[0][1]=200;          */
*((*p)+2)=300;                /*     p[0][2]=300;          */
*((*p)+3)=400;                /*     p[0][3]=400;          */

**(p+1)=1000;                 /*     p[1][0]=1000;         */
*((*(p+1))+1)=2000;           /*     p[1][1]=2000;         */
*((*(p+1))+2)=3000;           /*     p[1][2]=3000;         */
*((*(p+1))+3)=4000;           /*     p[1][3]=4000;         */

**(p+2)=-100;                 /*     p[2][0]=-100;         */
*((*(p+2))+1)=-200;           /*     p[2][1] =-200;        */

                               Mani Sridharan – bdmsts@gmail.com
*((*(p+2))+2)=-300;             /*     p[2][2] =-300;         */
       *((*(p+2))+3)=-400;             /*     p[2][3]=-400;          */

       **(p+3)=-1000;                  /*     p[3][0]=-1000;      */
       *((*(p+3))+1)=-2000;                   /*     p[3][1]=-2000;          */
       *((*(p+3))+2)=-3000;                   /*     p[3][2]=-3000;          */
       *((*(p+3))+3)=-4000;                   /*     p[3][3]=-4000;          */

       /* Printing the values stored in the two dimensional pointer */

       for(i=0;i<4;i++)
       {
              for(j=0;j<4;j++)
              {
                     printf("%5dt",*((*(p+i))+j));
              }
              printf("n");
       }

       for(i=3;i>-1;free(p[i]),i--);
       free(p);
}

EXERCISE:
1. Accept two integers M & N from users and create two matrix with „M‟ as number of rows and „N‟ as
number of columns. Do operations like addition, subtraction and multiplication with it. Note the matrix can
contain decimals & negative.

                           IMPLEMENTING USER DEFINED DATA-TYPES:

a. STRUCTURES:

        Structures are widely used for creating data-structures in „C‟. We would be interested in creating our
own data-types for storing details rather than the system defined in most of the cases. To illustrate this, let us
create a data type „Employee‟ to store employee details in an organization. Some of the Employee details
include „Employee Code‟, „Employee Name‟, „Grade‟, „Date of Birth‟, „Date of Joining‟, „Bank A/c No.‟,
„Blood Group‟, „Designation‟ and „Department‟. It is better to bring all the logical attributes of employee in
to a single physical attribute for clarity in programming. Structures are used in implementing the same.
Structures can contain structures as data elements. Here DOJ & DOB is a date type made of day,
month & year. Structures are created using struct keyword. Let us create the new user defined types
Employee & Date.

       struct Date
              {
                       short int dd;
                       short int mm;
                       int yy;
               };



       struct Employee
              {     int ECode;
                    char Name[26];

                                        Mani Sridharan – bdmsts@gmail.com
char Grade;
                       struct Date DOB;
                       struct Date DOJ;
                       int AccountNo;
                       char BloodGroup[3];
                       int DesigCode;
                       int DeptCode;
               };

        Now we have created a user defined type by name „Employee‟. Whenever an instance of „Employee‟
is created, all the attributes will gain scope to store details. „Employee‟ is a data-type like „char‟. Hence we
need to create an instance for storing details. To create an instance of structure, the syntax used is
                 struct <Struct name> <Variable Name>;

In Employee Structure we have created two instances of Struct Date to contain DOB and DOJ.

Let us look at the example for creating an instance.
        struct Employee emp1;
        struct Employee *eptr;

        Now we have created an instance of „Employee‟ as „emp1‟. Since „emp1‟ is not a pointer, the
memory is automatically allocated from STACK at time of compiling. In the second case „eptr‟ is a pointer
and hence memory has to be allocated from HEAP to store details. The sizeof the variable emp1 is the
total sum of all the attributes defined in the structure Employee. Here it is 54 bytes long.

       Let us initialize the details of „Johnson‟ in emp1. Each and every attribute is referenced by
putting instance‟.‟attribute in case of STATIC variables and instance->attribute in case of POINTER
variables.

Initializing Static Variable:
         emp1.Ecode=1;
         strcpy(emp1.Name,”Johnson”);
         emp1.Grade=„A‟;
         emp1.DOB.dd=12;
         emp1.DOB.mm=7;
         emp1.DOB.yy=1965;
         emp1.DOJ.dd=14061987;
         emp1.DOJ.mm=6;
         emp1.DOJ.yy=1987;
         emp1.AccountNo=12345;
         strcpy(emp1.BloodGroup,”O+”);
         emp1.DesigCode=1;
         emp1.DeptCode=5;

Initializing Pointer Variable:

eptr=(struct Employee *)malloc(sizeof(struct Employee));

/* In sizeof reserve word, eptr is not given because, it is a pointer variable and it is four bytes in size. We
need to allocate 54 bytes hence we take the sizeof structure into consideration */

       eptr->Ecode=1;
       strcpy(eptr->Name,”Johnson”);
       eptr->Grade=„A‟;

                                       Mani Sridharan – bdmsts@gmail.com
eptr->DOB.dd=12;
         eptr->DOB.mm=7;
         eptr->DOB.yy=1965;
         eptr->DOJ.dd=14061987;
         eptr->DOJ.mm=6;
         eptr->DOJ.yy=1987;
         eptr->AccountNo=12345;
         strcpy(eptr->BloodGroup,”O+”);
         eptr->DesigCode=1;
         eptr->DeptCode=5;

Ten.c:- To illustrate the usage of structures.

/* This is a sample program to accept the details of 25 Employees using structures and to print them
accordingly. */

#include <stdio.h>
#define CLS      system(“tput clear”)        /* Used for substituting CLS with
                                                system(“tput clear”) in the program
                                                at time of pre-processing stage during
                                                compilation. All CLS will be replaced
                                                with system(“tput clear”) in code */
/* system() is a function used for escaping & executing commands in shell */

#define TRUE 1
#define NO_OF_ELE 25

struct Employee {
                         int Code;
                         char Name[26];
                         float Basic;
                    };

struct Employee myemp[NO_OF_ELE]; /* Global variable outside all functions */

void addopt(void); void printopt(void);void printoptP(void);

main()
{
         menu();
         exit(0);
}

int menu(void)
{
      char choice;
      do
      {
             CLS;                     /*will be replaced with system(“tput clear”)
                                        at pre-processing stage */

                printf(“nnnnttttMAIN MENUnn”);
                printf(“nnttt A. Add details n”);
                printf(“nttt P. Print details using MyEmpn”);

                                       Mani Sridharan – bdmsts@gmail.com
printf(“nttt O. Print details using Pointer n”);
              printf(“nttt E. Exit nn”);
              printf(“nttt Choice : “);

              choice=getchar();fflush(stdin);

              switch(choice)
              {
              case „A‟:
              case „a‟ :    addopt();break;

              case „P‟ :
              case „p‟ :    printopt();break;

              case „O‟:
              case „o‟ :    printoptP();break;

              case „E‟ :
              case „e‟ :    return;
              }
       }while(TRUE);
}

void addopt(void)
{
       int i=0;
       for(;i<NO_OF_ELE;i++)
       {
               CLS;
               printf(“nnnttttAccepting Details for Employee:-%02d”,i+1);
               printf(“nntttt Code : “);
               scanf(“%d”,&myemp[i].Code);fflush(stdin);
               printf(“nntttt Name : “);
               gets(myemp[i].Name);

              printf(“nntttt Basic : “);
              scanf(“%f”,&myemp[i].Basic); fflush(stdin);
       }
}

void printopt(void)
{
       int i=0;

       for(;i<NO_OF_ELE;i++)
       {
              CLS;
              printf(“nnnttttPrinting Details for Employee:-%02d”,i+1);
              printf(“nntttt Code : %d“,myemp[i].Code);
              printf(“nntttt Name : %s“,myemp[i].Name);
              printf(“nntttt Basic : %f “,myemp[i].Basic);
              printf(“nntttPress [Enter] to Continue“);
              getchar();fflush(stdin);
       }

                                      Mani Sridharan – bdmsts@gmail.com
}
void printoptP(void)
{
       int i=0;
       struct Employee *eptr;

       for(eptr=myemp;i<NO_OF_ELE; eptr++,i++)
       {
              CLS;
              printf(“nnnttttPrinting Details for Employee:-%02d”,i+1);
              printf(“nntttt Code : %d“,eptr->Code);
              printf(“nntttt Name : %s“,eptr->Name);
              printf(“nntttt Basic : %f “,eptr->Basic);
              printf(“nntttPress [Enter] to Continue“);
              getchar();fflush(stdin);
       }
}

EXERCISE:

1. Write a program to accept details of 50 students(maximum per class). There are four class-rooms. Details
include Registration no, Rollno, name, DOB, marks in language 1, language 2, Maths, Science & Social.
Implement the following options. (Take care of all possible validations).

a. Details like name, dob is accepted on-line at the time of registration, Classroom is taken as a choice from
the user and the Registration number is automatically generated for that class for the new student.

b. Once the registration is complete an option for the sorting the details for each & every class to be
provided. It has to generate the Roll Number for each & every student in the ascending order of Name in
that class.

c. An option to be provided for accepting marks for each & every student in each & every class. This option
should display Roll number & Name to accept marks.

d. An option to be provided for displaying the first 3 toppers of the school.

e. Attendance list & Mark list to be generated from the system for each & every class.
   A candidate is eligible for passing only the score in all subjects > 50.

f. Graded Mark list to be printed for those students who have passed the examination in each & every class.
             Total Marks          Grade
             450 and Above Outstanding
             400 - 449            Excellent
             300 - 399            Good
             250- 299             Fair

b. UNIONS:-
       Unions are used for collecting a set of data elements like structures. In Union all the data elements
inside Union will share the same memory area. In otherwords the sizeof the Union is the sizeof the data-
element that has the maximum size in the Union. Unions are creating using union keyword.

       Example:
                      union Pay
                            {

                                       Mani Sridharan – bdmsts@gmail.com
float basic;
                                      short int Wages;
                              };

In the above example, the size of the union Pay is 4 bytes because float is of maximum length. If the
employee is Salaried Employee, the value is stored in Basic else stored in Wages. To create an instance of
union, the syntax used is
               union <Union name> <Variable Name>;

       Example:
            a. union Pay amount;
            b. union Pay *value;

Accessing Elements in an Union:
Each and every attribute is referenced by putting instance‟.‟attribute in case of STATIC variables and
instance->attribute in case of POINTER variables.

Example:
     amount.Basic=4000;                /* writing to commonly shared area */
     value=(union Pay *)malloc(sizeof(union Pay));     /* Allotting memory for
                                                          pointer variable */
     value->Wages=25;

c. TYPEDEF:-
        Typedef is reserve word used for adding an meaningful alias to existing data types. While writing
large applications there could be possibility that two programmers defining a variable as different types in
their code that might lead to loss of data and ambiguity in definition. To overcome this problem, typedef‟s
are used.

       A popular example is to store currency. Some programmers might define currency as float and others
as double and leads to confusion. In this case, it is better to create a type by name “MONEY” to define
currency in all their programs. If “MONEY” is defined as float in all the programs, where the instance of
MONEY is found it will be treated as float.

       It is also used for maintaining the code. If in future, if the size is to be increased, it enough to change
the typedef of MONEY as double, since all the programs uses MONEY and reduces heavy manual effort in
maintaining the code.

Example:

typedef float MONEY;                          /* MONEY is treated as float in programs */
typedef struct Employee EMPLOYEE;             /* EMPLOYEE is treated as struct Employee in Programs */


Creating an Instance:

       MONEY basic;
       MONEY hra;
       MONEY inv_amt;

       EMPLOYEE emp,emp1,emp2;

Note: Structures can contain unions, typedef & structures and pointers as data-members and the case is
also true for unions. Whenever we have a pointer pointing to structure or union, make sure it pointing to

                                        Mani Sridharan – bdmsts@gmail.com
valid memory address before accessing and it can be implementing by allocating memory or by pointing
to an existing instance of that type.

                                                      FILES

       Files in Unix Operating system are classified as Flat files, Directory files, Block devices, Character
devices, FIFO‟s and Symbolic links. In our discussion, we shall have a look over Flat files and its types
alone.

FLAT FILES or NORMAL FILES

        These files are used for storing data on the secondary storage for repeated usage. Flat files can be
further classified as text files & binary files. Text files contains the data in readable form and binary files in
compressed form. All the standard „C‟ library functions used for file operations are declared in „stdio.h‟. File
operations include opening a file, readingwriting contents.

Creating or Opening a Text or Binary File:

       fopen(“filename”,”mode”) is the Standard „C‟ library function used for creating a new file or
opening an existing file. It takes the filename and mode in which it has to be opened as arguments. It
returns a pointer of type „FILE‟, a structure defined in „stdio.h‟. If fopen() fails, it returns NULL,
#define variable in „stdio.h‟. The various modes and their operations are provided in the following tabular
column:

Mode      Remarks                                               Location of File Pointer
“w”       Create a new file or overwrite the file(if exists).   Beginning of File
“r”       Open the file for reading.                            Beginning of File
“a”       Open the file for appending.                          End of the file
“w+”      Like „w‟ mode and allows updating.                    Beginning of File
“r+”      Like „r‟ mode and allows updating.                    Beginning of File
“a+”      Like „a‟ mode and allows updating.                    End of the file

Examples:

       FILE *f1;
       FILE *f2, *f3;

       f1=fopen(“new.pc”,”w”);
       if( f1 == NULL)
       {
               printf(“Error opening New.pc in write mode n”);
               perror(“The Reason is “);
               /* Standard „C‟ library function to print the reason for failure */
               exit(0);
       }

       f2=fopen(“old.xc”,”r+”);
       if( f2 == NULL)
       {
               printf(“Error opening old.xc in read-write mode n”);
               perror(“The Reason is “);
               /* Standard „C‟ library function to print the reason for failure */
               exit(0);
       }
                                         Mani Sridharan – bdmsts@gmail.com
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics
Introduction to C Programming Language History and Basics

Weitere ähnliche Inhalte

Was ist angesagt? (20)

Compiler design Introduction
Compiler design IntroductionCompiler design Introduction
Compiler design Introduction
 
Compiler design
Compiler designCompiler design
Compiler design
 
Introduction to compilers
Introduction to compilersIntroduction to compilers
Introduction to compilers
 
Python Programming
Python ProgrammingPython Programming
Python Programming
 
notes on Programming fundamentals
notes on Programming fundamentals notes on Programming fundamentals
notes on Programming fundamentals
 
Lecture 01 introduction to compiler
Lecture 01 introduction to compilerLecture 01 introduction to compiler
Lecture 01 introduction to compiler
 
Introduction to Python Basics Programming
Introduction to Python Basics ProgrammingIntroduction to Python Basics Programming
Introduction to Python Basics Programming
 
Python quick guide1
Python quick guide1Python quick guide1
Python quick guide1
 
C Programming - Refresher - Part I
C Programming - Refresher - Part I C Programming - Refresher - Part I
C Programming - Refresher - Part I
 
Programing paradigm &amp; implementation
Programing paradigm &amp; implementationPrograming paradigm &amp; implementation
Programing paradigm &amp; implementation
 
Compiler Construction | Lecture 1 | What is a compiler?
Compiler Construction | Lecture 1 | What is a compiler?Compiler Construction | Lecture 1 | What is a compiler?
Compiler Construction | Lecture 1 | What is a compiler?
 
I18n
I18nI18n
I18n
 
Chapter 1 1
Chapter 1 1Chapter 1 1
Chapter 1 1
 
Unit1 pps
Unit1 ppsUnit1 pps
Unit1 pps
 
Presentation on java
Presentation on javaPresentation on java
Presentation on java
 
C Course Material0209
C Course Material0209C Course Material0209
C Course Material0209
 
basics of compiler design
basics of compiler designbasics of compiler design
basics of compiler design
 
Lecture 1 introduction to language processors
Lecture 1  introduction to language processorsLecture 1  introduction to language processors
Lecture 1 introduction to language processors
 
C languaGE UNIT-1
C languaGE UNIT-1C languaGE UNIT-1
C languaGE UNIT-1
 
Introduction to c++ ppt 1
Introduction to c++ ppt 1Introduction to c++ ppt 1
Introduction to c++ ppt 1
 

Ähnlich wie Introduction to C Programming Language History and Basics

computerprogramminglanguages-201216152310.pptx
computerprogramminglanguages-201216152310.pptxcomputerprogramminglanguages-201216152310.pptx
computerprogramminglanguages-201216152310.pptxSubramanian Mani
 
Lecture_1_Introduction_to_Programming.pptx
Lecture_1_Introduction_to_Programming.pptxLecture_1_Introduction_to_Programming.pptx
Lecture_1_Introduction_to_Programming.pptxChewe Lulembo
 
Introduction of c language
Introduction of c languageIntroduction of c language
Introduction of c languageTeena Bosamiya
 
What is a programming language.docx
What is a programming language.docxWhat is a programming language.docx
What is a programming language.docxssuser9846a6
 
English de lenguaje de programacion
English de lenguaje de programacionEnglish de lenguaje de programacion
English de lenguaje de programacionVillalba Griselda
 
all languages in computer programming
all languages in computer programmingall languages in computer programming
all languages in computer programminghamza239523
 
Abstraction level taxonomy of programming language frameworks
Abstraction level taxonomy of programming language frameworksAbstraction level taxonomy of programming language frameworks
Abstraction level taxonomy of programming language frameworksijpla
 
Programming languages
Programming languagesProgramming languages
Programming languagesgaurav jain
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAAiman Hud
 
Computer program, computer languages, computer software
Computer program, computer languages, computer softwareComputer program, computer languages, computer software
Computer program, computer languages, computer softwareSweta Kumari Barnwal
 
Introduction Programming and Application Lecture 1.pptx
Introduction Programming and Application Lecture 1.pptxIntroduction Programming and Application Lecture 1.pptx
Introduction Programming and Application Lecture 1.pptxMahamaHaruna
 
Generations Of Programming Languages
Generations Of Programming LanguagesGenerations Of Programming Languages
Generations Of Programming Languagespy7rjs
 
C Unit 1 notes PREPARED BY MVB REDDY
C Unit 1 notes PREPARED BY MVB REDDYC Unit 1 notes PREPARED BY MVB REDDY
C Unit 1 notes PREPARED BY MVB REDDYRajeshkumar Reddy
 
Basic terms used in microprocessor
Basic terms used in microprocessorBasic terms used in microprocessor
Basic terms used in microprocessorRamaPrabha24
 

Ähnlich wie Introduction to C Programming Language History and Basics (20)

computerprogramminglanguages-201216152310.pptx
computerprogramminglanguages-201216152310.pptxcomputerprogramminglanguages-201216152310.pptx
computerprogramminglanguages-201216152310.pptx
 
Computer programming languages
Computer programming languagesComputer programming languages
Computer programming languages
 
Lecture_1_Introduction_to_Programming.pptx
Lecture_1_Introduction_to_Programming.pptxLecture_1_Introduction_to_Programming.pptx
Lecture_1_Introduction_to_Programming.pptx
 
Computer languages 11
Computer languages 11Computer languages 11
Computer languages 11
 
Introduction of c language
Introduction of c languageIntroduction of c language
Introduction of c language
 
Unit 1
Unit 1Unit 1
Unit 1
 
Assignment on basic programming language
Assignment on  basic programming languageAssignment on  basic programming language
Assignment on basic programming language
 
What is a programming language.docx
What is a programming language.docxWhat is a programming language.docx
What is a programming language.docx
 
Chapter 2.pptx
Chapter 2.pptxChapter 2.pptx
Chapter 2.pptx
 
English de lenguaje de programacion
English de lenguaje de programacionEnglish de lenguaje de programacion
English de lenguaje de programacion
 
all languages in computer programming
all languages in computer programmingall languages in computer programming
all languages in computer programming
 
Introduction to programming c
Introduction to programming cIntroduction to programming c
Introduction to programming c
 
Abstraction level taxonomy of programming language frameworks
Abstraction level taxonomy of programming language frameworksAbstraction level taxonomy of programming language frameworks
Abstraction level taxonomy of programming language frameworks
 
Programming languages
Programming languagesProgramming languages
Programming languages
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIA
 
Computer program, computer languages, computer software
Computer program, computer languages, computer softwareComputer program, computer languages, computer software
Computer program, computer languages, computer software
 
Introduction Programming and Application Lecture 1.pptx
Introduction Programming and Application Lecture 1.pptxIntroduction Programming and Application Lecture 1.pptx
Introduction Programming and Application Lecture 1.pptx
 
Generations Of Programming Languages
Generations Of Programming LanguagesGenerations Of Programming Languages
Generations Of Programming Languages
 
C Unit 1 notes PREPARED BY MVB REDDY
C Unit 1 notes PREPARED BY MVB REDDYC Unit 1 notes PREPARED BY MVB REDDY
C Unit 1 notes PREPARED BY MVB REDDY
 
Basic terms used in microprocessor
Basic terms used in microprocessorBasic terms used in microprocessor
Basic terms used in microprocessor
 

Introduction to C Programming Language History and Basics

  • 1. C Programming by Mani Sridharan All Rights Reserved. No part of this material may be reproduced or modified by any means without written permission from Sridharan Mani. Warning and Disclaimer: This material is designed to provide information about „C‟ Language. Every effort has been made to make this material as complete and as accurate as possible, but no warranty or fitness is implied. The information is provided on an “as is” basis. The authors, distributors and publishers shall have neither liability nor responsibility to any person or entity with respect to any loss or damages arising from the information contained in this book or from the use of the programs that may accompany it. Mani Sridharan – bdmsts@gmail.com
  • 2. Welcome to the Land of 'C' 'C' is a programming language developed by Dennis Richie & Kerningham. It standards between 2nd rd and 3 generation languages. It is a powerful language for Business & Scientific applications. It can be used for writing commercial applications like financial accounting, banking operations as well as scientific applications like controlling a robot, electrical furnaces, nuclear reactors and so on. Some of the popular packages written out of 'C' are UNIX - Operating System. C++ - Compiler. SYBASE,ORACLE - RDBMS. Before we start looking at 'C' as a language, let us have a look over the generation of languages. Let us understand the term language. Language is a method for communication. Assume an Indian wants to discuss about building construction with a Mexican. Here the Indian and the Mexican should have some standards for discussions. Basically they have to communicate by means of a common channel which both of them can understand. Assume the Spaniard knows only 'Spanish' and the Indian knows only 'Hindi'. There will be a lot of misunderstanding during the communication. The computer understands only Zeroes and Ones and we need to communicate in Zeroes and Ones. Hence, the MACHINE Language was introduced and it forms the First Generation Language. Machine Language instructions were made of ones & zeroes that could be easily understand by the computer. Exercise: Why a computer can understand only Zeroes & Ones and not other numbers ? GENERATION OF LANGUAGES First Generation Language: First Generation Language is also known MACHINE LANGUAGE. Instructions are in binary format. All the instructions were in zeroes and ones. For Example if you want to add two numbers, say 5 & 6, in MACHINE LANGUAGE for Intel 80586 processor. You need to type the instruction as 101110000000010100000000 101110110000011000000000 0000000111011000 Machine Language is highly complex to write. It is also processor dependant. No conversion of instructions is required as it is in the host language and faster in execution. Second Generation Language: It is also known as Assembly Language. Here the instruction set is in simple English. For each instruction in Machine Language a mnemonic code is given. For example 10111000 -> MOV AX, 00000001 11011000-> Add AX,BX For adding 5 + 6, the instructions in assembly language would be MOV AX, 0005 MOV BX, 0006 ADD AX, BX Now AX will contain 000B(in hex) -> 00000000000010011(in binary) Mani Sridharan – bdmsts@gmail.com
  • 3. Assembly Language was easy to write. But it required a lot of skills in writing programs, since accessing of memory and device interfacing had be done directly. The language is also processor dependant. If we write a program for the Motorola 68020 processor, the program cannot be compiled and executed in 80486 Intel processor. Similarly, if we write a program for 80286 processor with advanced instructions of 80286, it is not possible to run the same program in the 8088 processor. Even though it is as faster as Machine Language, it is not portable across the system. Conversion from Mnemonic code to Machine code should be done before executing the program. The programmer‟s language is in simple English Mnemonic codes and the host language is in Bits. For converting Assembly code to Machine an Assembler is used. Two of the popular Assemblers are the TASM(Turbo Assembler) and the MASM(Macro Assembler). Third Generation Language: As we saw earlier, it is difficult to program using Machine language and assembly language is machine dependant. Computer professionals started looking at a language that was machine independent and could provide a satisfactory amount of performance. Third Generation languages are machine independent and easy to program. They have the methods of defining the data as number, character, date and so on. Here data definition statements and looping constructs were provided to help the programmers to develop applications easily. The software is like a book and resembles the English language. Let us have a look over a book (Software) written in English („C‟) with a Third Generation Language. Each book (software) is made of multiple chapters (programs). Each chapter (program) is made of paragraphs (functions) and each paragraph (function) is made of statements terminated by a period(;) and each statement is made of words (keywords and operators). Keywords and operators are specific to a language. Keywords & operators can be compared to the 26 alphabets of English Language. Third Generation languages are easy to write, but the performance is comparatively lower than FIRST & SECOND generation languages. Conversion is required because Third Generation languages are English like, whereas, the computer knows only binary instructions. To overcome this problem each language comes out with its own converter to convert their code into machine code. The converter used in conversions is known as a "COMPILER" or "INTEPRETOR", depending on the method of conversion. If we write a program in third generation language, we need to have the compiler for that language to convert into machine code. So Source code is machine independent whereas, the Compiler is processor dependant. In simple terms, assume you (SOURCE) have a servant (COMPILER) who can talk in any language (PROCESOR). Let us assume that you want to convey "How are you?" to a Spaniard, Polish, Tamilian & Mumbaite. In third generation language your will say "HOW ARE YOU?". Your servant will convert this to “Que te pasa” in Spanish, “Jak Sie mast” in Polish, "eppadi irrukirai?" in Tamil and "Thum kaisa ho?" in Hindi to allow different people to understand and proceed with their normal operations. Here, you are the Source code and your servant is the compiler that converts the code according to the system. Examples of Third Generation Languages are: C, C++, JAVA, FORTRAN, PASCAL and BASIC. Mani Sridharan – bdmsts@gmail.com
  • 4. INTEPRETORS are used for converting the source program line by line while the COMPILER converts in one stroke. BASIC is an example of an INTEPRETOR based language and all the rest of them in the example are COMPILER based. Exercise: Discuss the advantages and disadvantages of a Compiler and an Intepretor in detail. Identify their application areas. Fourth Generation Languages: As time passed, we wanted to have our lives to be made much simpler. It so happened that a programmer needs to understand the basis of a programming language to work with the systems. Professionals wanted to break this barrier. They wanted a language that resembles English and was easy for the end user to use without having any knowledge of hardware and system. The language that evolved out of this research is known as SQL (STRUCTURED QUERY LANGUAGE). It is an easy language and simple to use. It is easy to write programs in this language as it does not contain any device or memory operations as in the other generations of languages. Here we do not worry about the location of the data or the format of the data for querying. We do not bother to initialize printer or open a file to get reports as per requirements. SQL is the language set of RDBMS. SYBASE's SQL is known as TSQL(Transact Structured Query Language). ORACLE's SQL is known as PLSQL. I hope this would give you a general idea of computer languages. Now we will look at a specific third generation language 'C'. Mani Sridharan – bdmsts@gmail.com
  • 5. „C‟ LANGUAGE “C” lies between SECOND & THIRD generation languages. Using 'C' we can interface with devices directly with the help of hardware interrupts; like a second generation language; or we can use standard functions of 'C' to access peripherals without a knowledge of the device interfacing mechanism(ABSTRACTION of the earlier). Let us have a look over this example to have a clear idea of the statements made. Assume we want to print "C" on the Screen. LIKE A 2GL: Method 1: char far *scr[]=0xB8000000L;  refers to Video RAM Memory in VGA monitors. scr[0]='C';  Writing a character 'C' on the memory area which causes interrupt 10 to happen and the character is printed on monitor. Method 2: asm mov al,46  assigning al register with ascii value of 'C' in hex. asm mov ah,0A  assigning ah register with the function no. asm mov cx,01  counter set to indicate only one character asm int 10h  invoking interrupt 10 to call the necessary BIOS routines to handle the situation. asm int 20h  Exiting normally after printing the character on VDU LIKE A 3GL: printf("C");  printf does all the operations above said and it is a part of Standard 'C' library. Don't concentrate much on the code as it is just an example. The example illustrates that „C‟ language can behave either as a 2GL to directly interact with the devices or like a 3GL by using the standard library functions of it. The Computer can be defined as an electronic device that is capable of storing and processing data. A Computer is a data oriented machine but not knowledge oriented. It cannot think or perform any actions on its own. As professionals we need to program the way we want it to work. From the above statements we could infer that we need to provide a mechanism for storing and processing data. So a third generation language should provide means for storing and processing data. To provide a clear picture, any third generation language should contain the following components. COMPONENTS OF A LANGUAGE: 1. KEYWORDS. 2. OPERATORS. Keywords & Operators are like alphabets to English language. They forms the words, sentences & paragraphs of a language. „C‟ Language is made of 32 reserve words. Keywords provides the mechanism for 1. Defining data (as String, Number, Date,...). Mani Sridharan – bdmsts@gmail.com
  • 6. 2. Iteration (Repeated operations). Operators provides the method for doing arithmetic and logical operations. Assume we are interested in printing the sum of 5,6. The computer is a dumb fellow. It doesn't know what a number is or how to add numbers. So the language has to educate the computer and tell what the number is and how to find the sum of it. For defining the number we use KEYWORDS. For calculation we use OPERATORS. In 'C' it would be int no; no=5+6; here "int" keyword defining "no" as number. "=" is the assignment operator defined by the language. "+" is the addition operator defined by the language. Understand that "=","+" are like normal characters to a computer. The language has to associate the appropriate meaning to it for usage. Exercise: 1. Can you identify the differences between a LANGUAGE and a COMPILER and how a LANGUAGE and COMPILER are related? 2. Define your own language say 'D‟. Identify the data defining keywords and the operations possible with those datatypes with the symbol of the operator in the format shown below. Data Type Type of Data Operation Symbol KEYWORDS: The 'C' language is made of 32 keywords. Keywords are the alphabets to a language. They keywords are used for:  defining the type of data they are going hold  decision making  iteration operations. Computer stores data in terms of bits. 1 bit --> 0 or 1 (Binary Digit). 4 bits --> Nibble (Hex). 8 bits --> Byte (1 character (one alphabet in English)). 1024 bytes --> 1 Kilobyte. 1024 Kilobytes --> 1 Megabyte. 1024 Megabytes --> 1 Gigabyte. 1024 Gigabytes --> 1 terabyte. Each and every symbol in the keyboard is associated with a number. The number is allotted by ASCII(American Standard Code for Information Interchange), an international organization. The number associated with 'A' is 65. The number associated with 'a' is 97. The number associated with '0' is 48. Mani Sridharan – bdmsts@gmail.com
  • 7. When we want to represent 'A' in the computer, it would be represented as 65. 65 is converted into binary format and represented in a byte. We will have a look at keywords and operators when we start programming. Exercise: 1. How many Bytes & Hex the following data would require? a. “God is Love” b. “Hello World” c. “Y” d. “No defeat is final, until we stop trying” e. “Tough times never last but tough people do” 2. Express 67 in binary format and justify how it accommodates in a byte. 3. How many characters can be represented using a byte? Justify your answer. 4. What are the other standards defined for representing characters in Computer? Illustrate with examples. 5. Statement : 'T' is equal to 't' in Computers. Is the statement true? Justify. PROGRAMMING in C:- A 'C' program contains the following parts. 1. Header file --> contains information about the functions called. 2. main() --> Starting Point of 'C' program. 3. Statements --> The statements to be executed. 3. exit() --> Exit point of 'C' program. NOTE:- 'C' program file names should always terminate with .c extension. A sample 'C' program "first.c". Use vi for typing the code. first.c #include <stdio.h> main() { puts("Welcome to C"); exit(0); } #include is a keyword is used for including a header file. Here we are using a header file by name "stdio.h" which contains the declaration of puts function. main() is a function that indicates the starting point of execution. puts() is a function that takes "Welcome to C" as parameter for printing on to screen. exit() is a function that is used for terminating the 'C' program execution. Note: Each and Every Statement is terminated by ';' like '.' in English. { } is used for representing the beginning of function (or) paragraph and end of function (or) paragraph. Mani Sridharan – bdmsts@gmail.com
  • 8. main is the name of the function(in English - paragraph title) which is made of 2 statements(in English - lines). '{' indicates the beginning and '}' indicates the end of the paragraph. COMPILING & EXECUTING. After saving the file, compile using cc as shown below. $ cc first.c -ofirst Then execute first and see what happens. $first Exercise. 1. Write a program to print your name 5 times on Screen. 2. Write a program to print the following designs. a) ******* b)******* c) * ****** ****** *** ***** ***** ***** **** **** ******* *** *** ***** ** ** *** * * * 3. In puts function instead of enclosing the parameter in double quotes, enclose in single quotes and see what happens. 4. Use puts to print the value 5 on the screen without using quotes . Justify the reasons for error. Mani Sridharan – bdmsts@gmail.com
  • 9. COMPILER & COMPILATION Before we proceed further with the constructs of Language, let us try to figure out what a compiler does. We have multi pass compilers and Single pass compilers. A pass refers to the scanning of Source Code from top to bottom. 'C' Compilers are usually 2 pass compilers. A compiler is a software program is used for converting the source code(Native Language) either into an object code(Machine Language) for execution or Assembly code(2GL,Assembly language) for Assembler to convert into Machine Code. The compiler is made of following components. 1. Lexical Analyzer. 2. Syntactic & Semantic Analyzer. 3. Intermediate Code Generator. 4. Intermediate Code Optimizer. 5. Final Code Generator. 6. Error handler. 7. Symbol table. SOURCE CODE Lexical Analyzer Syntactic Analyzer Symbol Table Error Handler Semantic Analyzer Intermediate Code Generator Intermediate Code Optimizer Final Code Generator OBJECT CODE Any process that has to be executed in a computer should be loaded in the primary memory of the Computer(RAM). Computers can understand only ONE‟s & ZERO's. The Machine code contains the variables, functions in the form of address loaded on the main memory. A compiler converts all the variables and functions into the machine's memory addresses for proper execution. Each and every variable name and function name in the source code is known as a symbol. LEXICAL ANALYSER. This component of a Compiler divides the source program into a set of tokens. A token could be a keyword, or an identifier, or an operator or a constant value. Mani Sridharan – bdmsts@gmail.com
  • 10. Let us have a look at this example. char alpha='A'; puts(str); Lexical Analyzer would split this as char--> keyword. alpha--> identifier = -----> operator. 'A' ---> Value. puts ---> function(identifier). str ---> identifier The statement is made of four tokens. The identifiers would be stored in the symbol table for future reference. SYMBOL TABLE: The Symbol table contains the name, type, size and virtual address of the identifier. Virtual address are usually represented in hex. To provide clarity in understanding the addresses are represented as numbers in the entire book. SYMBOL NAME TYPE Size MEMORY ADDRESS (start) (end) alpha character 1 400 400 puts function 4 600 603 (int) str character 25 700 724 Symbol table contains the information of all the variables and function defined in the program. It contains the memory address pointed by the symbol. Any operation made with the symbol would be made in that memory address pointed by it. When we refer to variable 'alpha' in a program, it means we are operating memory address 400. Let us look at this small piece of Code. alpha='A'; A -> 65 (ASCII value) = 01000001 Binary. 'alpha' is pointing to 400th byte in Memory Location. As we know earlier a byte can hold 8 bits. 01000001 is stored in memory location 400 which is equivalent of storing 'A' in that location. Exercise: What does the following statement do ? How does it operates on memory ? Assume alpha containing 'C' in all cases. alpha=alpha + 2 alpha=alpha / (2 * alpha) alpha=alpha - 1 Mani Sridharan – bdmsts@gmail.com
  • 11. SYNTATIC & SEMANTIC ANALYSER: It is used for checking the syntax and semantics of the code as defined by the language. Syntax and Semantics are predefined by the language. Syntax refers to the way the statements are to be framed. For example: Syntax of 'if' is if <condition> { } In the program if use 'if' as <condition> if { } it is syntactically wrong. Semantics refers to the grammar of the language. For example: 'puts' is a function used for printing a stream of characters on Screen. puts("Welcome") ---> valid usage. puts(4000) ---> Grammatically wrong. The above statement is syntactically correct but semantically wrong. It has been defined so that puts can print a stream of characters on screen and not a number. The Syntactic and Semantic analyzer creates a parse tree after scanning the tokes passed by Lexical Analyzer. LR parsing, Canonical Parsing, Bottom-up parsing, top-down parsing are some of the methods used for parsing. Refer to Compiler Construction of Aho Ullman for more details on Parsing. Exercise: How a Compiler knows that puts can take only a string and not a number is an interesting question ? It is very true that puts is not a part of 'C' language and arguments that it takes is not defined in the language part. Can you tell me how the Compiler identifies the arguments passed to the functions are valid or not ? INTERMEDIATE CODE GENERATION: Using the parse trees an intermediate object code is generated. It is one to one conversion of Source code into machine language. All the Symbols are replaced by virtual machine addresses. INTERMEDIATE CODE OPTIMISER: This part of the compiler optimizes the code that was generated earlier. For example consider the following piece of source code. if a == b goto Lab1 if a < b goto Lab2 if a > b goto Lab1 Mani Sridharan – bdmsts@gmail.com
  • 12. Object code generated after Intermediate Code Generation will also contain same steps. The Intermediate code Optimizer would optimize it to if a < b goto I2 goto I1 Now have a look over the no. of steps.(CPU operations are reduced drastically and hence improves performance). Intermediate Code Optimizer, Optimizes for Speed & Size. FINAL CODE GENERATION: The code generated after Optimization is the final object code. Object contains the one to one conversion of source code. LINKING The final code generated by the compiler contains the equivalent statements of source language in machine code. In our program, if we have puts("welcome"), the same statement would be written as machine code in object FILE. Now our object file doesn't know what it has to do when it encounters the puts function.(???)The Source program doesn't contain the instructions of puts function and it not a part of 'C' the language. 'puts' is an external symbol(function) with respect to this program. So if our program has to run successfully the code of puts should be also included in our program. So a linker is used for attaching the code of the external functions used in our program. So whenever we use cc compiler, first it creates an object code and then it creates an executable code. Example : $cc first.c -ofirst is equivalent to $cc -c first.c ---> COMPILATION $cc -l first.o -ofirst ---> LINKING Try this out: Type a.c and b.c using vi and answer the questions. Program 1: a.c #include <stdio.h> main() { puts("Welcome"); b(); } Program 2: b.c #include <stdio.h> Mani Sridharan – bdmsts@gmail.com
  • 13. b() { puts("In Program B"); } Exercise: Compile as 1. $ cc a.c b.c -oa $a 2. $ rm a $ cc a.c -oa $a Analyze the output and give reasons. DATA TYPES IN 'C' C has following data types for defining data. Size of data type int is machine dependant and it is equal to the size of “word” of the processor. The size of the datatypes are enclosed in brackets. Data Type Size(in bytes) Storage char 1 alpha-numeric character int 2 or 4 Integers float 4 exponents(real numbers). long 4 Long Integers (can store numbers beyond the width of int) double 8 Long exponents (can store numbers beyond the width of float) short 2 Short Integers(small integers). Exercise: 1. Assume our machine has a memory of 640K out which 300K is available for us. Our Program code occupies 200K in memory. Considering the situation and answer the following questions? 1. Max no. of Integer variables that can be defined in program. 2. Max no. of Character Variables that can be defined. 3. Max no. of Double variables that can be defined. 2. Assume virtual address for the following variables. Create a Symbol table and draw memory maps for them. char first; int number=25; char name[30]; float basic; double squareroot; short empno; long pointer; 3. Integer & float occupies 4 bytes of memory in „C‟. But how, float can store decimals which integer can‟t. Explain. Mani Sridharan – bdmsts@gmail.com
  • 14. CONSTRUCTS IN „C‟ IF CONSTRUCT. Usage: if ( <condition> ) { statement; statement; } else { statement; statement; } If we have only one statement to processed after checking for the conditions, the {} braces are not required. NOTE: „=‟ is used for assignment and „==‟ is used for checking. Any zero assignment in condition is considered to be False and non-zero assigment is considered to be True. All the operators returns a zero or a non-zero value in „C‟ to indicate True or False states. Let us write a small program which accepts a character and checks whether it is '1' or '0'. getchar, fflush, putchar & puts are standard library functions of C. getchar() -> used for accepting character. fflush() -> clearing the buffer (here input buffer). putchar() -> printing a character on Screen. puts() -> printing a stream of characters on Screen. Note: “stdin” refers to the buffer associated with standard input device - keyboard. “stdout” refers to the buffer associated with standard output device - usually Visual display unit. “stderr” refers to the buffer associated with standard error device - usually Visual display unit. “stdin, stdout & stderr” are #defined variables in „stdio.h‟ Second.c #include <stdio.h> main() { char alpha; alpha=getchar(); fflush(stdin); if ( alpha == '1' ) { putchar('1'); } if (alpha == '0' ) { putchar('0'); } } Mani Sridharan – bdmsts@gmail.com
  • 15. WHILE & DO WHILE CONSTRUCT While Construct: while ( <condition> ) { statement; statement; statement; } Do While Construct: do { statement; statement; statement; } while( <condition>); Note: The difference between while and do while construct is in while, it checks the condition and executes the statements and in the case of do while it executes the statements and checks the condition. Example: Third.c - To display menu.(using while construct) #include <stdio.h> main() { char choice=„1‟; while ( choice != „0‟ ) { puts(“1. Add”); puts(“2. Mod”); puts(“3. Del”); puts(“0.Exit”); choice=getchar();fflush(stdin); /* do something/ } } Third.c - To display menu.(using do while construct) #include <stdio.h> main() { char choice; do { puts(“1. Add”); puts(“2. Mod”); puts(“3. Del”); puts(“0.Exit”); choice=getchar();fflush(stdin); /* do something */ }while(choice != „0‟); } Note: In the above example we have initialized choice to „1‟ whene using while construct to ensure that it enters the loop(in while it checks the condition and enters loop). But it in the case of do while(2 nd method) choice is not initialized because, it enters the loop and then checks the condition. Mani Sridharan – bdmsts@gmail.com
  • 16. Exercise. 1. Write a program to check whether the entered character is an alphabet, or digit or a special symbol. The program should continue functioning till '0' is entered. 2. Write a program to accept 2 characters and print the greatest of them. ( using if and without using if or any constructs) 3. Write a program to accept 3 characters and print the least of them. 4. Write a program to accept a character and it has to check with the previous character. It is has to display whether the current character entered is greater or lesser or equal to the earlier character entered. The program should continue till the user enters '0'. 5. Write a program that reverses the case of the character entered and prints on the screen. The program should terminate when user enters '0'. It should take care of all possible errors. 3. Write a program to swap two characters using a temporary variable and without using a temporary variable. The program should terminate when user enters '0'. It should take care of all possible errors. Mani Sridharan – bdmsts@gmail.com
  • 17. FOR CONSTRUCT for ( <initialization>;<condition>;<new assignment> ) { statement; statement; statement; } Example: Fourth.c - To print from 1 to 100. #include <stdio.h> main() { int i; for(i=1;i<101;i++) { printf(“%dn”,i); } } In the above example we are printing the first 100 natural numbers. Here we are using the for construct for achieving the same. for construct is made of three parts Part 1 is for initialization Part 2 is for condition checking Part 3 is for assigning new values; In this example it assigns 1 to „i‟ (Part 1) and checks whether it is less than 101(part 2), then it executes the statements enclosed in parenthesis which is “printf(“%dn”,i)” and then increments „i‟ by 1(Part 3). Then it goes to Part 2 for checking. If the condition is satisfied statements are executed and does the action specified in Part 3 and hands the control to Part 2. This loop continues and the statements are executed till the condition is satisfied. Break Reserve Word break is a reserve word used for exiting from a loop(while, do while & for). Example: To illustrate the usage of „break reserve word‟ Fifth.c - To print from 1 to 100. #include <stdio.h> main() { int ctr=1; while(ctr) { if (ctr > 100) break; printf(“%dn”,ctr); ctr=ctr+1; } } In the above example, the while loop terminates when the ctr contains the value 100. The termination is made possible by the break reserve word. Continue Reserve Word. Mani Sridharan – bdmsts@gmail.com
  • 18. continue is a reserve word used to place control to the top of the loop (while ,do while & for). Example: To illustrate the usage of „continue reserve word‟ Sixth.c - To print from 1 to 100. #include <stdio.h> main() { int ctr=0; do { ctr++; printf(“%dn”,ctr); if (ctr < 101) continue; break; }while(1); } In the above example, the do while loop continues till the ctr reaches 101. When ctr contains 101, the condition in the „if‟ statement fails and executes the break reserve word to terminate from the loop. When ctr is less than 101, the reserve word continue takes the control back to the top of the loop (i.e) ctr++ to increment ctr by 1 and to proceed with rest of the operations. Return Reserve Word. return is a reserve word used for return the control back to the calling routine from the sub routine. Example: To illustrate the usage of „return reserve word‟ Seventh.c - To return the character entered by the user to the shell #include <stdio.h> main() { char alpha; puts(“Enter a character”); alpha=getchar(); fflush(stdin); puts(“Entered Character is “); putchar(alpha); puts(“At Shell prompt type „echo $?‟ to print the ascii value of the character”); return alpha; } In the above example, return reserve word causes the ascii value of the character entered to be returned to the shell. SWITCH CONSTRUCT Switch is used as a substitute to “if”. In a situation if we have different operations to be performed depending on the value on a variable, the switch construct is usually replaced with “if” construct to reduce the complexity of the code. switch(variable) { Mani Sridharan – bdmsts@gmail.com
  • 19. case value1: statement; statement; break; case value2: statement; break; case value3: case value4: statement; /* for value3 & value 4 same set of statements are executed */ statement; break; default : statement; statement; break; /* if none of the values tally */ } Eight.c - To display menu & use switch case. #include <stdio.h> main() { char choice; do { puts(“1. Add”); puts(“2. Mod”); puts(“3. Del”); puts(“0.Exit”); choice=getchar();fflush(stdin); switch(choice) { case „1‟: printf(“In Add option”); break; case „2‟: printf(“In Mod option”); break; case „3‟: printf(“In Del option”); break; case „0‟: return; default : printf(“Invalid Choice: Range[0-3]”);break; } }while(1); } A look at library functions printf & scanf printf: printf is a library function used for displaying a character or a stream of characters, integer, float, double or long on the standard output device. Syntax : int printf(const char *, arg1,arg2,....); first parameter (const char *) refers to format. Format Used for %c Character %d Integers, short int, long int %s String %ld Long %x Hexa-decimal %o Octal Mani Sridharan – bdmsts@gmail.com
  • 20. %h Short %f Float %L Long Double %e, %E, %g Float %p Address of the variable Example : printf(“%s”,”Hello World”); printf(“%d”, 234); printf(“%s%d”,”Hello World”,234); printf(“%d%s%d”,234,”Ramesh”,2342); printf(“%p”, “Hello World”); printf(“%02d”,5); printf(“%*.*s”, 15,15, “Hello World”); printf(“%h”, 23); printf(“%o”, 94); printf(“%x”, 12); printf(“%d”, 0x0004); scanf: scanf is a library function used for accepting a character or a stream of characters, integer, float, double or long from the standard input device. Syntax : int scanf (const char *, (address of arg1),(address of arg2),....); first parameter (const char *) refers to format. Format can specify the sequence of characters to be accepted using [], ^ . Format Used for %c Character %d Integers, short int, long int %s String %ld Long %x Hexa-decimal %o Octal %f Float %h Short %L Long Double %e, %E, %g Float %p Address of the variable Example : char c; char str[50]; int j; float f; scanf(“%c”,&c); scanf(“%s”, &str); or scanf(“%s”,str); scanf(“%c%s”,&c,&str); scanf(“%25s”,str); / * Accept a max of 25 characters */ scanf(“%c%s%d”,&c,&str,&j); scanf(“%f”,&f); scanf(“%[A-Z]”,str); /* Valid Characters are only A to Z */ scanf(“%[^!]”,str); /* Accepts till factorial is entered */ scanf(“%d%s%f”,&j,&str,&f); NOTE: If we refer to the variable name, it refers to the content of the variable. If we want know the address of the variable, we must put „&‟ before the variable name. When we use printf we are printing the content and we just refer the variable name and in the case of scanf we have to store the details at the Mani Sridharan – bdmsts@gmail.com
  • 21. location of the variable and hence we should specific „&‟ before the variable. Exception to this rule is in the case of array, variable name and &variable name refers to the address. Arrays are vector quantities and all base types are scalar quantities. EXERCISE: 1. What would be the output of i,j at the end of each and every case: a. for(i=0;i<100;j=i,i++); b. for(i=0;i<100;j=i++); c. for(i=0;i<100;j=++i); d. for(i=j=5;(i<100) && (j < 200);i=i-5,j+=i); e. for(i=j=5;(i<100) || (j< 200);i=i-5;j+=i); 2. Identify the errors (if there are any) Assume „i‟ to an integer variable in all cases. a. for(i=0, i<100, i++) b. for( ; ; ); c. for(;i<100;); d. for(;; i+=2); e. for(;;i-=2) { printf(“hello”); } f. for(i=0;i<100;printf(“%dn”,i+1),i++); g. for(i=0;;); 3. Write a program to print first 100 even numbers in reverse order. 4. Write a program to print first 100 prime numbers. 5. Write a program to print first 3 Armstrong number. 6. Write a program to print first 3 Perfect numbers. 7. Write a program to accept a number and check it is a prime. 8. Write a program to accept a number and find square-root of that no. 9. Write a program to accept a number and find cube-root of that no. 10. Write a program to accept a number and check it is perfect no. 11. Write a program to accept 30 floats and find the sum, max, min and avg. 12. Write a program to accept the first term(a) and the difference (d) and display the value of n th term in the Arithmetic Progression. [formula: Term n = a + (n - 1)d ] 13. Accept n & m.(m >= n) Write a program to print the sum of the series for 1 + 2 + 3 + …. n [formula: Sn=(n(n+1))/2] n + (n+1) + (n+2 ) + (n+3) …. m 1 + 3 + 5 + .… n [formula: Sn=((n+1)/2)2] n + (n+2) + (n+4) + (n+6) … m (m is odd ) 12+ 22 + 32 + … n2 [formula: Sn=(n(n+1)(2n+1)) / 6] n2 + (n+1)2 + (n+2)2 + (n+3)2 …. m2 13 + 23 + 33 + … n3 [formula: Sn=(n(n+1)/2)2] n3 + (n+1)3 + (n+2)3 + (n+3)3 …. m3 14. Write a program to accept length of Square (could be decimals) and print a. Area of the Square b. Diagonal c. Perimeter. 15. Write a program to accept circumference of a circle and print a. Area of the circle b. Diameter of the circle Mani Sridharan – bdmsts@gmail.com
  • 22. USER DEFINED FUNCTIONS This chapter introduces the concept of creating our own functions in „C‟. A user defined function should be declared and then it has to be defined. DECLARATION: Declaration is to indicate the name of the function, arguments taken by the function and the type of value returned by the function. The template for declaring a function is <Return Type> <Function name> ( <arguments>) ; Examples : a. int Sum (int , int); Here Sum is the name of the function that returns an int and takes two int as arguments. b. float reminder(long, int); „reminder‟ is the name of the function that returns a float and takes a long and int as parameter. c. void display(int,char[]); „display‟ is the name of the function that returns nothing(void) and takes a int and character array as arguments. d. void Header(void); „Header‟ is the name of the function that returns nothing(void) and takes nothing. e. void setX(int *x); „setX‟ is the name of the function that returns nothing(void) and takes a pointer to an integer. Pointers will be discussed later in this material. DEFINING : While defining the function we actually specify what the function has to do when it is invoked. return statement is used for returning the value from the function. Examples:(the code for functions declared earlier are given below:) a. int sum(number1,number2) int number1,number2; { return (number1 + number2); } b. float reminder(divident,divisor) long divident; int divisor; { float remind; remind=(divisor>0)?(divident/divisor):-1; return remind; } c. void display(empcode,empname) Mani Sridharan – bdmsts@gmail.com
  • 23. int empcode; char empname[]; { printf(“Employee Code :- %d n”,empcode); printf(“Employee Name:- %s n”,empname); return; } d. void Header(void) { printf(“ntttSoftTech Consultants”); printf(“ntttC Programmers”); printf(“nnn”); return; } nine.c To illustrate the usage of user defined functions. Write a program to accept 2 numbers and print the minimum of two numbers. #include <stdio.h> int minimum(int,int); /* Declaring the function */ int main(void) { int no1, no2; int minvalue; printf(“Enter Number 1: ”); scanf(“%d”,&no1);fflush(stdin); printf(“Enter Number 2: ”); scanf(“%d”,&no2);fflush(stdin); minvalue=minimum(no1,no2); /* Invoking the function */ printf(“The minimum value is %dn”,minvalue); } int minimum(number1, number2) /* Defining the function */ int number1,number2; { if (number1 < number2) return number1; return number2; } Note: Some of the compilers doesn‟t support the argument declarations while declaring the function. In that case, we can declare the function with out arguments by having dummy ( ) followed by „;‟. By default „C‟ compiler automatically declares the functions which returns an integer and hence they could be defined without declaring. Mani Sridharan – bdmsts@gmail.com
  • 24. Exercise: 1. Write a user defined function to return absolute value of a number. 2. Write a user defined function Greater that takes four numbers as arguments and returns the maximum of the four. 3. Write a user defined function CheckUpper to take a character as an argument and returns 1 if it is in upper case else zero. 4. Write a user defined function CheckDigit to take a character as an argument and returns 1 if it is a digit else zero. 5. Write a user defined function CheckLower to take a character as an argument and returns 1 if it is in lower case else zero. 6. Write a program to check whether the entered character is an alphabet, or digit or a special symbol. The program should continue functioning till '0' is entered. Use the functions that you have created earlier. 7. Write a user defined function SI to calculate simple interest. The function should take principal, rate of interest and no. of years and returns the SI value. 8. Write a user defined function check_right_angled_triangle. It should take the length of opposite side, adjacent side and hypotenuse and returns 0 if it matches the sides of a right angled triangle or 1 if not. 9. Write a user defined function Area_of_a_triangle. It should take length of 3 sides as parameters and returns the area of the triangle. 10. Write a user defined function FACTORIAL that returns the factorial of the number passed as parameter. 11. Write a user defined function GCD (Greatest Common Divisor) that takes 3 numbers as arguments and returns the GCD of the three. 12. Write a user defined function LCM (Least Common Divisor) that takes 2 numbers as arguments and returns the LCM of the two. 13. Write a user defined function that prints the multiplication table. It should take the table no. and multiplication value till a no. Example: multable(16,8) Output Should be from 16 x 1 = 16 to 16 x 8 = 128 13. Write a user defined function that returns Square root of a number.(don‟t use sqrt library function). 14. Write a user defined function that returns Cube root of a number. 15. Implement user defined functions for SIN, COS and TAN. Mani Sridharan – bdmsts@gmail.com
  • 25. ARRAYS: Arrays are rectangular arrangement of elements of the same type. Each and every element in the array is referred using the subscript of the element. Syntax for creating a single dimensional array: <Storage identifier> <variable name>[<no_of_elements>]; Example: char alphabet[26]; Creates a single dimensional character array under the variable name alphabet to hold 26 characters. int marks[5]; Creates a single dimensional integer array marks to hold 5 subject marks. float rate[12]; Creates a single dimensional floating point array to hold rate of 12 items. Referring elements in an array: Elements in the array are referred using the subscript, the subscript starts from zero. Thus if we want to refer to element no. 5, the subscript should be 4. If we want to refer to first item, the subscript should be zero. Let us assign alphabet array with all alphabets. Method 1: We can initialize each and every array element by referring to subscript char alphabet[26]; alphabet[0]=„a‟; alphabet[1]=„b‟; alphabet[2]=„c‟; : : alphabet[25]=„z‟; Method 2: The better way of doing could be. char alphabet[26]; int i; for(i=0;i<26;alphabet[i]=„a‟+i, i++); Mani Sridharan – bdmsts@gmail.com
  • 26. Accepting data on to array. Let us define array “name” to store the name of an individual(max of 30 characters). Let us see how to accept the name in different ways. If we want to store 30 characters we need to define an array of 31 characters, simply because „0‟ is used as a string terminator in most of the „C‟ functions. The String Terminator „0‟ is defined as NULL in stdio.h include file. In our code, we can check for String Terminator by comparing with „0‟ or with NULL. Method 1: char name[31]; int i=0; printf(“Name : “); for(;i<30;i++) { name[i]=getchar(); fflush(stdin); } name[30]=„0‟; /*Placing the terminator to specify the end of the string. printf looks for string terminator when %s is specified as argument. The other way of doing the same is name[30]=NULL*/ printf(“Your name is %sn”,name); Method 2: char name[31]; printf(“Enter Name(max 30 chars) : “); gets(name); /* we can use scanf(“%s”,name); also*/ fflush(stdin); /*gets & scanf are library functions of „C‟ */ /*gets & scanf takes care of putting „0‟ at the end of the stream */ /*fflush is a library function used for clearing the buffer associated with it */ printf(“Your name is %s n”, name); Note: In „C‟ single quotes and double quotes have different meaning. Single quotes is used for enclosing one single character where as double quotes is used for enclosing an array of characters known as string. For example in puts if enclose the argument in single quotes, it generate a compilation error as it requires stream of characters as input. In general, single quotes refers to the value to be stored and the double quotes returns the address of the location of the data in memory. The subscript is again used for referring to elements in Integer and Float arrays. The format “%d” is used for integer and “%f” is used for float while accepting and printing data using “scanf” and “printf” functions. “gets” function cannot be used for accepting a float or an integer. It can be used only for accepting a stream of characters(strings). ARRAY Referencing in MEMORY The memory address of an array element is found by (Starting address + (subscript * sizeof(data type)); Mani Sridharan – bdmsts@gmail.com
  • 27. sizeof is a reserved word in „C‟ used for calculating the total bytes associated with that datatype. Example 1: Let us define an array by name Alphabet to hold 26 characters. char Alphabet[26]; let us assume Alphabet is memory location 300. Alphabet[0] will be location 300. Alphabet[1] will be location 301. Alphabet[2] will be location 302. Hence location of Alphabet[n]=(Starting address + (n * sizeof(char)); Alphabet[5]=(300 + (5*1)) ==> 305. Example 2: Let us define an array by name Rate to hold 5 characters. int Rate[5]; let us assume Rate is pointing to memory location 400. Rate[0] will be location 400 - 403. Rate[1] will be location 404 - 407. Hence location of Rate[n]=(Starting address + (n * sizeof(int)); Rate[3]=(400 + (3*4)) ==> 412. EXERCISE For Exercises 2 to 9, you need incorporate by writing your own functions. 1. Identify the output of the following programming. #include <stdio.h> main() { char alphabet[26]; /* alphabet is location 125 in memory */ int marks[5]; /* marks is location 200 in memory */ alphabet[6]=„f‟; alphabet[5]=alphabet[6]-1; marks[0]=100; marks[2]=marks[0]-24; marks[4]=marks[0]-marks[2]+20; marks[3]=36; marks[1]=marks[0]%(marks[2]-marks[3]) alphabet[0]=alphabet[1]=alphabet[7]=„0‟; printf(“%d”,alphabet[5]); printf(“%d”,&alphabet); printf(“%d”,&alphabet[0]); printf(“%d”,&alphabet[21]); printf(“%d%d%d%d%d”,marks[0],marks[1],marks[2],marks[3],marks[4]) printf(“%d %d”, &marks[3],&marks[1]); } Mani Sridharan – bdmsts@gmail.com
  • 28. 2. Write a program to accept 30 characters and print the no of vowels, consonants, digits & special characters in the group. 3. Write a program to accept 30 characters and print the length of the string. 4. Write a program to accept 30 characters and convert all uppercase to lowercase and print. 5. Write a program to accept 30 characters and convert all lowercase to uppercase and print. 6. Write a program to accept a string of 50 characters long and check whether it is palindrome or not. 7. Write a program to accept two strings (assume size) and check whether they are same or not. 8. Write a program to accept two strings(assume size), print both the strings and append the string string to the first and print both. 9. Implement substring, ltrim, rtrim, left, right functions. 10. Write user defined functions ASortC, ASortI, ASortF to sort Character, Integer & Float arrays. 11. Write user defined functions ACopyI, AFloatF to copy contents of Integer to Integer, Float to Float arrays. 12. Write a program to accept 25 integers on to array. While Storing store it in ascending order. 13. Write a program to accept details of 5 items. Details are itemcode integer, rate integer, quantity as float type variable. Incorporate the following options. a. To print the details of all items. b. To print the details of an item specified by the user. c. To print the details of all items whose rate < accepted rate. 14. Implement a user defined function REVERSE, that takes a character array ( assume size) and reverses and writes the string to the second character array passed as parameters. 15. Implement a user defined function to encrypt and decrypt a string. (one possible logic is to add 40 to each character while encrypting and subtracting 40 while decrypting). Mani Sridharan – bdmsts@gmail.com
  • 29. Syntax for creating a Two dimensional array: <Storage identifier> <variable name>[<no_of_rows>][<no_of_columns>]; Example: char names[5][31]; Creates a two dimensional character array under the variable name “names” to hold 5 names each 30 characters long assuming 1 byte for „0‟(String Terminator). int matrix [3][3]; Creates a two dimensional integer array “matrix” to hold integers for a 3x3 matrix. Referring elements in an two dimensional array: Elements in the two dimensional array are referred using the row subscript and column subscript, the subscript starts from zero. Thus if we want to refer to third row, second element, it should be (2,1). Let us initialize matrix array with unit matrix. We can initialize each and every array element by referring to row, column subscript int matrix[3][3]; int i=0; int j=0; for(;i<3;i++) for ( ; j<3;j++) matrix[i][j]=0; matrix[0][0]=matrix[1][1]=matrix[2][2]=1; Accepting and Accessing data on a two dimensional array. Let us define array matrix to store a 3x3 matrix. int matrix[3][3]; int i,j; /* Accepting Details */ for(i=0;i< 3; i++) { for(j=0; j < 3; j++) { printf(“Enter value for row %02d, column %02d ”, i+1,j+1); scanf(“%d”,&matrix[i][j]); fflush(stdin); } } /*Accessing Details & Printing */ for(i=0;i<3;i++) { for(j=0;j<3;j++) printf(“%dt”,matrix[i][j]); printf(“n”); } Note: Similar method can be used for Accepting and Accessing details on to a character two dimensional array. The library functions scanf and gets can be used for accepting details. Mani Sridharan – bdmsts@gmail.com
  • 30. EXERCISE: 1.Assume two 3x3 matrices A& B. Write programs for a. Addition of 3x3 matrices b. Subtraction of 3x3 matrices. c. Multiplication of 3x3 matrices. d. Inverse of a 3x3 matrix. 2. “The PLAYGROUP NURSERY” is one of the famous nursery in Bombay. They teach the kids with the help of PLAYWAY method. The nursery current consists of 25 kids. They wanted to store the following details in order to prepare a grade sheet for the kids. They have approached you to automate their process. The task includes: 1. Accepting and storing details for 25 students. Details include, their name, age, ranking out of 10 in playing, grasping, listening, hearing, reading & writing. 2. Prepare a grade sheet and print the appropriate grade. Valid grades are Outstanding, Excellent, Good, Average & Poor. Total ranking Grade out of 10 9.0 and Above Outstanding 8.0 - 8.9 Excellent 7.0 - 7.9 Good 5.0 - 6.9 Average less than 5.0 Poor. You need to prepare the report in the following format. THE PLAYGROUP NURSERY Graded Mark Sheet S.No. Name Age Total Ranking Grade 1. Ramesh 3 8.3 Excellent 2. Rajesh 4 9.1 Outstanding .. ........... .... .... ..... Mani Sridharan – bdmsts@gmail.com
  • 31. STRING HANDLING FUNCTIONS IN STANDARD „C‟ LIBRARY All the string handling library functions are prototyped in „string.h‟. So whenever we use string handling functions the file „string.h‟ should be included along with „stdio.h‟ in our program. This can be included to our program with the help of „#include‟ preprocessor statement and it is shown below. #include <stdio.h> #include <string.h> Appending One String to Another: a. char *strcat(char *s1, const char *s2); - Appends a copy of string s2 to the end of string s1. It automatically terminates s1 with NULL(„0‟) - String Terminator. b. char *strncat(char *s1, const char *s2, size_t n); - Appends a maximum of n characters. It copies fewer if s2 is shorter than n characters. Returns a pointer to the null-terminated result (the value of s1). Copying One String to Another: a. char *strcpy(char *s1, const char *s2); - Copies the s2 on to s1 by overwriting the contents of s1. Copying stops when it encounters a NULL byte. Returns a pointer to the null-terminated result (the value of s1). b. char *strncpy(char *s1, const char *s2,size_t n); - Copies a maximum of n characters. It copies fewer if s2 is shorter than n characters. Copying stops when it encounters a NULL byte. Returns a pointer to the null-terminated result (the value of s1). c. char *strdup(const char *s); - creates a duplicate of s and returns the memory location of the duplicate copy. Comparing Strings: a. int strcmp(const char *s1, const char *s2);- Compares its arguments and returns an integer less than, equal to, or greater than zero, depending on whether s1 is lexicographically less than, equal to, or greater than s2. b. int strncmp(const char *s1, const char *s2, size_t n);- makes the comparison like strcmp but examines a maximum of n characters (n less than or equal to zero yields equality). Length of a String: a. size_t strlen(const char *s); -Returns the number of characters in s, not including the terminating null byte. Mani Sridharan – bdmsts@gmail.com
  • 32. POINTERS Pointers are variables in „C‟ whose contents are addresses. Pointers are the backbone of „C‟. They are used to refer to a particular memory address to change its contents. Any Pointer variable occupies 4 bytes of memory. To point to character type memory address, character pointers are used. For integer type memory address, integer pointers are used. In specific, if the memory location of a storage type is to be accessed using a pointer, the pointer needs to be defined of that type. Exception to this rule is “void” pointers, they can point to any storage types memory location. In the case of a Pointer variable, we don‟t know the exact size of data it is pointing to.  Pointers can be used for pointing to scalar and vector types.  Pointer variable refers to memory address it is containing i.e. the content of a pointer variable is an address.  „*‟Pointer variable refers to the content in the memory address it is containing.  „&‟Variable refers to the address of the variable . DECLARING A POINTER: char *ptr; /* Declaring a Character Pointer */ int *ijk; /* Declaring a Integer Pointer */ float *x; /* Declaring a Float Pointer */ void *v; /* Declaring a Void Pointer */ POINTER MANIPULATIONS: Let us define two variables „a‟ & „ptr‟. „ptr‟ is a pointer type variable. Assume „a‟ is memory location 300 and „ptr‟ is memory location 400. char a,*ptr; /* Declaring Variables */ a=„x‟; /* Assigning the value „x‟ to variable „a‟ */ /* At memory location 300, „x‟ is written as Variable „a‟ is address 300 */ ptr=&a; /* Assigning the address of variable „a‟ to „ptr‟ */ /* At memory location 400, the address (300) of „a‟ is written */ printf(“%p”,ptr); /* Printing the content of ptr --- > 300 */ printf(“%c”,*ptr); /* Printing the content of content of ptr. ==> content of content of 400 ==> content of 300 ==> „x‟ */ (*ptr)++; /*Incrementing the content of content of ptr by 1 ==> incrementing the content of content of 400 by 1 ==> incrementing the content of 300 by 1 ==> incrementing the value „x‟ by 1 ==> at 300, the value would be „y‟ */ Mani Sridharan – bdmsts@gmail.com
  • 33. printf(“%c”,*ptr); /* would be printing „y‟ */ printf(“%c”,a); /* variable „a‟ refers to 300 and hence prints „y‟ */ Note: In the above example, „ptr‟ refers to the content of the variable „ptr‟ which is the memory address of variable „a‟ and „*ptr‟ refers to the content of content of ptr which is the value in memory location 300 and it is „x‟ initially then incremented to „y‟. EXERCISE: Assume the character variable „myvar‟ is memory address 500 and character type pointer variable „myptr‟ is memory address 625. With reference to this explain each & every line in the code and errors (if any). myvar=„p‟; printf(“%p”,&myvar); printf(“%c”,myvar); printf(“%p”,&myptr); printf(“%c”,myptr); printf(“%c”,*myvar); printf(“%c”,*myptr); myptr=myvar; printf(“%p”,&myvar); printf(“%c”,myvar); printf(“%p”,&myptr); printf(“%c”,myptr); printf(“%c”,*myvar); printf(“%c”,*myptr); myptr=&myvar; printf(“%p”,&myvar); printf(“%c”,myvar); printf(“%p”,&myptr); printf(“%c”,myptr); printf(“%c”,*myvar); printf(“%c”,*myptr); (*myptr)++; printf(“%p”,&myvar); printf(“%c”,myvar); printf(“%p”,&myptr); printf(“%c”,myptr); printf(“%c”,*myvar); printf(“%c”,*myptr); myptr++; printf(“%p”,&myvar); printf(“%c”,myvar); printf(“%p”,&myptr); printf(“%c”,myptr); printf(“%c”,*myvar); printf(“%c”,*myptr); One might raise the question like, if pointers contents are memory address, why we need different kind of pointers ? Mani Sridharan – bdmsts@gmail.com
  • 34. To answer this question, let us get back to arrays. Let us take up our same old example character array „Alphabet‟ and integer array „Rate‟. Assume Alphabet is memory location 400 and Rate is memory location 500. char Alphabet[26]; /* Alphabet is location 400 */ int Rate[5]; /* Rate is location 500 */ &Alphabet[0] is location 400, &Alphabet[1] is location 401 and &Alphabet[subscript]=(starting address+(subscript * sizeof(storage type)) Here &Alphabet[subscript]=(400+(subscript * 1)). (Since sizeof(char) is 1). Hence &Alphabet[1]=(400+(1*1)) = 401. Similarly, &Rate[0] is location 500, &Rate[1] is location 504, &Rate[subscript] = (starting address +(subscript * sizeof(storage type)) Here &Rate[subscript] = ( 500 +(subscript * 4)). (Since sizeof(int) is 4). Hence &Rate[1]=(500+(1*4)) = 504. Let us have two pointer variables „MyCharPtr‟ and „MyIntPtr‟. „MyCharPtr‟ is a char type pointer varible and „MyIntPtr‟ is a int type pointer variable. Let us make this pointers point to our earlier variables Alphabet & Rate. With the help of this we shall identify the need of different types of pointer variables. char Alphabet[26]; /* Alphabet is location 400 */ int Rate[5]; /* Rate is location 500 */ char *MyCharPtr; /* Character Pointer */ int *MyIntPtr; /* Integer Pointer */ MyCharPtr = &Alphabet; /* Storing 400 in MyCharPtr */ MyIntPtr = &Rate; /* Storing 500 in MyIntPtr */ Now the Pointer variable MyCharPtr is pointing to the address of Alphabet[0]. We want MyCharPtr to point to the address of Alphabet[1]. As we know the sizeof (char) is one, we are incrementing the content of MyCharPtr by 1 hence it will contain the memory address as 401 and that is &Alphabet[1]. MyCharPtr++; /*Increases the content of MyCharPtr by 1 */ Similarly, we want MyIntPtr to point to the address of Rate[1]. As we know the sizeof(int), we will increment the content of MyIntPtr by sizeof(int) assuming “4”. MyIntPtr=MyIntPtr + sizeof(int); To check whether it has increment correctly, let us print the new memory address stored in MyIntPtr. It should be 504. printf(“%p”,MyIntPtr); We would be wondered to see the content is printed as 516 refering to Rate[4] instead of Rate[1]. The reason is the scaling factor of int is „4‟ and hence when we say MyIntPtr + 4, it increments the content of MyIntPtr by 4 times 4 and hence containing the address of Rate[4]. In our script we should have increment MyIntPtr by 1 instead of 4 to point to Rate[1]. Mani Sridharan – bdmsts@gmail.com
  • 35. What we need to identify here is whenever we define a character pointer and any mathematical operation is carried with it will be interms of sizeof(char) (i.e 1). Incase of integer pointers, it will be in terms of sizeof(int) (i.e. assumed as 4). In Specific whenever we carry a mathematical operation with the pointers, the operation will be carried in terms of sizeof(storage type). Secondly, the way in which the char, int & float data stored in memory differs and hence we can‟t have integer type pointer pointing to char and char type pointer pointing to int as the scaling factor and the data conversion technique differs. Note: Pointer variable++ and „*‟Pointer variable ++ are not the same. Pointer variable++ increases the content of the pointer variable by the scaling factor and „*‟Pointer variable ++ increments the content of the content of Pointer variable by 1 in the case of single dimensional pointers. Scaling factor is value required for skipping that element to move to next element in the sequence. Example: Convert all UpperCase to LowerCase using Pointers. Method 1: Without User defined Function. #include <stdio.h> main() { char string[101]; char *ptr; printf(“String (max 100 chars) : “); gets(string); ptr=string; printf(“The Entered String is %s n”,ptr); for(ptr=string;(*ptr != „0‟); ptr++) { if ((*ptr) > „A‟ && (*ptr) < „Z‟)) (*ptr)=(*ptr) + 32; } printf(“The String in lowercase is %s”,string); /* We cannot use ptr to print because, ptr is moved to the address of „0‟. If we want to print using ptr, again assign the address of string to ptr and print */ } Method 2: With User defined Function. #include <stdio.h> void toLowerCase(); main() { char string[101]; printf(“String (max 100 chars) : “); gets(string); toLowerCase(string); Mani Sridharan – bdmsts@gmail.com
  • 36. printf(“The String in lowercase is %s”,string); } void toLowerCase(ptr) char *ptr; { for(ptr=string;(*ptr != „0‟); ptr++) { if ((*ptr) > „A‟ && (*ptr) < „Z‟)) (*ptr)=(*ptr) + 32; } } Note: Method 2 has great advantage as method 1 because, the size of the array is not taken into consideration in Method 2 and it is modular. EXERCISE 1. Try the exercise 2 to 9 given for arrays using pointers.(refer to earlier example (Method 2) for implementation). 2. Implement a user defined function SearchReplace which takes the Main String, Search String & Replace String and replaces all occurrences of Search String in MainString with Replace String. MEMORY HANDLING: Any variable (non Pointer Variables) defined in the program by default assumes maximum size of the data it is containing. For example, if we define int j, we know j is going to occupy four bytes of memory. If say, char name[31], it is very well known that name is going to occupy 31 bytes of memory. Since these variables assume a define size of data they are going to store, they are created in STACK. The Executable file contains the virtual memory layout of these variables in memory as the compiler knows the size & type of these variables at the time of Compilation. All the non-pointer variables are initialized variables. Pointers are the technique used in „C‟ to point to a memory location and to manipulate the data in it. If we take applications like word processor or spreadsheet the size of the data and the data it is holding is known only at the run-time. Hence the memory allocation to be done dynamically at the run-time. Dynamically Memory is allocated from HEAP. HEAP is the global memory and doesn‟t form a part of current running process. Using Pointers and Standard „C‟ library functions, we allocate memory from HEAP for processing. HEAP memory area can be pointed only by Pointers. Pointer variables are not initialised variables. Pointers can refer to STACK and HEAP memory areas. DYNAMIC ALLOCATION OF MEMORY FROM HEAP void *malloc(int); The function used for allocating memory dynamically from HEAP. „malloc‟ takes the no_of_bytes required from Heap as an argument and allocates that many bytes from Heap by returning a valid memory address else returns NULL(or Zero). Since malloc returns a void pointer it can be type-casted to any storage type by enclosing the storage type pointer in brackets. Mani Sridharan – bdmsts@gmail.com
  • 37. Examples: 1. char *str; str=(char *)malloc(16); /* Since malloc returns a void pointer and str is a character pointer, we are type-casting the void address returned by malloc to char pointer by enclosing (char *) in brackets. We are taking 16 bytes from heap to store 15 characters and „0‟(String Terminator) ---> look the example */ 2. int *iptr; iptr=(iptr *)malloc(sizeof(int)); /* Since malloc returns a void pointer and iptr is a integer pointer, we are type-casting the void address returned by malloc to integer pointer by enclosing (int *) in brackets. Since any int requires four bytes of memory, we are passing the sizeof(int) as arguement. ---> look the example */ RE-ALLOCATING MEMORY ASSIGNED BY MALLOC. void *realloc(void *ptr, size_t size); It is used for changing the size of memory allocated by earlier malloc function and returns a pointer to the block(possibly new) where it is allocated. If ptr is a NULL pointer, realloc() behaves like malloc()for the specified size. If size is zero and ptr is not a NULL pointer, the object it points to is freed and NULL is returned. Example: 1. char *str; str=(char *)malloc(16); /* Since malloc returns a void pointer and str is a character pointer, we are type-casting the void address returned by malloc to char pointer by enclosing (char *) in brackets. We are taking 16 bytes from heap to store 15 characters and „0‟(String Terminator) ---> look the example */ str=(char *)realloc(str,10); /* Re-initialising str to point to a location for storing 10 bytes instead of 16 */ RELEASING MEMORY ASSIGNED BY MALLOC. void free(void *ptr); It is used for releasing the memory earlier allocated by malloc function. Example: 1. char *str; str=(char *)malloc(16); free(str); /* Releasing memory thus allotted by malloc */ Mani Sridharan – bdmsts@gmail.com
  • 38. GOOD PROGRAMING PRACTICES: Whenever we allocate memory from HEAP using „malloc‟ function, check whether it returns NULL or not. If it returns a NULL that means it has failed the operation due to memory insufficiency. You need to handle these errors. It is a good programming practice to release the memory used by a pointer using „free‟ function as soon as the operation with the variable is complete. This increases the HEAP memory area size and help other processes to utilize it. EXERCISE: 1. Write a program to accept a number, allocate memory to hold that many no. of characters. Accept data from the user and print the details. 2. Allow the user to enter a text of unlimited size and print it in reverse order. MULTI DIMENSIONAL POINTERS: Like Multi-dimensional arrays we can have multi-dimensional pointers. This is an example of two dimensional integer pointer to hold details of an 4x4 matrix. In the example, explanations are given in normal comment entries and other method of doing the same operation in bold comment entries. #include <stdio.h> main() { int **p; /*declaring a two dimensional integer pointer */ int i,j; p=(int **)malloc(4*sizeof(int)); /*allocating memory to hold four rows */ /*allocating 16 bytes for 4 integers (4x4)*/ /*assume malloc returns 400, hence „p‟ points from 400 - 415, and that could be divided as 400-403 for p[0], 404-407 for p[1], 408-411 for p[2], 412-415 for p[3] */ if(p==NULL) { printf(“Memory Not Available... Aborting “); exit(-1); } /*p[0] = p [points to 400-403], p[1]= (p+1) [points to 404 - 407, simply because, scaling factor for a integer is 4, hence „p+1‟ refers to next location of pointer „p‟ (i.e. 404). p[2]=(p+2) [points to 408 - 411] p[3]=(p+3) [points to 412-415] */ /* Since the p[0] - p[4] is pointing to junk, we need to initialize with a valid memory area address. Again allocating 16 bytes for each subscript to ensure proper storage of 4 bytes in each case. */ /* Let us assume p[0][0] is pointing to 500 - 515 Mani Sridharan – bdmsts@gmail.com
  • 39. p[1][0] is pointing to 600 - 615 p[2][0] is pointing to 700 - 715 p[3][0] is pointing to 800 - 815 */ *p=(int *)malloc(4*sizeof(int)); /* (p[0])=(int *)malloc(16); */ if((*p)==NULL) { printf(“Memory Not Available for p[0] ... Aborting “); free(p); exit(-1); } *(p+1)=(int *)malloc(4*sizeof(int)); /* (p[1])=(int *)malloc(16); */ if((*(p+1))==NULL) { printf(“Memory Not Available for p[1] ... Aborting “); free(p[0]); /* freeing memory in descending order */ free(p); exit(-1); } *(p+2)=(int *)malloc(4*sizeof(int)); /* (p[2])=(int *)malloc(16); */ if((*(p+2))==NULL) { printf(“Memory Not Available for p[2] ... Aborting “); free(p[1]); free(p[0]); free(p); exit(-1); } *(p+3)=(int *)malloc(4*sizeof(int)); /* (p[3])=(int *)malloc(16);*/ if((*(p+3))==NULL) { printf(“Memory Not Available for p[3] ... Aborting “); free(p[2]); free(p[1]); free(p[0]); free(p); exit(-1); } **p=100; /*p[0][0]=100*/ /* we are initializing **p with 100 ==> initializing content of content of 400 ==> initializing content of 500 - 503 with 100 */ /* similarly compute for others */ *((*p)+1)=200; /* p[0][1]=200; */ *((*p)+2)=300; /* p[0][2]=300; */ *((*p)+3)=400; /* p[0][3]=400; */ **(p+1)=1000; /* p[1][0]=1000; */ *((*(p+1))+1)=2000; /* p[1][1]=2000; */ *((*(p+1))+2)=3000; /* p[1][2]=3000; */ *((*(p+1))+3)=4000; /* p[1][3]=4000; */ **(p+2)=-100; /* p[2][0]=-100; */ *((*(p+2))+1)=-200; /* p[2][1] =-200; */ Mani Sridharan – bdmsts@gmail.com
  • 40. *((*(p+2))+2)=-300; /* p[2][2] =-300; */ *((*(p+2))+3)=-400; /* p[2][3]=-400; */ **(p+3)=-1000; /* p[3][0]=-1000; */ *((*(p+3))+1)=-2000; /* p[3][1]=-2000; */ *((*(p+3))+2)=-3000; /* p[3][2]=-3000; */ *((*(p+3))+3)=-4000; /* p[3][3]=-4000; */ /* Printing the values stored in the two dimensional pointer */ for(i=0;i<4;i++) { for(j=0;j<4;j++) { printf("%5dt",*((*(p+i))+j)); } printf("n"); } for(i=3;i>-1;free(p[i]),i--); free(p); } EXERCISE: 1. Accept two integers M & N from users and create two matrix with „M‟ as number of rows and „N‟ as number of columns. Do operations like addition, subtraction and multiplication with it. Note the matrix can contain decimals & negative. IMPLEMENTING USER DEFINED DATA-TYPES: a. STRUCTURES: Structures are widely used for creating data-structures in „C‟. We would be interested in creating our own data-types for storing details rather than the system defined in most of the cases. To illustrate this, let us create a data type „Employee‟ to store employee details in an organization. Some of the Employee details include „Employee Code‟, „Employee Name‟, „Grade‟, „Date of Birth‟, „Date of Joining‟, „Bank A/c No.‟, „Blood Group‟, „Designation‟ and „Department‟. It is better to bring all the logical attributes of employee in to a single physical attribute for clarity in programming. Structures are used in implementing the same. Structures can contain structures as data elements. Here DOJ & DOB is a date type made of day, month & year. Structures are created using struct keyword. Let us create the new user defined types Employee & Date. struct Date { short int dd; short int mm; int yy; }; struct Employee { int ECode; char Name[26]; Mani Sridharan – bdmsts@gmail.com
  • 41. char Grade; struct Date DOB; struct Date DOJ; int AccountNo; char BloodGroup[3]; int DesigCode; int DeptCode; }; Now we have created a user defined type by name „Employee‟. Whenever an instance of „Employee‟ is created, all the attributes will gain scope to store details. „Employee‟ is a data-type like „char‟. Hence we need to create an instance for storing details. To create an instance of structure, the syntax used is struct <Struct name> <Variable Name>; In Employee Structure we have created two instances of Struct Date to contain DOB and DOJ. Let us look at the example for creating an instance. struct Employee emp1; struct Employee *eptr; Now we have created an instance of „Employee‟ as „emp1‟. Since „emp1‟ is not a pointer, the memory is automatically allocated from STACK at time of compiling. In the second case „eptr‟ is a pointer and hence memory has to be allocated from HEAP to store details. The sizeof the variable emp1 is the total sum of all the attributes defined in the structure Employee. Here it is 54 bytes long. Let us initialize the details of „Johnson‟ in emp1. Each and every attribute is referenced by putting instance‟.‟attribute in case of STATIC variables and instance->attribute in case of POINTER variables. Initializing Static Variable: emp1.Ecode=1; strcpy(emp1.Name,”Johnson”); emp1.Grade=„A‟; emp1.DOB.dd=12; emp1.DOB.mm=7; emp1.DOB.yy=1965; emp1.DOJ.dd=14061987; emp1.DOJ.mm=6; emp1.DOJ.yy=1987; emp1.AccountNo=12345; strcpy(emp1.BloodGroup,”O+”); emp1.DesigCode=1; emp1.DeptCode=5; Initializing Pointer Variable: eptr=(struct Employee *)malloc(sizeof(struct Employee)); /* In sizeof reserve word, eptr is not given because, it is a pointer variable and it is four bytes in size. We need to allocate 54 bytes hence we take the sizeof structure into consideration */ eptr->Ecode=1; strcpy(eptr->Name,”Johnson”); eptr->Grade=„A‟; Mani Sridharan – bdmsts@gmail.com
  • 42. eptr->DOB.dd=12; eptr->DOB.mm=7; eptr->DOB.yy=1965; eptr->DOJ.dd=14061987; eptr->DOJ.mm=6; eptr->DOJ.yy=1987; eptr->AccountNo=12345; strcpy(eptr->BloodGroup,”O+”); eptr->DesigCode=1; eptr->DeptCode=5; Ten.c:- To illustrate the usage of structures. /* This is a sample program to accept the details of 25 Employees using structures and to print them accordingly. */ #include <stdio.h> #define CLS system(“tput clear”) /* Used for substituting CLS with system(“tput clear”) in the program at time of pre-processing stage during compilation. All CLS will be replaced with system(“tput clear”) in code */ /* system() is a function used for escaping & executing commands in shell */ #define TRUE 1 #define NO_OF_ELE 25 struct Employee { int Code; char Name[26]; float Basic; }; struct Employee myemp[NO_OF_ELE]; /* Global variable outside all functions */ void addopt(void); void printopt(void);void printoptP(void); main() { menu(); exit(0); } int menu(void) { char choice; do { CLS; /*will be replaced with system(“tput clear”) at pre-processing stage */ printf(“nnnnttttMAIN MENUnn”); printf(“nnttt A. Add details n”); printf(“nttt P. Print details using MyEmpn”); Mani Sridharan – bdmsts@gmail.com
  • 43. printf(“nttt O. Print details using Pointer n”); printf(“nttt E. Exit nn”); printf(“nttt Choice : “); choice=getchar();fflush(stdin); switch(choice) { case „A‟: case „a‟ : addopt();break; case „P‟ : case „p‟ : printopt();break; case „O‟: case „o‟ : printoptP();break; case „E‟ : case „e‟ : return; } }while(TRUE); } void addopt(void) { int i=0; for(;i<NO_OF_ELE;i++) { CLS; printf(“nnnttttAccepting Details for Employee:-%02d”,i+1); printf(“nntttt Code : “); scanf(“%d”,&myemp[i].Code);fflush(stdin); printf(“nntttt Name : “); gets(myemp[i].Name); printf(“nntttt Basic : “); scanf(“%f”,&myemp[i].Basic); fflush(stdin); } } void printopt(void) { int i=0; for(;i<NO_OF_ELE;i++) { CLS; printf(“nnnttttPrinting Details for Employee:-%02d”,i+1); printf(“nntttt Code : %d“,myemp[i].Code); printf(“nntttt Name : %s“,myemp[i].Name); printf(“nntttt Basic : %f “,myemp[i].Basic); printf(“nntttPress [Enter] to Continue“); getchar();fflush(stdin); } Mani Sridharan – bdmsts@gmail.com
  • 44. } void printoptP(void) { int i=0; struct Employee *eptr; for(eptr=myemp;i<NO_OF_ELE; eptr++,i++) { CLS; printf(“nnnttttPrinting Details for Employee:-%02d”,i+1); printf(“nntttt Code : %d“,eptr->Code); printf(“nntttt Name : %s“,eptr->Name); printf(“nntttt Basic : %f “,eptr->Basic); printf(“nntttPress [Enter] to Continue“); getchar();fflush(stdin); } } EXERCISE: 1. Write a program to accept details of 50 students(maximum per class). There are four class-rooms. Details include Registration no, Rollno, name, DOB, marks in language 1, language 2, Maths, Science & Social. Implement the following options. (Take care of all possible validations). a. Details like name, dob is accepted on-line at the time of registration, Classroom is taken as a choice from the user and the Registration number is automatically generated for that class for the new student. b. Once the registration is complete an option for the sorting the details for each & every class to be provided. It has to generate the Roll Number for each & every student in the ascending order of Name in that class. c. An option to be provided for accepting marks for each & every student in each & every class. This option should display Roll number & Name to accept marks. d. An option to be provided for displaying the first 3 toppers of the school. e. Attendance list & Mark list to be generated from the system for each & every class. A candidate is eligible for passing only the score in all subjects > 50. f. Graded Mark list to be printed for those students who have passed the examination in each & every class. Total Marks Grade 450 and Above Outstanding 400 - 449 Excellent 300 - 399 Good 250- 299 Fair b. UNIONS:- Unions are used for collecting a set of data elements like structures. In Union all the data elements inside Union will share the same memory area. In otherwords the sizeof the Union is the sizeof the data- element that has the maximum size in the Union. Unions are creating using union keyword. Example: union Pay { Mani Sridharan – bdmsts@gmail.com
  • 45. float basic; short int Wages; }; In the above example, the size of the union Pay is 4 bytes because float is of maximum length. If the employee is Salaried Employee, the value is stored in Basic else stored in Wages. To create an instance of union, the syntax used is union <Union name> <Variable Name>; Example: a. union Pay amount; b. union Pay *value; Accessing Elements in an Union: Each and every attribute is referenced by putting instance‟.‟attribute in case of STATIC variables and instance->attribute in case of POINTER variables. Example: amount.Basic=4000; /* writing to commonly shared area */ value=(union Pay *)malloc(sizeof(union Pay)); /* Allotting memory for pointer variable */ value->Wages=25; c. TYPEDEF:- Typedef is reserve word used for adding an meaningful alias to existing data types. While writing large applications there could be possibility that two programmers defining a variable as different types in their code that might lead to loss of data and ambiguity in definition. To overcome this problem, typedef‟s are used. A popular example is to store currency. Some programmers might define currency as float and others as double and leads to confusion. In this case, it is better to create a type by name “MONEY” to define currency in all their programs. If “MONEY” is defined as float in all the programs, where the instance of MONEY is found it will be treated as float. It is also used for maintaining the code. If in future, if the size is to be increased, it enough to change the typedef of MONEY as double, since all the programs uses MONEY and reduces heavy manual effort in maintaining the code. Example: typedef float MONEY; /* MONEY is treated as float in programs */ typedef struct Employee EMPLOYEE; /* EMPLOYEE is treated as struct Employee in Programs */ Creating an Instance: MONEY basic; MONEY hra; MONEY inv_amt; EMPLOYEE emp,emp1,emp2; Note: Structures can contain unions, typedef & structures and pointers as data-members and the case is also true for unions. Whenever we have a pointer pointing to structure or union, make sure it pointing to Mani Sridharan – bdmsts@gmail.com
  • 46. valid memory address before accessing and it can be implementing by allocating memory or by pointing to an existing instance of that type. FILES Files in Unix Operating system are classified as Flat files, Directory files, Block devices, Character devices, FIFO‟s and Symbolic links. In our discussion, we shall have a look over Flat files and its types alone. FLAT FILES or NORMAL FILES These files are used for storing data on the secondary storage for repeated usage. Flat files can be further classified as text files & binary files. Text files contains the data in readable form and binary files in compressed form. All the standard „C‟ library functions used for file operations are declared in „stdio.h‟. File operations include opening a file, readingwriting contents. Creating or Opening a Text or Binary File: fopen(“filename”,”mode”) is the Standard „C‟ library function used for creating a new file or opening an existing file. It takes the filename and mode in which it has to be opened as arguments. It returns a pointer of type „FILE‟, a structure defined in „stdio.h‟. If fopen() fails, it returns NULL, #define variable in „stdio.h‟. The various modes and their operations are provided in the following tabular column: Mode Remarks Location of File Pointer “w” Create a new file or overwrite the file(if exists). Beginning of File “r” Open the file for reading. Beginning of File “a” Open the file for appending. End of the file “w+” Like „w‟ mode and allows updating. Beginning of File “r+” Like „r‟ mode and allows updating. Beginning of File “a+” Like „a‟ mode and allows updating. End of the file Examples: FILE *f1; FILE *f2, *f3; f1=fopen(“new.pc”,”w”); if( f1 == NULL) { printf(“Error opening New.pc in write mode n”); perror(“The Reason is “); /* Standard „C‟ library function to print the reason for failure */ exit(0); } f2=fopen(“old.xc”,”r+”); if( f2 == NULL) { printf(“Error opening old.xc in read-write mode n”); perror(“The Reason is “); /* Standard „C‟ library function to print the reason for failure */ exit(0); } Mani Sridharan – bdmsts@gmail.com