Saturday, 10 August 2013

Storage Classes in C

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| Storage Classes |


A storage class defines the scope (visibility) and life time of variables and/or functions within a C Program. These specifiers precede the type that they modify. There are following storage classes which can be used in a C Program.

auto, static, register, extern

| auto Storage Class |

The auto storage class is the default storage class for all local variables.

{
int a;
auto int a;
}

The example above defines two variables with the same storage class, auto can only be used within functions, i.e. local variables.

| register Storage Class |

The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can't have the unary '&' operator applied to it (as it does not have a memory location).

{
register int m;
}
The register should only be used for variables that require quick access such as counters. It should also be noted that defining 'register' goes not mean that the variable will be stored in a register.

| static Storage Class |


The static storage class instructs the compiler to keep a local variable in existence during the lifetime of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.

The static modifier may also be applied to global variables. When this is done, it causes that variable's scope to be restricted to the file in which it is declared.
#include <stdio.h>
void func(void);
static int count = 10; /* global variable */
main()
{
while(count--)
{
func();
}
return 0;
}
void func( void )
{
static int i = 10; /* local static variable */
i++;
printf("\ni is %d and count is %d", i, count);
}

| extern Storage Class |


The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. When we use 'extern' the variable cannot be initialized as all it does is point the variable name at a storage location that has been previously defined. When we have multiple files and you define a global variable or function which will be used in other files also, then extern will be used in another file to give reference of defined variable or function. Just for understanding extern is used to declare a global variable or function in another files.

The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions as explained below.

First file: main.c
#include <stdio.h>
int count ;
extern void write_extern();
main()
{
count = 5;
write_extern();
}

Second File: second.c
#include <stdio.h>
extern int count;
void write_extern(void)
{
printf("count is %d\n", count);
}

Here extern keyword is being used to declare count in the second file where as it has its definition in the first file main.c.

Structures in C

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| Structure in C |


Arrays allow you to define type of variables that can hold several data items of the same kind but structure is another user defined data type available in C programming, which allows you to combine data items of different kinds.

Structures are used to represent a record, Suppose you want to keep track of your books in a library. You might want to track the following attributes about each book:

Title, Author, Subject, Book ID

| Defining a Structure |

To define a structure, you must use the struct statement. The struct statement defines a new data type, with more than one member for your program. The format of the struct statement is this:

struct [structure tag]
{
member definition;
member definition;
...
member definition;
} [one or more structure variables];

The structure tag is optional and each member definition is a normal variable definition, such as int i; or float f; or any other valid variable definition. At the end of the structure's definition, before the final semicolon, you can specify one or more structure variables but it is optional. Here is the way you would declare the Book structure:

struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;

| Accessing Structure Members |

To access any member of a structure, we use the member access operator (.). The member access operator is coded as a period between the structure variable name and the structure member that we wish to access. You would use struct keyword to define variables of structure type. Following is the example to explain usage of structure:

#include <stdio.h>
#include <string.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */
/* book 1 specification */
strcpy( Book1.title, "C Tutorials ");
strcpy( Book1.author, "Wind T ");
strcpy( Book1.subject, "C Tutorial");
Book1.book_id = 1234567;
/* book 2 specification */
strcpy( Book2.title, "C Tutorials1 ");
strcpy( Book2.author, "Wind T ");
strcpy( Book2.subject, "C Tutorial1");
Book2.book_id = 1234568;
/* print Book1 info */
printf( "Book 1 title : %s\n", Book1.title);
printf( "Book 1 author : %s\n", Book1.author);
printf( "Book 1 subject : %s\n", Book1.subject);
printf( "Book 1 book_id : %d\n", Book1.book_id);
/* print Book2 info */
printf( "Book 2 title : %s\n", Book2.title);
printf( "Book 2 author : %s\n", Book2.author);
printf( "Book 2 subject : %s\n", Book2.subject);
printf( "Book 2 book_id : %d\n", Book2.book_id);
return 0;
}

| Structures as Function Arguments |


You can pass a structure as a function argument in very similar way as you pass any other variable or pointer. You would access structure variables in the similar way as you have accessed in the above example:

#include <stdio.h>
#include <string.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};

