Sunday 1 July 2012

C program : Print the name

 
 


/* Hello World program */

#include<stdio.h>

main()
{
    printf("write Hello World which you want to print");
}

simpl tecneq to run the copy pasting of C program


PROGRAMING . WHAT IS ??? HADER FILES AND ETC

comming soon ...

some imp. topix 3.

comming soon

some imp. topix 2.

comming soon

some imp. topix 1.

comming soon

Searching and Sorting

Searching Techniques:


Searching for data is one of the fundamental fields of computing. Often, the difference between a fast program and a slow one is the use of a good algorithm for the data set. This article will focus on searching for data stored in a linear data structure such as an array or linked list.

Linear Search, Binary Search and other Searching Techniques:

 

Linear Search

The most obvious algorithm is to start at the beginning and walk to the end, testing for a match at each item:

bool jw_search ( int *list, int size, int key, int*& rec )
{
  // Basic sequential search
  bool found = false;
  int i;

  for ( i = 0; i < size; i++ ) {
    if ( key == list[i] )
      break;
  }
  if ( i < size ) {
    found = true;
    rec = &list[i];
  }

  return found;
} 
 
 
 
 

Binary Search

All of the sequential search algorithms have the same problem; they walk over the entire list. Some of our improvements work to minimize the cost of traversing the whole data set, but those improvements only cover up what is really a problem with the algorithm. By thinking of the data in a different way, we can make speed improvements that are much better than anything sequential search can guarantee.




bool jw_search ( int *list, int size, int key, int*& rec )
{
  // Binary search
  bool found = false;
  int low = 0, high = size - 1;

  while ( high >= low ) {
    int mid = ( low + high ) / 2;
    if ( key < list[mid] )
      high = mid - 1;
    else if ( key > list[mid] )
      low = mid + 1;
    else {
      found = true;
      rec = &list[mid];
      break;
    }
  }

  return found;
}



Conclusion:

Searching is an important function in computer science. Many advanced algorithms and data structures have been devised for the sole purpose of making searches more efficient. And as the data sets become larger and larger, good search algorithms will become more important. At one point in the history of computing, sequential search was sufficient. But that quickly changed as the value of computers became apparent.

Linear search has many interesting properties in its own right, but is also a basis for all other search algorithms. Learning how it works is critical.

Binary search is the next logical step in searching. By dividing the working data set in half with each comparison, logarithmic performance, O(log n), is achieved. That performance can be improved significantly when the data set is very large by using interpolation search, and improved yet again by using binary search when the data set gets smaller.
 
 
 Sorting:  It is the process of aranging a set of similar 
info into inc. or dec. order  
 
 

Techniques:

  1. Insertion sort

  2. Bubble sort

  3. Merge sort 

source codes:


2d  insertion sort [linked list]:
#include <stdio.h>
#include <stdlib.h>

struct node {
 int number;
 struct node *next;
};

struct node *head = NULL;

/* insert a node directly at the right place in the linked list */
void insert_node(int value);

int main(void) {
 struct node *current = NULL;
 struct node *next = NULL;
 int test[] = {8, 3, 2, 6, 1, 5, 4, 7, 9, 0};
 int i = 0;

 /* insert some numbers into the linked list */
 for(i = 0; i < 10; i++)
  insert_node(test[i]);

 /* print the list */
 printf(" before  after\n"), i = 0;
 while(head->next != NULL) {
  printf("%4d\t%4d\n", test[i++], head->number);
  head = head->next;
 }

 /* free the list */
 for(current = head; current != NULL; current = next)
  next = current->next, free(current);

 return 0;
}

void insert_node(int value) {
 struct node *temp = NULL;
 struct node *one = NULL;
 struct node *two = NULL;

 if(head == NULL) {
  head = (struct node *)malloc(sizeof(struct node *));
  head->next = NULL;
 }

 one = head;
 two = head->next;
 
 temp = (struct node *)malloc(sizeof(struct node *));
 temp->number = value;
 
 while(two != NULL && temp->number < two->number) {
  one = one->next;
  two = two->next;
 }

 one->next = temp;
 temp->next = two;
}

Insertion sort [linked list]:


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

struct lnode {
 char *str;
 struct lnode *next;
};

struct lnode *insert(char *data, struct lnode *list);
void free_list(struct lnode *list);
void print_list(struct lnode *list);

int main(void) {
 char line[1024];
 struct lnode *list;

 list = NULL;
 while((fgets(line, 1024, stdin)) != NULL)
  list = insert(line, list);

 print_list(list);
 free_list(list);
 return 0;
}

struct lnode *insert(char *data, struct lnode *list) {
 struct lnode *p;
 struct lnode *q;

 /* create a new node */
 p = (struct lnode *)malloc(sizeof(struct lnode));
 /* save data into new node */
 p->str = strdup(data);

 /* first, we handle the case where `data' should be the first element */
 if(list == NULL || strcmp(list->str, data) > 0) {
  /* apperently this !IS! the first element */
  /* now data should [be|becomes] the first element */
  p->next = list;
  return p;
 } else { 
  /* search the linked list for the right location */
  q = list;
  while(q->next != NULL && strcmp(q->next->str, data) < 0) {
   q = q->next;
  }
  p->next = q->next;
  q->next = p;
  return list;
 }
}
   
