Basic Knowledge Of C language:

>C is programming language. Compiler is developed by Dennis Ritchie in 1972 on PDP-11 unix based system.

>C is high level language. is case sensitive language.
>Standards of C Compiler ---- C89, C99(lastest standard)

>in c89 32 keywords are available.
>in c99 32+5 keywords are available.

>C procedural language.

>Data types :

    *Primitiave data types:
        -char,int,float,double
    *Derived Data Types
          -structure,union,array,pointer

> Type modifiers: long,short,signed,unsigned   

> Identifier rules : 
           1.We can not add space,any special character       
           2. Alphabets,digits and _(underscore) allowed
           3. we can not start indefier with digit.


>function calling convention: _cdecl ,_pascal,_firstcall,_stdcall

>main is entry point function. main is user defined function Called by compiler with the help of system.

int var; //declaration and definition

int main();
int main(void);  //declaration of main
void main(void);

#include<stdio.h> //preprocessive directive
int main(void)
{
     printf("Hello C");
     return 0;   
}//definition of main

>preprocessor pre-process statements starting with #

>source code (.c) ---> preprocessor---> (.i)------> compiler --->.asm assembler will covert into---(.obj + lib .obj)--->linker----->.exe---->loaded by loader-->in main memory RAM
>formatted function            unformatted function
printf                   
scanf                                       getch,getchar,getche,fgetc
                                                                gets,puts


>escape sequence characters :

    \n    adds a new line
    \t    adds horizontal tab space
    \f    form feed rather a new page
    \b    moves cursor one character back
    \a    adds a beep (alert sound)
    \v    adds vertical tab
    \r    adds carraige return
    \\    prints only \
    \"
    \'

>Format specifiers:
    %d        decimal integer
    %c        character
    %f        float
    %x        hexadecimal
    %o        octal
    %s        string   
    %u        unsigned
    %lf        long float
    %%        to print actually %
   

>Program Constructs

    1. sequence
    2. decision control if else / switch
    3. loop / iteration ( while, do while,for)   


if(<expressio>)                    if(percentage>=40)
{                        {
  <true statement>                    printf("PASS");
  <true statement>                }
  <true statement>
    ......
}


if(<expressio>)                    if(percentage>=40)
{                        {
  <true statement>                    printf("PASS");
  <true statement>                }
  <true statement>                else
    ......                    {
}                            printf("FAIL");
else                        }   
{
  <false statement>   
  <false statement>
  <false statement>
  .....
}



if...else if

    if(<expression)
    {

    }
    else if(<expression>)
    {

    }
    else if(<expression>)
    {

    }
    else //optional but in sequence need to be at last
    {

    }



>Ternary operator/conditional operator

    <expression> ? <true statement>    : <false <statement> ;
   

var_char>=65 && var_char<=90 ? var_char+=32 :
    var_char>=97 && var_char<=122 ? var_char-=32 : var_char;


>enum : it is a collection of enumarated fields. where as every field represents integer constant.

    Advantages:
        1. improves code readability
        2. somehow saves memory

>if enum first field is not inisialised by default it receives value 0 and next fields receives the value i.e. step 1 value ahead of previous field


 switch(<expression>)   
 {
    case <int constant> :
                 <statements>
                          <......>       
                 break;   

    default: //optional case //else
 }

1. case is to be followed by integer constant
2. default is case is optional. And even it sequence can be anywhere.
3. sequence of case doe not matter.
4. break is necessary statement after each block of case. If not mentioned it excutes next case also till break is not encountered. Infact break statement takes execution control forcefully out of switch
5. duplicate case is not allowed


>Iteration: Calling block of statement contineously till expression results true.
To stop execution of loop we need to add some modification statement which will result loop expression to false state.

>Type of loops
    1. on entry check ---- while, for
    2. on exit check  ---- do ...while
       
while(<expression>) //on entry check
 {
   <block of statements executed repeteadly>
 
 }

>conventionally it is said that if no. of iterations are not fixed then use while loop.


>jump statements:
    break : we can use inside loop & switch case. It helps to move execution control forcefully out switch/loop. and stops next execution of iterations.
    continue : can be used only inside loop. if continue is encountered in loop execution control is given to next iteration forcefully and from current iteration it skips execution of all statements below continue.