/* function declaration */
void printBook( struct Books book );
int main( )
{
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */
/* book 1 specification */
strcpy( Book1.title, "C Tutorial ");
strcpy( Book1.author, "Wind T ");
strcpy( Book1.subject, "C Tutorial");
Book1.book_id = 1234567;
/* book 2 specification */
strcpy( Book2.title, "C Tutorial ");
strcpy( Book2.author, "Wind T ");
strcpy( Book2.subject, "C Tutorial ");
Book2.book_id = 1234568;
/* print Book1 info */
printBook( Book1 );
/* Print Book2 info */
printBook( Book2 );
return 0;
}
void printBook( struct Books book )
{
printf( "Book title : %s\n", book.title);
printf( "Book author : %s\n", book.author);
printf( "Book subject : %s\n", book.subject);
printf( "Book book_id : %d\n", book.book_id);
}

| Pointers to Structures |

You can pass a structure as a function argument in very similar way as you pass any other variable or pointer. You would access structure variables in the similar way as you have accessed in the above example:

#include <stdio.h>
#include <string.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};

/* function declaration */
void printBook( struct Books *book );
int main( )
{
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */
/* book 1 specification */
strcpy( Book1.title, "C Tutorial ");
strcpy( Book1.author, "Wind T ");
strcpy( Book1.subject, "C Tutorial");
Book1.book_id = 1234567;
/* book 2 specification */
strcpy( Book2.title, "C Tutorial1 ");
strcpy( Book2.author, "Wind T ");
strcpy( Book2.subject, "C Tutorial1");
Book2.book_id = 1234568;
/* print Book1 info by passing address of Book1 */
printBook( &Book1 );
/* print Book2 info by passing address of Book2 */
printBook( &Book2 );
return 0;
}
void printBook( struct Books *book )
{
printf( "Book title : %s\n", book->title);
printf( "Book author : %s\n", book->author);
printf( "Book subject : %s\n", book->subject);
printf( "Book book_id : %d\n", book->book_id);
}

| Bit Fields |

Bit Fields allow the packing of data in a structure. This is especially useful when memory or data storage is at a premium.

struct packed_struct {
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int my_int:9;
} pack;

Here the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4 bit type and a 9 bit my_int. C automatically packs the above bit fields as compactly as possible, provided that the maximum length of the field is less than or equal to the integer word length of the computer. If this is not the case then some compilers may allow memory overlap for the fields whilst other would store the next field in the next word.

Recursion in C

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| Recursion in C |

Recursion is the process of repeating items in a self-similar way. Same applies in programming languages as well where if a programming allows you to call a function inside the same function that is called recursive call of the function as follows.

void recursion()
{
recursion(); /* function calls itself */
}
int main()
{
recursion();
}

The C programming language supports recursion ie. a function to call itself. But while using recursion, programmers need to be careful to define an exit condition from the function, otherwise it will go in infinite loop.

Recursive function are very useful to solve many mathematical problems like to calculate factorial of a number, generating fibonacci series etc.

| Factorial |

Following is an example which calculate factorial for a given number using a recursive function:

#include <stdio.h>
int factorial(unsigned int i)
{
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1);
}
int main()
{
int i = 15;
printf("Factorial of %d is %d\n", i, factorial(i));
return 0;
}

| Fibonacci Series |

Following is another example which generates fibonacci series for a given number using a recursive function:

#include <stdio.h>
int fibonaci(int i)
{
if(i == 0)
{
return 0;
}
if(i == 1)
{
return 1;
}
return fibonaci(i-1) + fibonaci(i-2);
}
int main()
{
int i;
for (i = 0; i < 10; i++)
{
printf("%d\t%n", fibonaci(i));
}
return 0;
}

C Preprocessor

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| C Preprocessor |

The C Preprocessor is not part of the compiler, but is a separate step in the compilation process. In simplistic terms, a C Preprocessor is just a text substitution tool and they instruct compiler to do required pre-processing before actual compilation. We'll refer to the C Preprocessor as the CPP.