void free_list(struct lnode *list) {
 struct lnode *p;

 while(list != NULL) {
  p = list->next;
  free(list);
  list = p;
 }
}
 
void print_list(struct lnode *list) {
 struct lnode *p;
 
 for(p = list; p != NULL; p = p->next)
  printf("%s", p->str);
}




 Bubble sort [linked list]:
#include <stdio.h>
#include <stdlib.h>

#define MAX 10

struct lnode {
 int data;
 struct lnode *next;
} *head, *visit;

/* add a new entry to the linked list */
void llist_add(struct lnode **q, int num);
/* preform a bubble sort on the linked list */
void llist_bubble_sort(void);
/* print the entire linked list */
void llist_print(void);

int main(void) {
 /* linked list */
 struct lnode *newnode = NULL;
 int i = 0; /* a general counter */

 /* load some random values into the linked list */
 for(i = 0; i < MAX; i++) {
  llist_add(&newnode, (rand() % 100));
 }

 head = newnode;
 printf("Before bubble sort:\n");
 llist_print();
 printf("After  bubble sort:\n");
 llist_bubble_sort();
 llist_print();

 return 0;
}

/* adds a node at the end of a linked list */
void llist_add(struct lnode **q, int num) {
 struct lnode *tmp;

 tmp = *q;

 /* if the list is empty, create first node */
 if(*q == NULL) {
  *q = malloc(sizeof(struct lnode));
   tmp = *q;
 } else {
  /* go to last node */
  while(tmp->next != NULL)
   tmp = tmp->next;

   /* add node at the end */
   tmp->next = malloc(sizeof(struct lnode));
   tmp = tmp->next;
 }

 /* assign data to the last node */
 tmp->data = num;
 tmp->next = NULL;
}

/* print the entire linked list */
void llist_print(void) {
 visit = head;

 while(visit != NULL) {
  printf("%d ", visit->data);
  visit = visit->next;
 }
 printf("\n");
}

/* preform a bubble sort on the linked list */
void llist_bubble_sort(void) {
 struct lnode *a = NULL;
 struct lnode *b = NULL;
 struct lnode *c = NULL;
 struct lnode *e = NULL;
 struct lnode *tmp = NULL;

 /*
 // the `c' node precedes the `a' and `e' node
 // pointing up the node to which the comparisons
 // are being made.
 */
 while(e != head->next) {
 c = a = head;
 b = a->next;
  while(a != e) {
   if(a->data > b->data) {
    if(a == head) {
     tmp = b -> next;
     b->next = a;
     a->next = tmp;
     head = b;
     c = b;
    } else {
     tmp = b->next;
     b->next = a;
     a->next = tmp;
     c->next = b;
     c = b;
    }
   } else {
    c = a;
    a = a->next;
   }
   b = a->next;
   if(b == e)
    e = a;
  }
 }
}


Merge sort [linked list]:

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

struct node {
 int number;
 struct node *next;
};

/* add a node to the linked list */
struct node *addnode(int number, struct node *next);
/* preform merge sort on the linked list */
struct node *mergesort(struct node *head);
/* merge the lists.. */
struct node *merge(struct node *head_one, struct node *head_two);

int main(void) {
 struct node *head;
 struct node *current;
 struct node *next;
 int test[] = {8, 3, 2, 6, 1, 5, 4, 7, 9, 0};
 int i;

 head = NULL;
 /* insert some numbers into the linked list */
 for(i = 0; i < 10; i++)
  head = addnode(test[i], head);

 /* sort the list */
 head = mergesort(head);

 /* print the list */
 printf(" before  after\n"), i = 0;
 for(current = head; current != NULL; current = current->next)
  printf("%4d\t%4d\n", test[i++], current->number);

 /* free the list */
 for(current = head; current != NULL; current = next)
  next = current->next, free(current);

 /* done... */
 return 0;
}

/* add a node to the linked list */
struct node *addnode(int number, struct node *next) {
 struct node *tnode;

 tnode = (struct node*)malloc(sizeof(*tnode));

 if(tnode != NULL) {
  tnode->number = number;
  tnode->next = next;
 }

 return tnode;
}

/* preform merge sort on the linked list */
struct node *mergesort(struct node *head) {
 struct node *head_one;
 struct node *head_two;

 if((head == NULL) || (head->next == NULL))
  return head;

 head_one = head;
 head_two = head->next;
 while((head_two != NULL) && (head_two->next != NULL)) {
  head = head->next;
  head_two = head->next->next;
 }
 head_two = head->next;
 head->next = NULL;

 return merge(mergesort(head_one), mergesort(head_two));
}

/* merge the lists.. */
struct node *merge(struct node *head_one, struct node *head_two) {
 struct node *head_three;

 if(head_one == NULL)
  return head_two;

 if(head_two == NULL)
  return head_one;

 if(head_one->number < head_two->number) {
  head_three = head_one;
  head_three->next = merge(head_one->next, head_two);
 } else {
  head_three = head_two;
  head_three->next = merge(head_one, head_two->next);
 }

 return head_three;
}

C Programming - Linked Lists

Linked Lists:


Linked lists are a type of data structure for storing information as a list. They are a memory efficient alternative to arrays because the size of the list is only ever as large as the data. Plus they do not have to shift data and recopy when resizing as dynamic arrays do.