do
{
   <statements>
   .....
}while(<expression>); //on exit check loop


1. its aleast one execution is sure.
2. on exit check loop
3. it is conventionally said that if no. of iterations are not fixed use do..while


>Function: Set of instructions gather together as subprogram to achieve certain functionality.
    Function may or may not return value
    Function may or may not take arguments
    There is no concept of nested function.
    we can return only one value from function.

>Types of functions
    1. User defined functions
    2. Library Functions(printf,scanf...)
   
   
 >Arguments can be given to function
    1. pass by value
    2. pass by address
   

>declaration :
    <return type> <function name> ([<arg type>],[<arg type>..]);

e.g.declaration of printf
    int printf(const char *,...);

definition
    <return type> <function name> ([<arg type><identfier>],[<arg type> <identfier>])
    {
       <statements>   
    }   


>call
    [location] = <nameoffunction>([<arg values>,<arg values..>]);
   


>storage classes:

        keword       life        scope     location memory    default
automatic   auto       block        block       stack         garbage 
register    register       block        block       cpu register         garbage
extern      extern         program      program     data section           0
static      static         program      block       data section           0 


Scope: to whom it is known. In other words Who can access.
Life: How long particular type variable memory will retain in memory.

1. auto - Each variable locally created by nature by default it is auto. Infact auto keyword prefix to data type is option.
2. Register - register variable is request is supplied with cpu registers if they are available. Else case the request is simply converted to auto type of variables. There is no gaurantee of success request as register. If successful will be faster in process else case coverting request into auto type make process more slower.
>We can not address registers.

3. extern is used to declare global resource.

4. static :
    1. static variables are to be intialised at the time of declaration
    2. static variables are used to retain value of each call of respective function in which they are defined to next call.
    3. static variables can not be initialised to variable value.
    4. static variables are assigned at the time of declaration but only on     first invocation of particular function.


>Recursion:
Calling function within its self definition is called as recursion.
If block of statements to be executed repeatedly but in LIFO format then we can make use of recursion where each called process state is persisted separately.
Recursion needs terminating condition else results in stack overflow.

It is one of algorithm.

Difference btwn loop & recursion
In loop if no terminating condition is handled results into infinite iterations
In recursion if no terminating condition is handled results into stack overflow state.

In loop no use of extra memory.
In case of recursion more consumption of memory


In loop all instructions are executed using top down approach where as in case of recursion the function which has been called at the last will complete its entire process first


In loop its less time consuming and in case recursion more time consumption.
   

    while(n!=0)  
       {
      if(n%2==0)
             pf(0)
      else
             pf(0)
   
            n/=2;
        }



    void bin_rec(int n)
    {
       if(n==0)   
          return ;   
     
          bin_rec(n/2);
       printf("%d",n%2);
    }

>Pointer: is a variable specially designed to store address of valid location.
Each pointer variable will receive its own memory separately. Pointer holds always address and addresses are always in unsigned int format. Depends on compiler unsigned int data type size pointer will receive memory for each variable.

    & operator --- gives address of valid location(memory which is in alive     state)


    * operator --- called as value at operator or dereferencing operator or     indirection operator. it is unary operator can be applied only on address.   

    We can have pointer at n indiredection levels.




00000000
00000001
01011110
01111101


Array: is a collection of similar type of elements.
    1. Memory is always is given in sequence.
    2. each element in array shares a common name
    3. each element can be uniquely identified with its subscript(index) value
    4. We can have n dimention of array. Where as the last dimention of array     is always compulsory at the time of declaration(no. of elements)
    5. If array members are initialised at the time declaration partially then     remaining all receives value 0 .
    6. Dimention of array can be skipped only when members are initialised at     the time of declaration. Where as such arrray size depends on no. of     elements assigned with.
    7. Array name always provides the base address i.e. first element's     address which helps to use array interchangiblilty with pointer
    8. When the prerequisite of no. of elements to be processed is known then         we can make use of array.
    9. Once memory resolved for array can not be shrinked or grown at runtime.
    10. Array always passed by address.
    11. Array bound is job of programmer.
    12. Array dimention has to be given with integer constant only
    13. Array subscript for first element is always starts with 0 and         obviously last element always receive SIZE-1