All preprocessor commands begin with a pound symbol (#). It must be the first nonblank character, and for readability, a preprocessor directive should begin in first column. Following section lists down all important preprocessor directives:

Directive Description
#define Substitutes a preprocessor macro
#include Inserts a particular header from another file
#undef Undefines a preprocessor macro
#ifdef Returns true if this macro is defined
#ifndef Returns true if this macro is not defined
#if Tests if a compile time condition is true
#else The alternative for #if
#elif #else an #if in one statement
#endif Ends preprocessor conditional
#error Prints error message on stderr
#pragma Issues special commands to the compiler, using a standardized method

 

| Preprocessor examples |

#define MAX_ARRAY_LENGTH 20

This directive tells the CPP to replace instances of MAX_ARRAY_LENGTH with 20. Use #define for constants to increase readability.

#include <stdio.h>
#include "myheader.h"

These directives tell the CPP to get stdio.h from System Libraries and add the text to the current source file. The next line tells CPP to get myheader.h from the local directory and add the content to the current source file.

#undef FILE_SIZE
#define FILE_SIZE 42

This tells the CPP to undefine existing FILE_SIZE and define it as 42.

#ifndef MESSAGE
#define MESSAGE "We wish!"
#endif

This tells the CPP to define MESSAGE only if MESSAGE isn't already defined.

#ifdef DEBUG
/* Your debugging statements here */
#endif

This tells the CPP to do the process the statements enclosed if DEBUG is defined. This is useful if you pass the -DDEBUG flag to gcc compiler at the time of compilation. This will define DEBUG, so you can turn debugging on and off on the fly during compilation.

| Predefined Macros |

ANSI C defines a number of macros. Although each one is available for your use in programming, the predefined macros should not be directly modified.

Macro Description
__DATE__ The current date as a character literal in "MMM DD YYYY" format
__TIME__ The current time as a character literal in "HH:MM:SS" format
__FILE__ This contains the current filename as a string literal.
__LINE__ This contains the current line number as a decimal constant.
__STDC__ Defined as 1 when the compiler complies with the ANSI standard.

Let's try the following example:

#include <stdio.h>
main()
{
printf("File :%s\n", __FILE__ );
printf("Date :%s\n", __DATE__ );
printf("Time :%s\n", __TIME__ );
printf("Line :%d\n", __LINE__ );
printf("ANSI :%d\n", __STDC__ );
}

| Preprocessor Operators |

The C preprocessor offers following operators to help you in creating macros:

Macro Continuation (\)

A macro usually must be contained on a single line. The macro continuation operator is used to continue a macro that is too long for a single line. For example:

#define message_for(a, b) \
printf(#a " and " #b ": World Wide Web!\n")

Stringize (#)

The stringize or number-sign operator ('#'), when used within a macro definition, converts a macro parameter into a string constant. This operator may be used only in a macro that has a specified argument or parameter list. For example:

#include <stdio.h>
#define message_for(a, b) \
printf(#a " and " #b ": World Wide Web!\n")
int main(void)
{
message_for(Wind, Trainers);
return 0;
}

Token Pasting (##)

The token-pasting operator (##) within a macro definition combines two arguments. It permits two separate tokens in the macro definition to be joined into a single token. For example:

#include <stdio.h>
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
int main(void)
{
int token34 = 40;
tokenpaster(34);
return 0;
}

The defined() Operator

The preprocessor defined operator is used in constant expressions to determine if an identifier is defined using #define. If the specified identifier is defined, the value is true (non-zero). If the symbol is not defined, the value is false (zero). The defined operator is specified as follows:

#include <stdio.h>
#if !defined (MESSAGE)
#define MESSAGE "Wind T !"
#endif
int main(void)
{
printf("Here is the message: %s\n", MESSAGE);
return 0;
}

| Parameterized Macros |

One of the powerful functions of the CPP is the ability to simulate functions using parameterized macros. For example, we might have some code to square a number as follows:

int square(int x)
{
return x * x;
}

We can rewrite above code using a macro as follows:

#define square(x) ((x) * (x))

Macros with arguments must be defined using the #define directive before they can be used. The argument list is enclosed in parentheses and must immediately follow the macro name. Spaces are not allowed between and macro name and open parenthesis. For example:

#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int main(void)
{
printf("Max between 20 and 10 is %d\n", MAX(10, 20));
return 0;
}

Pointers in C

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| Pointers in C |


A pointer is a variable whose value is the address of another variable ie. direct address of the memory location. Like any variable or constant, you must declare a pointer before you can use it to store any variable address. The general form of a pointer variable declaration is:

type *varname;

Here, type is the pointer's base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * you used to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Following are the valid pointer declaration:

int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */

The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

| Using Pointer |



#include <stdio.h>
int main ()
{
int var = 20; /* actual variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
printf("Address of var variable: %x\n", &var );
/* address stored in pointer variable */
printf("Address stored in ip variable: %x\n", ip );
/* access the value using the pointer */
printf("Value of *ip variable: %d\n", *ip );
return 0;
}

| NULL Pointer |

It is always a good practice to assign a NULL value to a pointer variable in case you do not have exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned NULL is called a null pointer. The NULL pointer is a constant with a value of zero defined in several standard libraries. Consider the following program:

#include <stdio.h>
int main ()
{
int *ptr = NULL;
printf("The value of ptr is : %x\n", ptr );
return 0;
}

On most of the operating systems, programs are not permitted to access memory at address 0 because that memory is reserved by the operating system. However, the memory address 0 has special significance; it signals that the pointer is not intended to point to an accessible memory location. Pointers have many but easy concepts and they are very important to C programming. There are following few important pointer concepts which should be clear to a C programmer:

1. There are four arithmetic operators that can be used on pointers: ++, --, +, -.
2. We can define arrays to hold a number of pointers.
3. C allows you to have pointer on a pointer and so on.
4. Passing an argument by reference or by address both enable the passed argument to be changed in the calling function by the called function.
5. C allows a function to return a pointer to local variable, static variable and dynamically allocated memory as well.

Operators in C

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| Operators |

An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations.

1. Arithmetic Operators
2. Relational Operators
3. Logical Operators
4. Bitwise Operators
5. Assigment Operator
6. Misc Operators

| Arithmetic Operators |


Operator
Description
Example
+
Addition
a+b
-
Subtraction
a-b
*
Mulitplication
a*b
/
Division
a/b
%
Modulus
a%b
++
Increment Operator
++a, a++
--
Decrement Operator
--a, a--

 


| Relational Operators |


Operator
Description
Example
==
Checks if the value of two operands is equal or not, if yes then condition becomes true.
a==b
!=
Checks if the value of two operands is equal or not, if values are not equal then condition becomes true.
a!=b
>
Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.
a>b
<
Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.
a<b
>=
Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.
a>=b
<=
Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.
a<=b

| Logical Operators |



Operator
Description
Example
&&
Called Logical AND operator. If both the operands are non zero then condition becomes true.
a&&b
||
Called Logical OR Operator. If any of the two operands is non zero then condition becomes true.
a||b
!
Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.
!(a&&b)


| Bitwise Operators |


Operator
Description
Example
&
Binary AND Operator copies a bit to the result if it exists in both operands.
a&b
|
Binary OR Operator copies a bit if it exists in either operand.
a|b
^
Binary XOR Operator copies the bit if it is set in one operand but not both.
a ^ b
~
Binary Ones Complement Operator is unary and has the effect of 'flipping' bits.
~ a
<<
Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.
a << 2
>>
Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.
a >> 2

| Assignment Operators |


Operator
Description
Example
=
Simple assignment operator, Assigns values from right side operands to left side operand
a=5

| Misc Operators |


Operator
Description
Example
sizeof()
Returns the size of an variable.
sizeof(a)
&
Returns the address of an variable.
&a;
*
Pointer to a variable.
*a;
? :
Conditional Expression
If a>b? a:b;

Memory Management in C

Welcome to Wind Trainers :: Trainers, C, Tutorials, Programming, Java, VB.net, C++, ANSI, Learn C, Learn Programming
Forum | Contact

C Tutorials


| Memory Management |


The C programming language provides several functions for memory allocation and management. These functions can be found in the <stdlib.h> header file.

S.N. Function and Description
1 void *calloc(int num, int size);
This function allocates an array of num elements each of which size in bytes will be size.
2 void free(void *address);
This function release a block of memory block specified by address.
3 void *malloc(int num);
This function allocates an array of num bytes and leave them initialized.
4 void *realloc(void *address, int newsize);
This function re-allocates memory extending it upto newsize.

 

| Allocating Memory Dynamically |

While doing programming, if you are aware about the size of an array, then it is easy and you can define it as an array. For example to store a name of any person, it can go max 100 characters so you can define something as follows:

char name[100];

But now let us consider a situation where you have no idea about the length of the text you need to store, for example you want to store a detailed description about a topic. Here we need to define a pointer to character without defining how much memory is required and later based on requirement we can allocate memory as shown in the below example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[100];
char *description;
strcpy(name, "Wind T");
/* allocate memory dynamically */
description = malloc( 200 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Wind Trainers is a Tutorial Website ");
}
printf("Name = %s\n", name );
printf("Description: %s\n", description );
}

| Resizing and Releasing Memory |

When our program comes out, operating system automatically release all the memory allocated by our program but as a good practice when you are not in need of memory anymore then we should release that memory by calling the function free().

Alternatively, we can increase or decrease the size of an allocated memory block by calling the function realloc(). Let us check the above program once again and make use of realloc() and free() functions:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[100];
char *description;
strcpy(name, "Wind T");
/* allocate memory dynamically */
description = malloc( 30 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Wind Trainers.");
}
/* suppose you want to store bigger description */
description = realloc( description, 100 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcat( description, "Wind Trainers - Online Training ");
}
printf("Name = %s\n", name );
printf("Description: %s\n", description );
/* release memory using free() function */
free(description);
}