They do have the extra overhead of 1 or 2 pointers per data node, so they make sense only with larger records. You would not want to store a list of integers in a linked list because it would actually double your memory overhead over the same list in an array.

There are three different types of linked lists, but the other two are just variations of the basic singly linked list. If you understand this linked list then you will be able to handle other two types of lists.

Advantages of Linked Lists:

A linked list is a dynamic data structure and therefore the size of the linked list can grow or shrink in size during execution of the program. A linked list does not require any extra space therefore it does not waste extra memory. It provides flexibility in rearranging the items efficiently.
The limitation of linked list is that it consumes extra space when compared to a array since each node must also contain the address of the next item in the list to search for a single item in a linked list is cumbersome and time consuming process.

Linked lists Types:

There are 4 different kinds of linked lists:
  1. Linear singly linked list
  2. Circular singly linked list
  3. Two way or doubly linked list
  4. Circular doubly linked list.

Linked List Nodes:

A linked list gets their name from the fact that each list node is "linked" by a pointer. A linked list node is comparable to an array element. A node contains a data portion and a pointer portion, and is declared as structs in C.
As an example, we can implement a list of high scores for a game as a linked list.


Creating Linked Lists:

A linked list always has a base node that is most commonly called a head, but some call it as a root. An empty linked list will have this node and will be set to NULL. This goes for all three types of linked lists. The last node in a linked list always points to NULL.
Let us declare our linked list for implementing high scores list.

struct llnode *head = NULL;

Here we just declared a regular pointer variable of the node struct we declared, and then set the head to NULL to indicate the list is empty.

Traversing a Linked List:

Moving through a linked list and visiting all the nodes is called traversing the linked list. There is more than one way to encounter segmentation faults when traversing a linked list, but if you are careful and follow 2 basic checks you will be able to handle segmentation faults.


To traverse a singly linked list you create a pointer and set it to head. Often called the current node as a reminder that it is keeping track of the current node. Always make sure to check that head is not NULL before trying to traverse the list or you will get a segmentation fault. You may also need to check that the next pointer of the current node is not NULL, if not, you will go past the end of the list and create a segmentation fault.



C Doubly Linked Lists:


Doubly linked lists are the same as singly linked lists, except they have an extra pointer per node so they point to the next node and the previous node. You just make sure that whenever you insert a node you set next to the next node and previous to the previous node. They will also commonly keep a tail and head pointer so that traversal may start at either end of the list.

Doubly Linked List Nodes

A doubly linked list node would look like this:


struct dllnode {

          Arbitrary Data Portion

          struct dllnode *next;
          struct dllnode *previous;
        };


 
It contains a data portion and a pointer to both the next and previous nodes in the list sequence allowing for two-way traversal.

Creating A Doubly Linked List:

When creating a doubly linked list, we want to be able to go both ways as well as be able to start at either end of the list when traversing it. As mentioned earlier, we use a both a tail and a head pointer to provide this functionality.

Checking for head being NULL is sufficient for checking for an empty list.

if (head == NULL) {
            //This node becomes the first and last node in the list.                    
            newnode->previous = NULL;
            newnode->next = NULL;
            head = newnode;
            tail = head;


        }


Pretty much the same as we have done throughout this tutorial with the singularly linked lists, with the addition of the previous pointer needing to be set to NULL and the tail also being equal to the new node.

Inserting Nodes:

Same as linear singularly linked lists, we can add at the beginning, middle, or end of a doubly linked list.

Placing a node at the beginning of a doubly linked list is quite simple but an empty and nonempty must be handled differently.

When the list is empty all you have to do is create the new node, set its next and previous pointers to NULL, and point the head and tail pointers to it. We already saw the code for this in the last section.

Inserting a new node at the beginning of a nonempty doubly linked list is a little tricky, but not impossible. First you create your new node and set its previous pointer to NULL, but the next pointer to the current head. Then set the current head's previous pointer to the new node being inserted to move the old head one up in the list. Now all you have to do is point head at the new node and you are done.
In code it should look something like this


newnode->previous = NULL;
    newnode->next = head;
    head->previous = newnode;
    head = newnode;
Insertion of a new node at the end of the list is quite similar although we use the tail pointer as a reference instead of the head pointer. Since the empty list case here is identical to the empty list case above for insert at beginning we will skip it.

To place a node at the end of the nonempty list you create the new node, set its next pointer to NULL and its previous pointer to the current tail. Then set the current tail's next pointer to the new node. Now point tail to the new node which you have inserted a node at the back of the list. Although it's not in our example, here is a code snippet


newnode->next = NULL;
        newnode->previous = tail;
        tail->next = newnode;
        tail = newnode;


Note the similarity to the sample for insertion at the beginning.
Here's the fun part, this is the greatest feature of the doubly linked list. It's actually so simple though, you may be disappointed.

Forward traversal is identical to singly linked list traversal. Seriously, there is no difference. This should look familiar.

if (head != NULL) {
            currentnode = head;
            while (currentnode->next != NULL) {
              currentnode = currentnode->next;
}
            }
With that in mind, you would think that going the other way would be the same but with the tail pointer. You would be correct.