>Pointer Arithmatic:

    Possible:
        1. We can add or substract intger constant from pointer. Obviously         we can increment or decrement pointer.
               
        i.e. one operand is address and other operand is intger constant

        2. We can substract two pointers.
        i.e. both operands are addresses

    NOT Possible
        1. We can not add two pointers   
        i.e. both operands if are addresses
        2. Multilplication adn division of pointers in not possible.         Infact it meaningless.


void pointer : is a generic pointer designed to hold any type of address. We can not acceess value at such pointer directly or apply arithmatics on that. Bcoz such pointer is always unknown about its scale. And i.e reason we need to always typecast void * prior to its use.

    int n=80;
    void *vptr=&n;

    pf("%d",*vptr);//will be errorneous statement
       
    resolve with typecast
    pf("%d",*(int *)vptr);//will derefer 4 bytes


Character Array : is a collectoion of characters

String : is a collection of characters but with last character member always as null character.

Dynamic Memory Allocation : can be received with help functions like malloc,calloc,realloc. We always receive memory at tuntime from the heap section. If requested bytes of memory is available in heap section then address of first of request block will be returned else case it return NULL.

malloc allocated memory is by default assigned to garbage where as calloc requested memory is by default initialised to 0.

Where prequisite is not known we can request dynamic memory. Which can be shrinked or grown at runtime.

One malloc call request provides always the bytes block which will be in sequence in memory.

malloc does not aware of for what purpose memory is requested for. infact it returns void pointer (i.e. just unknown type address) We need t typecast to our requirement prior to its use.


Dangling pointer: is pointer keeps pointing to location which is already freed. Such memory can be reallocated to other request at runtime results in valid address and can give unpredictable value.


Memory Leakage: Suppose a variable which holds the address of runtime memory is released (goes out of scope) we loose resource to access dynamic memory. Which causes memory leakage. A programmer should always avoid leakages can results into heap is full.

void create_mem( int length)
{
    char *c;
    c =  (char *) malloc((sizeof(char)*length)+1);
}//here c goes out of scope on completion of function. Beacause of which we loose reference to access dynamic memory.


Preprocessor preprocess directives which starts with #
    #define        defined() #ndef #undef
    #include
    #pragma
    #debug
    #if
    #else
    #endif


#include<> / #include""
<> included file will be searched in include path of respetive editor
"" include file will be searched in current project folder first and then will be search even in include folder path of respective compiler


#define can be used to represent symbolic constant or macro. Macro which represents syntax taking arguments at the of use.

#define <symbol> <replaceble text>

#define SIZE 5
#define SQR(x)  x*x

In case of macro less memory consumption    where in function more memory consumption

macro is less time consuming as per as execution where as function genrates stack frame copies actual arg in formal ...releases them take time


as all ocurrances of macro will get replaced with replaceble text which increases LOC results more time for compilation whre as function we compile only once use many time


Conditional Compilation is possible by using #if #else #endif
At preprocessor level it will be decided will souce code to be forwarded for compilation.

    #if defined(SQR)
        printf("%d", SQR(4 + 2));
    #else
        SWAP(4,2,int);
    #endif

in above example SQR macro if it already defined then only one statement
        printf("%d", 4+2*4+2); will forwarded for compilation in replace of above condition precessive directive



to execute application from command prompt
    --->windows logo+r ---> cmd
    --->change directory to a location wher e.exe is available
    ---><exe file name> [arguments to be separated with space]


if arguments to main to be accepted in formal arguments then
    1. first argument should be compulsory of int type which stores the count of arguments
    2. second argument should be collection of string representation to store actual arguments passed
    3. third can hold enviornment variables i.e collection of strings

    however all arguments to main are optional but sequence of respective type is imp.