if (tail != NULL) {
            currentnode = tail;
            while (currentnode->previous != NULL) {
              currentnode = currentnode->previous;
            }
        }
 

C Circular Linked Lists:



In this tutorial you will learn about C Programming - What is Circular Linked List, Adding Nodes to Circular Linked Lists, Traversing a Circularly Linked List and working with Circularly Linked List Example.
Circular linked lists are usually used for a queue or stack type situation, or for implementing a round robin algorithm in system level programming. You could also use one for a multiplayer game where you were keeping track of player's turns where it just repeats until the game ends.

They are exactly the same as a singly linked list, but instead of setting the next pointer in the last node of the list to NULL, you set it to point to head. Hence the name circular. Instead of a head pointer, they commonly use a tail pointer instead to keep track of the last node.
A cingularly linked list node looks exactly the same as a linear singly linked list. Here's the node for the example. 
struct cllnode {
          char name[4];
          struct cllnode *next;
        };
It should be familiar from the previously introduced linear linked list, just a data portion and the next pointer.

Adding Nodes to Circular Linked Lists

Adding nodes and creating new circularly linked lists is very similar to the linear ones we learned previously. Let's look at our example to illustrate.
void addNode(struct cllnode *newnode) {
          //List is empty. Create new list.                                            
          if (tail == NULL) {
 
            tail = newnode;
            newnode->next = tail;
 
          } else {
            //List isn't empty so add at the tail. Remember "first in first out."      
            newnode->next = tail->next;
            tail->next = newnode;
            tail = newnode;
          }
        }
That addNode function is all it takes to handle both the empty and non-empty singularly linked list cases when adding new nodes. You add at the back of the list in this linked list case and that's one of the reasons these are used for modeling queues and FIFO stacks.

Just as in the singularly linked list case you first check if the list pointer (no matter what you are calling it) is NULL. Then set the tail equal to the new node being added and make its pointer point back at itself, thus completing the circle.

When there are nodes in the list, you first set the new node's next pointer to tail->next because you are adding it just after tail, not at tail. You may be able to see why we use tail pointers rather than head pointers for circularly linked lists. The head would be 2 pointers away from where we perform insertions.

After that, you set tail's next pointer to the new node and set tail equal to the new node. Viola, we have inserted a new node at the end of the list, and tail is now pointing at it.

Traversing a Circularly Linked List:

Traversing a circularly linked list is a little different than the regular type, due to the fact that there is no NULL termination to tell you when to stop. However, we can just use the tail pointer for this purpose as well.

As we see in this snippet of our example program, it's not any more difficult to traverse, it's just different


if (tail != NULL) {
            current = tail->next;
 
            while (current != tail) {
 
                ...
 
        current = current->next;
            }
 
            current = tail;
 
            ...
          }

We begin with the familiar check for the list's existence. If we have a list, we set the current pointer to the node after tail. From here we can just go through the nodes until we return to tail, so we use a while loop to do that. The traversal is the same as before in that you just set the current pointer to the next one at the end of the wile loop.
Now if you want to do something when you get to the tail you must do it after the while loop traversal, because our condition stopped the traversal at the node just before tail and started just after it. As you can see we had to add an addition print out block after the while loop to be able to see the last node's information printed out.

C Programming - Dynamic Memory allocation


C Programming - Dynamic Memory allocation:


Embedded and other low-memory footprint applications need to be easy on the amount of memory they use when executing.  In such scenarios, statically sized data types and data structures just are not going to solve your problem.  The best way to achieve this is by allocation of memory for variables at runtime under your watchful eye. This way your program is not using more memory than it has to at any given time. However, it is important to note that the amount of memory that can be allocated by a call to any of these functions is different on every O.S. .

Dynamic Memory Allocation:

malloc, calloc, or realloc are the three functions used to manipulate memory.  These commonly used functions are available through the stdlib library so you must include this library in order to use them.

#include stdlib.h 
After including the stdlib library you can use the malloc, calloc, or realloc functions to manipulate chunks of memory for your variables.

Dynamic Memory Allocation Process:

When a program executes, the operating system gives it a stack and a heap to work with. The stack is where global variables, static variables, and functions and their locally defined variables reside. The heap is a free section for the program to use for allocating memory at runtime.

Allocating a Block of Memory

Use the malloc function to allocate a block of memory for a variable. If there is not enough memory available, malloc will return NULL.
The prototype for malloc is:


void *malloc(size_t size);



Do not worry about the size of your variable, there is a nice and convenient function that will find it for you, called sizeof. Most calls to malloc will look like the following example:

ptr = (struct mystruct*)malloc(sizeof(struct mystruct));


This way you can get memory for your structure variable without having to know exacly how much to allocate for all its members as well.

Allocating Multiple Blocks of Memory:

You can also ask for multiple blocks of memory with the calloc function:


void *calloc(size_t num, size_t size);

If you want to allocate a block for a 10 char array, you can do this:



  1. char *ptr;
  2. ptr = (char *)calloc(10, sizeof(char));
The above code will give you a chunk of memory the size of 10 chars, and the ptr variable would be pointing to the beginning of the memory chunk. If the call fails, ptr would be NULL.

Releasing the Used Space:

All calls to the memory allocating functions discussed here, need to have the memory explicitly freed when no longer in use to prevent memory leaks. Just remember that for every call to an *alloc function you must have a corresponding call to free.
The function call to explicitly free the memory is very simple and is written as shown here below:
free(ptr);
Just pass this function the pointer to the variable you want to free and you are done.
To Alter the Size of Allocated Memory
Lets get to that third memory allocation function, realloc.

void *realloc(void *ptr, size_t size);
Pass this function the pointer to the memory you want to resize and the new size you want to resize the allocated memory for the variable you want to resize.




Arrays & Pointers

C Programming - Arrays:


Array is a collection of same type elements under the same variable identifier referenced by index number. Arrays are widely used within programming for different purposes such as sorting, searching and etc. Arrays allow you to store a group of data of a single type.  Arrays are efficient and useful for performing operations . You can use them to store a set of high scores in a video game, a 2 dimensional map layout, or store the coordinates of a multi-dimensional matrix for linear algebra calculations.

Arrays are of two types single dimension array and multi-dimension array.  Each of these array type can be of either static array or dynamic array. Static arrays have their sizes declared from the start and the size cannot be changed after declaration. Dynamic arrays that allow you to dynamically change their size at runtime, but they require more advanced techniques such as pointers and memory allocation. 


It helps to visualize an array as a spreadsheet. A single dimension array is represented be a single column, whereas a multiple dimensional array would span out n columns by n rows.  In this tutorial, you will learn how to declare, initialize and access single and multi dimensional arrays.

Single Dimension Arrays:

Declaring Single Dimension Arrays:

Arrays can be declared using any of the data types available in C. Array size must be declared using constant value before initialization.  A single dimensional array will be useful for simple grouping of data that is relatively small in size. You can declare a single dimensional array as follows:

<data type> array_name[size_of_array];

Say we want to store a group of 3 possible data information that correspond to a char value, we can declare it like this:



 char game_map[4];



Initializing Single Dimension Arrays:

Array can be initialized in two ways, initializing on declaration or initialized by assignment.

Initializing on Declaration:

If you know the values you want in the array at declaration time, you can initialize an array as follows:

 <data type> array_name[size_of_array] = {element 1,
element 2, ...};



C Programming - Pointers:

Pointers are widely used in programming; they are used to refer to memory location of another variable without using variable identifier itself. They are mainly used in linked lists and call by reference functions.
Diagram 1 illustrates the idea of pointers. As you can see below; Yptr is pointing to memory address 100.

Diagram 1: 1. Pointer and memory relationship

Pointer Declaration;

Declaring pointers can be very confusing and difficult at times (working with structures and pointer to pointers). To declare pointer variable we need to use * operator (indirection/dereferencing operator) before the variable identifier and after data type. Pointer can only point to variable of the same data type.
Syntax
Datatype * identifier;



Address operator:

Address operator (&) is used to get the address of the operand. For example if variable x is stored at location 100 of memory; &x will return 100.
This operator is used to assign value to the pointer variable. It is important to remember that you MUST NOT use this operator for arrays, no matter what data type the array is holding. This is because array identifier (name) is pointer variable itself. When we call for ArrayA[2]; ‘ArrayA’ returns the address of first item in that array so ArrayA[2] is the same as saying ArrayA+=2; and will return the third item in that array.

Pointer arithmetic:

Pointers can be added and subtracted. However pointer arithmetic is quite meaningless unless performed on arrays. Addition and subtraction are mainly for moving forward and backward in an array.

 Note:
you have to be very careful NOT to exceed the array elements when you use arithmetic; otherwise you will get horrible errors such as “access violation”. This error is caused because your code is trying to access a memory location which is registered to another program.


Operator
Result
++
Goes to the next memory location that the pointer is pointing to.
--
Goes to the previous memory location that the pointer is pointing to.
-= or -
Subtracts value from pointer.
+= or +
Adding to the pointer



Pointer to Arrays:

Array identifier is a pointer itself. Therefore & notation shouldn’t be used with arrays. The example of this can be found at code 3. When working with arrays and pointers always remember the following:
  • Never use & for pointer variable pointing to an array.
  • When passing array to function you don’t need * for your declaration.
  • Be VERY CAREFUL not to exceed number of elements your array holds when using pointer arithmetic to avoid errors.

Pointers and Structures:

Pointers and structures is broad topic and it can be very complex to include it all in one single tutorial. However pointers and structures are great combinations; linked lists, stacks, queues and etc are all developed using pointers and structures in advanced systems.

Pointer to Pointer:

Pointers can point to other pointers; there is no limit whatsoever on how many ‘pointer to pointer’ links you can have in your program. It is entirely up to you and your programming skills to decide how far you can go before you get confused with the links. Here we will only look at simple pointer to pointer link. Pointing to pointer can be done exactly in the same way as normal pointer. Diagram below can help you understand pointer to pointer relationship.

Diagram 2. Simple pointer to pointer relationship
Code for diagram 2:
Char *ptrA;
Char x=’b’;
Char *ptrb;
ptrb=&x;
ptrA=&ptrb;
ptrA gives 100, *ptrA gives 101 , ptrb is 101 ,*ptrb gives b, **ptrA gives b
comment: **ptrA means ‘value stored at memory location of value stored in memory location stored at PtrA’