>structure:
    is collection of disimaliar/similar type of members. Helps to create user     defined data type.

    structure declaration is like skeleton/template which does not allocate     memory.

    if variable type of particular sture is created then every member receives     memory separately as per its own declaration data type.


    we can not access structure members out of declaration without structure     variable. Members to be separated using operator .(dot) or ->(arrow)


    at the time declaration functionally related members to be collected

   
    we can not assign any member of structure at the time declaration as no     memory is allocation


    //s is locally created and passed to display as by value   

    int main()
    {
        STUDENT s;
        s= accept_student_data();
        display_student_data(s)    //here is passed by value
    }

    STUDENT accept_student_data()
    {
        STUDENT s;
        //accept data in s
        return s;
    }

    void display_student_data(STUDENT s)
    {        //and s here is newly created with 40 bytes and copied
            actual arg. overhead to memory
        //display data
    }


    //s is globally declared then no need to pass both functions will     share/access same memory identified s

    STUDENT s;

    int main()
    {
        accept_student_data();
        display_student_data()   
    }

    void accept_student_data()
    {
        //accept data in s of global scope
    }

    void display_student_data()
    {       
        //display data
    }

    //pass by address
    int main()
    {
        STUDENT s;//s is locally declared
        accept_student_data(&s);//achieve pass by address
        display_student_data(&s);//achieve pass by address
    }

    void accept_student_data(STUDENT *sptr)
    {
   
        //accept data in sptr
   
    }

    void display_student_data(const STUDENT *sptr)
    {        //and sptr here is newly created with 4 bytes and             //starts pointing to s of main
        //display data
    }
   

    Bit Field : can be a part of structure declaration only. Helps to identify     bit/buits with specified name.

    We need to assign data which can fit into the specified bit else case will     result un predictable value.

    Bit fields can not be addressed.


> Syntax :
    signed/unsigned <field name> : <no.of bits> ;            


    union : is a collection of diffent types of variable.
        Memory to one union varable is given as per the member which         requires max memory
   
        All members of union shares same memory. i.e. a reason one member             should access given memory at a time.
       
        the one one member who access memory at last whoes data will be             avaialble for access.
   

    In case of structure every member receives memory separately where as in     case of union all members shares the same memory.   


>File Handling:
Need a pointer which will be pointer to FILE (typedefined struct declaration available in stdio.h)

fopen --- this function will help to associate file pointer loaded memory. Else case fopen returns NULL

>Type of files:
        1. Text File
            read  ---- fgetc,getc(MACRO),fgets,fscanf
            write ---- fputc,putc,fputs,fprintf
        2. Binary file
             read  ---- fread   
            write ---- fwrite

text data --->fwrite--->convert into binary--->write to file
read binary--->fread--->convert into text-->we access in text


>in which modes open file:
    r        --- read only
    r+    -----read first and then write
    w    ----only write
    w+    ----write first and then read
    a    -----append for writting at the end
    a+    ----- append(write) and read


the above mentioned all modes are used even in bonary format only thing we need to append 'b' .



fseek(FILE *fptr,long offset,int origin);
    a long offset can be +/-ve. If +ve will help to reposition file pointer in forward direction else if it is -ve then will help to reposition file pointer in backward direction.

origin can be represented with help symbolic constants available in stdio.h
    constant    replacable text   
    SEEK_SET      0 //repositions file pointer from beginning
    SEEK_CUR      1 //repositions file pointer from current position
    SEEK_END      2 //repositions file pointer from end of file       


 fseek(fp,10,SEEK_SET)//repositions file pointer 10 offset position ahead from beginning

 fseek(fp,-10,SEEK_CUR)//repositions file pointer 10 offset position back from current position

fseek(fp,10,SEEK_CUR)//repositions file pointer 10 offset position ahead from current position

fseek(fp,-10,SEEK_END)//repositions file pointer 10 offset position back from end of file

    fwrite returns count of record wriiten to a file

    STUDENT s;
    fwrite(&s,sizeof(STUDENT),1,fp);


    STUDENT s[5];
    fwrite(&s,sizeof(STUDENT),5,fp);
    or
    fwrite(&s,sizeof(s),1,fp);
    or
    for(i=0;i<5;i++)
    {
     fwrite(&s[i],sizeof(STUDENT),1,fp);
    }
   
Data Structure

stack ---->

    follows LIFO(LAST IN FIRST OUT)

    operations are performed via one end i.e. top

    can be implemented using array/dynamic memory

    applications of stack :
        1. recursion where implicit stack is used
        2. expression evaluation


 >  operations
        1. push ---adding element
            isfull stack check stack overflow state
        2. pop --- deleting element
            isempty() stack check stack underflow state
        3. peek--retrives top element
            isempty() stack check stack underflow state

















Comments

  1. Thanks sir.. almost all ours c concepts revised....
    Great efforts 👍👍

    ReplyDelete

Post a Comment

Popular posts from this blog