Call by Value and Call by Reference & Recursion

Call by Value and Call by Reference:


In C programming language, variables can be referred differently depending on the context. For example, if you are writing a program for a low memory system, you may want to avoid copying larger sized types such as structs and arrays when passing them to functions. On the other hand, with data types like integers, there is no point in passing by reference when a pointer to an integer is the same size in memory as an integer itself.
Now, let us learn how variables can be passed in a C program.

Pass By Value:

Passing a variable by value makes a copy of the variable before passing it onto a function. This means that if you try to modify the value inside a function, it will only have the modified value inside that function. One the function returns, the variable you passed it will have the same value it had before you passed it into the function.

Pass By Reference:

There are two instances where a variable is passed by reference:
  1. When you modify the value of the passed variable locally and also the value of the variable in the calling function as well.
  2. To avoid making a copy of the variable for efficiency reasons.

Recursion:

A function that calls itself is known as recursive function and the process of calling function itself is known as recursion in programming.

Advantages and Disadvantages of Recursion:

Recursion is more elegant and requries few variables which make program clean and easy to understand. Recursion can be used to replace complex nesting code by dividing the problem into same problem of subtype.
In other hand, it is hard to think the logic of a recursive function. It is also difficult to debug the code containing recursion.





Storage Class

Storage Class:

Every variable and function in C programming has two properties: type and storage class. Type refers to the data type of variable whether it is character or integer or floating-point value etc.
There are 4 types of storage class:

  • automatic
  • external
  • static
  • register

Automatic storage class:

Keyword for automatic variable:

auto
 
 
Variables declared inside the function body are automatic by default. These variable are also known as local variables as they are local to the function and doesn't have meaning outside that function
Since, variable inside a function is automatic by default, keyword auto are rarely used.

External storage class:

External variable can be accessed by any function. They are also known as global variables. Variables declared outside every function are external variables.
In case of large program, containing more than one file, if the global variable is declared in file 1 and that variable is used in file 2 then, compiler will show error. To solve this problem, keyword extern is used in file 2 to indicate that, the variable specified is global variable and declared in another file.




Static Storage Class:

The value of static variable persists until the end of the program. A variable can be declared static using keyword: static. For example:

static int i;
 
 

Register Storage Class:

Keyword to declare register variable:

register
 
 
Example of register variable:

register int a;
 
Register variables are similar to automatic variable and exists inside that particular function only.
If the compiler encounters register variable, it tries to store variable in microprocessor's register rather than memory. Value stored in register are much faster than that of memory.
In case of larger program, variables that are used in loops and function parameters are declared register variables.
Since, there are limited number of register in processor and if it couldn't store the variable in register, it will automatically store it in memory.

 
 
 
 

Modular programming & C Functions

Modular programming:

 A programming style that braks down program functions into modules, each of which accomplishes one function and contains all the source code and variables needed to accomplish that function. Modular programming is a solution to the problem of very large programs that are difficult to debug and maintain. By segmenting the program into modules that perform clearly defined functions, you can determine the source of program erros more easly. Object-orientated programming languages, such as SmallTalk and HyperTalk, incorporate modular programming principles.


 

Function:

A function in programming is a segment that groups a number of program statements to perform specific task.
A C program has atleast one function [ main( ) ]. Without main() , there is technically no C program.

Types of C functions:

Basically, there are two types of functions in C on basis of whether it is defined by user or not.
  • Library function
  • User defined function

Library function:

Library functions are the in-built function in C programming system. For example:
main()
- The execution of every C program starts from this main. 
printf()
- prinf() is used for displaying output in C.
scanf()
- scanf()  is used for taking input in C.
Visit this page to learn more about library functions in C programming.

User defined function

C provides programmer to define their own function according to their requirement known as user defined functions.

Example of how C function works:

#include <stdio.h>
void function_name(){
................
................
}
int main(){
...........
...........
function_name();
...........
...........
} 
 
 
As mentioned earlier, every C program begins from main() and program starts executing the codes inside main function. When the control of program reaches to function_name() inside main. The control of program jumps to "void function_name()" and executes the codes inside it. When, all the codes inside that user defined function is executed, control of the program jumps to statement just below it. Analyze the figure below for understanding the concept of function in C.

Working of functions in C programming


Remember, the function name is an identifier and should be unique.

Advantages of user defined functions:

  • User defined functions helps to decompose the large program into small segments which makes programmar easy to understand, maintain and debug.
  • If repeated code occurs in a program. Function can be used to include those codes and execute when needed by calling that function.
  • Programmar working on large project can divide the workload by making different functions.



Function prototype(declaration):

Every function in C programming should be declared before they are used. These type of declaration are also called function prototype. Function prototype gives compiler information about function name, type of arguments to be passed and return type.

Syntax of function prototype:

return_type function_name(type(1) argument(1),....,
type(n) argument(n));

Here, in the above example, function prototype is "int add(int a, int b);" which provides following information to the compiler:
  1. name of the function is "add"
  2. return type of the function is int.
  3. two arguments of type int are passed to function.
Function prototype is not needed, if you write function definition above the main function. In this program if the code from line 12 to line 19 is written above main( ), there is no need of function prototype.

Function call:

Control of the program cannot be transferred to user-defined function (function definition) unless it is called (invoked).

Syntax of function call:

function_name(argument(1),....argument(n));
 
In the above example, function call is made using statement "add(num1,num2);" in line 8. This makes control of program transferred to function declarator(line 12). In line 8, the value returned by function is kept into "sum" which you will study in detail in function return type of this chapter.

Function definition:

Function definition contains programming codes to perform specific task.

Syntax of function definition:

return_type function_name(type(1) argument(1),.
....,type(n) argument(n))
{
                //body of function
} 
 
 
Function definition has two major components:

1. Function declarator:

Function declarator is the first line of function definition. When a function is invoked from calling function, control of the program is transferred to function declarator or called function.

Syntax of function declarator

return_type function_name(type(1) argument(1),....,type(n) argument(n))
Syntax of function declaration and declarator are almost same except, there is no semicolon at the end of declarator and function declarator is followed by function body.
In above example, " int add(int a,int b)" in line 12 is function declarator.

2. Function body:

Function declarator is followed by body of function which is composed of statements.
In above example, line 13-19 represents body of a function.

Passing arguments to functions

In programming, argument/parameter is a piece of data(constant or  variable) passed from a program to the function.
In above example two variable, num1 and num2 are passed to function during function call and these arguments are accepted by arguments a and b in function definition.

Passing argument/parameter through function in C

Arguments that are passed in function call and arguments that are accepted in function definition should have same data type. For example:
If argument num1 was of int type and num2 was of float type then, argument a should be of int type and b should be of float type in function definition. i.e. type of argument during function call and function definition should be same.
A function can be called with or without an argument.

Return Statement:

Return statement is used for returning a value from function definition to calling function.

Syntax of return statement

return (expression;
          OR
     return;     

For example:

return;
return a;
return (a+b);
 
 
In above example of source code, add is returned (line 18) to the calling function add(num1,num2); (line 8) and this value is stored in variable sum.
Note that, data type of add is int and also the return type of function is int. The data type of expression in return statement should also match the return type of function.

Working of return statement in C





C Decisions & Loops


if...else Statement:

Decision making are needed when, the program encounters the situation to choose a particular statement among many statements. C programming provides following statements to make decision makings:
  • if...else statement
  • switch statement

if (test expression)
     statements to be executed if test expression is true;




Branching in C programming using if statement

Nested if...else statement (if...elseif....else Statement):

The if...else statement can be used in nested form when a serious decision are involved. The ANSI standard specifies that 15 levels of nesting may be continued.

Syntax of nested if...else statement:

if (test expression)
     statements to be executed if test expression is true;
else
     if(test expression 1)
          statements to be executed if test expressions 1 is true;
       else 
          if
           .
           .
           .
            else
              statements to be executed if all test expressions are false;
How nested if...else works?
If the test expression is true, it will execute the relevant code but, if it is false, the control of the program jumps to the else part and check test expression 1 and the process continues. If all the test expression are fa;se then, only the last statement is executed.


 

for Loop

C programming loops:

Loops causes program to repeat the certain block of code until some conditions are satisfied. Loops are used in performing repetitive work in programming.

Syntax of for loop:

for(initial expression; test expression; update expression)
{
       codes to be executed; 
}

How for loops in C programming works?

The initial expression is initialized only once at the beginning of the for loop. Then, the test expression is checked by the program.
If the test expression is false, for loop is terminated.
If test expression is true then, the codes are executed and update expression is updated. Again, the test expression is checked. If it is false, loop is terminated and if it is true, the same process repeats until test expression is false.
For the easier understanding of how for loop works, analyze the flowchart of for loop below.
Flowchart of for loop in C programming language




Importent:
  • Initial, test and update expression in C for loop are separated by semicolon(;).
  • Two or more expression of same type  in for loop are separated by comma(,).

o...while Loop

C programming loops

Loops causes program to repeat the certain block of code until some conditions are satisfied. Loops are used in performing repetitive work in programming.

C while loops:

Syntax of while loop:

 
while (test expression)
{
     statements to be executed.  
}


In the beginning of while loop, test expression is checked. If it is true, codes inside the body of while loop is executed and again the test expression is checked and process continues until, the test expression becomes false.



Flowchart of while loop in C programming



C do...while loops:

C do...while loop is very similar to while loop. Only difference between these two loops is that, in while loops, test expression is checked at first but, in do...while loop code is executed at first then the condition is checked. So, the code are executed at least once in do...while loops.

Syntax of do...while loops:

do {
   some codes;
}
while (test expression); 
 
At first codes inside body of do is executed. Then, the test expression is checked. If it is true(nonzero), codes inside  body of do are executed again and the process continues until test expression is zero(false).
Notice, there is semicolon in the end of while (); in do...while loop.



Flowchart of working of do...while loop in C programming.



 

break and continue Statement:

There are two statement built in C, break; and continue; to interrupt the normal flow of control of  a program. Loops performs a set of operation repeately until certain control variable fails but, it is sometimes desirable to skip some statements inside loop and terminate the loop immediately without checking the test expression. In such cases, break and continue statements are used.

C break statement:

In C programming, break is used in terminating the loop immediately after it is encountered. The break statement is used with conditional if statement.

Syntax of break statement:

break; 
 
The break statement can be used in terminating all three loops for, while and do...while loops.



Flowchart of break statement in C programming.
 For better understanding of how break statements works in C programming loops. Anlayze the illustration of exiting a loop with break statement below.



working of break statement in C programming in for, while and do...while loops



C continue statement:

It is sometimes desirable to skip some statements inside the loop. In such cases, continue statements are used. Continue statements are only used in while, do...while and for loops in C programming.

Syntax of continue statement:

continue; 
 
Just like break, continue is also used with conditional if statement.

 For better understanding of how continue statements works in C programming. Analyze the illustration of bypassing and continuing in loops below.

Working of continue statement in  C programming for, while and do...while loops








 

switch....case Statement:

Decision making are needed when, the program encounters the situation to choose a particular statement among many statements. If a programmar has to choose one among many alternatives if...else can be used but, this makes programming logic complex. This type of problem can be handled in C using switch...case statement.

Syntax of C switch...case:

switch (expression)
{
case constant1:
   codes to be executed if expression equals to constant1;
   break;
case constant2:
   codes to be executed if expression equals to constant3;
   break;
   .
   .
   . 
default:
   codes to be executed if expression doesn't match to any cases;
}

In switch...case, expression is an integer or character expression asked to a user. If the value of switch expression matches any of the constant in cases, the relevant codes are executed and control moves out of the switch case statement. If the expression doesn't matches any of the constant in cases, then the default statement is executed.

 

Working of C switch...case statement in C programming.

 

 

 

goto Statement:

The goto statement in C is used to alter the normal sequence of program execution by transferring control to some other part of the program.

Syntax of goto statement:

goto label;
.............
.............
.............
label: 
statement; 
 
 
In this syntax, label is an identifier. When, the control of program reaches to goto label statement, the control of the program will jump to the label.
Working of goto statement in C programming

 

Reasons to avoid goto statement:

Though, using goto statement give power to programmar to jump to any part of program, using goto statement in programming makes the logic of the program complex and tangled. In modern programming, goto statement is considered a harmful construct and a bad programming practice.
The goto statement can be replaced in most of  C program with the use of break and continue statements. In fact, any program in C programming can be perfectly written without the use of goto statement. All programmar should try to avoid goto statement as possible as they can.

Operators available in C

Operators

Operators are the symbol which operates on value or a variable. For example: + is a operator to perform addition.
C programming language has wide range of operators to perform operations. For better understanding of operators in C, these operators can be classified as:

Operators in C programming
Arithmetic Operators
Increment and Decrement Operators
Assignment Operators
Relational Operators
Logical Operators
Conditional Operators
Bitwise Operators




Arithmetic Operators:

Operator Meaning of Operator
+ addition or unary plus
- subtraction or  unary minus
* multiplication
/ division
% remainder after division( modulo division)




Increment and decrement operators:

In C, ++ and -- are called increment and decrement operators respectively. Both of these operators are uniary operators, i.e, used on single operand. ++ adds 1 to operand and -- subtracts 1 to operand respectively. For example:

Let a=5 and b=10
a++;  //a becomes 6
++a;  //a becomes 7
--b;  //b becomes 9
b--;  //b becomes 8 

Assignment Operators:

The most common assignment operator is '='. This operator assigns the value in right side to the left side. For example:
var=5  //5 is assigned to var
a=c;   //value of c is assigned to a
5=c;   // Error! 5 is a constant and its value can't be changed. 
Operator Example Same as
= a=b a=b
+= a+=b a=a+b
-= a-=b a=a-b
*= a*=b a=a*b
/= a/=b a=a/b
%= a%=b a=a%b


Relational Operator:

Relational operators are used to test relationship between two operands. If the relation is true, it returns value 1 and if the relation is false, it returns value 0. For example:
a>b
Here, > is a relational operator. If a is greater than b, a>b returns 1 if not then, it returns 0.
Relational operators are normally used in decision making and loops in C programming.
Operator Meaning of Operator Example
== Equal to 5==3 returns false (0)
> Greater than 5>3 returns true (1)
< Less than 5<3 returns false (0)
!= Not equal to 5!=3 returns true(1)
>= Greater than or equal to 5>=3 returns true (1)
<= Less than or equal to 5<=3 return false (0)

Logical Operators

Logical operators are used to combine expressions containing relation operators. In C, there are 3 logical operators.
Operator Meaning of Operator Example
&& Logial AND  If c=5 and d=2 then,((c==5) && (d>5)) returns false.
|| Logical OR If c=5 and d=2 then, ((c==5) || (d>5)) returns true.
! Logical NOT If c=5 then, !(c==5) returns false.



Conditional Operator:

Conditional operator takes three operands and consists of two symbols ? and : . Conditional operators are used for decision making in C. For example:
 
c=(c>0)?10:-10; 
 
If c is greater than 0, value of c will be 10 but, if c is less than 0, value of c will be -10.
To learn more, visit conditional operators page.


Bitwise Operators:

A bitwise operator works on each bit of data. Bitwise operators are used in bit level programming.
Operators Meaning of operators
& Bitwise AND
| Bitwise OR
^ Bitwise exclusive OR
~ Bitwise complement
<< Shift left
>> Shift right
Bitwise operator is advance topic in programming . You go further in C programming without knowing bitwise programming