Needs To U

Thursday, February 17, 2011

C FULL


                       Full C                                          



1.   C  Tutorial
2.   C  Interview questions
3.   C  Aptitude Questions 1
4.    C  Aptitude Questions 2




















                          C TUTORIAL (fully c)
The C is a general-purpose, procedural, imperative computer programming language developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system.
C is the most widely used computer language.
This tutorial should be your starting point only.
Control Statements :
Branching
Looping
Structured Datatypes :
Structure
Pointer to Structure
Working with Files :
Files
Basic I/O

C Programming Tutorials

Basic Introduction
C is a general-purpose high level language that was originally developed by Dennis Ritchie for the Unix operating system. It was first implemented on the Digital Equipment Corporation PDP-11 computer in 1972.

The Unix operating system and virtually all Unix applications are written in the C language. C has now become a widely used professional language for various reasons.
·         Easy to learn
·         Structured language
·         It produces efficient programs.
·         It can handle low-level activities.
·         It can be compiled on a variety of computers.
Facts about C
·         C was invented to write an operating system called UNIX.
·         C is a successor of B language which was introduced around 1970
·         The language was formalized in 1988 by the American National Standard Institute (ANSI).
·         By 1973 UNIX OS almost totally written in C.
·         Today C is the most widely used System Programming Language.
·         Most of the state of the art software have been implemented using C
Why to use C ?
C was initially used for system development work, in particular the programs that make-up the operating system. C was adopted as a system development language because it produces code that runs nearly as fast as code written in assembly language. Some examples of the use of C might be:
·         Operating Systems
·         Language Compilers
·         Assemblers
·         Text Editors
·         Print Spoolers
·         Network Drivers
·         Modern Programs
·         Data Bases
·         Language Interpreters
·         Utilities
C Program File
All the C programs are written into text files with extension ".c" for example hello.c. You can use "vi" editor to write your C program into a file.

This tutorial assumes that you know how to edit a text file and how to write programming instructions inside a program file.
C Compilers
When you write any program in C language then to run that program you need to compile that program using a C Compiler which converts your program into a language understandable by a computer. This is called machine language (ie. binary format). So before proceeding, make sure you have C Compiler available at your computer. It comes along with all flavors of Unix and Linux.

If you are working over Unix or Linux then you can type gcc -v or cc -v and check the result. You can ask your system administrator or you can take help from anyone to identify an available C Compiler at your computer.

If you don't have C compiler installed at your computer then you can use below given link to download a GNU C Compiler and use it.
Program Structure
A C program basically has the following form:
·         Preprocessor Commands
·         Functions
·         Variables
·         Statements & Expressions
·         Comments
The following program is written in the C programming language. Open a text file hello.c using vi editor and put the following lines inside that file.
#include <stdio.h>

int main()
{
/* My first program */
printf("Hello, TechPreparation! \n");

return 0;
}
Preprocessor Commands:
These commands tells the compiler to do preprocessing before doing actual compilation. Like #include <stdio.h> is a preprocessor command which tells a C compiler to include stdio.h file before going to actual compilation. You will learn more about C Preprocessors in C Preprocessors session.
Functions:
Functions are main building blocks of any C Program. Every C Program will have one or more functions and there is one mandatory function which is called main() function. This function is prefixed with keyword int which means this function returns an integer value when it exits. This integer value is returned using return statement.

The C Programming language provides a set of built-in functions. In the above example printf() is a C built-in function which is used to print anything on the screen.
Variables:
Variables are used to hold numbers, strings and complex data for manipulation. You will learn in detail about variables in C Variable Types.
Statements & Expressions :
Expressions combine variables and constants to create new values. Statements are expressions, assignments, function calls, or control flow statements which make up C programs.
Comments:
Comments are used to give additional useful information inside a C Program. All the comments will be put inside /*...*/ as given in the example above. A comment can span through multiple lines.




  • %i - int (same as %d)
  • %lf - double
  • %c - char
  • %s - string
  • %x - hexadecimal

Note the followings
·         C is a case sensitive programming language. It means in C printf and Printf will have different meanings.
·         C has a free-form line structure. End of each C statement must be marked with a semicolon.
·         Multiple statements can be one the same line.
·         White Spaces (ie tab space and space bar ) are ignored.
·         Statements can continue over multiple lines.
C Program Compilation
To compile a C program you would have to Compiler name and program files name. Assuming your compiler's name is cc and program file name is hello.c, give following command at Unix prompt.
$cc hello.c
This will produce a binary file called a.out and an object file hello.o in your current directory. Here a.out is your first program which you will run at Unix prompt like any other system program. If you don't like the name a.out then you can produce a binary file with your own name by using -o option while compiling C program. See an example below
$cc -o hello hello.c
Now you will get a binary with name hello. Execute this program at Unix prompt but before executing / running this program make sure that it has execute permission set. If you don't know what is execute permission then just follow these two steps
$chmod 755 hello
$./hello

This will produce following result
Hello, TechPreparation!
Congratulations!! you have written your first program in "C". Now believe me its not difficult to learn "C".
Basic Datatypes
C has a concept of 'data types' which are used to define a variable before its use. The definition of a variable will assign storage for the variable and define the type of data that will be held in the location.

The value of a variable can be changed any time.

C has the following basic built-in datatypes.
·         int
·         float
·         double
·         char
Please note that there is not a Boolean data type. C does not have the traditional view about logical comparison, but that's another story.
int - data type
int is used to define integer numbers.
 {
int Count;
Count = 5;
}
float - data type
float is used to define floating point numbers.
 {
float Miles;
Miles = 5.6;
}
double - data type
double is used to define BIG floating point numbers. It reserves twice the storage for the number. On PCs this is likely to be 8 bytes.
 {
double Atoms;
Atoms = 2500000;
}
char - data type
char defines characters.
 {
char Letter;
Letter = 'x';
}
Modifiers
The data types explained above have the following modifiers.
·         short
·         long
·         signed
·         unsigned
The modifiers define the amount of storage allocated to the variable. The amount of storage allocated is not cast in stone. ANSI has the following rules:
 short int <= int <= long int
float <= double <= long double
What this means is that a 'short int' should assign less than or the same amount of storage as an 'int' and the 'int' should be less or the same bytes than a 'long int'. What this means in the real world is:
 Type
Bytes
Range

short int
2
-32,768 -> +32,767
(32kb)
unsigned short int
2
0 -> +65,535
(64Kb)
unsigned int
4
0 -> +4,294,967,295
( 4Gb)
int
4
-2,147,483,648 -> +2,147,483,647
( 2Gb)
long int
4
-2,147,483,648 -> +2,147,483,647
( 2Gb)
signed char
1
-128 -> +127

unsigned char
1
0 -> +255

float
4


double
8


long double
12


These figures only apply to today's generation of PCs. Mainframes and midrange machines could use different figures, but would still comply with the rule above.

You can find out how much storage is allocated to a data type by using the sizeof operator discussed in Operator Types Session.

Here is an example to check size of memory taken by various datatypes.
int
main()
{
printf("sizeof(char) == %d\n", sizeof(char));
printf("sizeof(short) == %d\n", sizeof(short));
printf("sizeof(int) == %d\n", sizeof(int));
printf("sizeof(long) == %d\n", sizeof(long));
printf("sizeof(float) == %d\n", sizeof(float));
printf("sizeof(double) == %d\n", sizeof(double));
printf("sizeof(long double) == %d\n", sizeof(long double));
printf("sizeof(long long) == %d\n", sizeof(long long));

return 0;
}
Qualifiers
A type qualifier is used to refine the declaration of a variable, a function, and parameters, by specifying whether:
·         The value of a variable can be changed.
·         The value of a variable must always be read from memory rather than from a register
Standard C language recognizes the following two qualifiers:
·         const
·         volatile
The const qualifier is used to tell C that the variable value can not change after initialization.
const float pi=3.14159;

Now pi cannot be changed at a later time within the program.

Another way to define constants is with the #define preprocessor which has the advantage that it does not use any storage

The volatile qualifier declares a data type that can have its value changed in ways outside the control or detection of the compiler (such as a variable updated by the system clock or by another program). This prevents the compiler from optimizing code referring to the object by storing the object's value in a register and re-reading it from there, rather than from memory, where it may have changed. You will use this qualifier once you will become expert in "C". So for now just proceed.
What are Arrays:
We have seen all basic data types. In C language it is possible to make arrays whose elements are basic types. Thus we can make an array of 10 integers with the declaration.
int x[10];
The square brackets mean subscripting; parentheses are used only for function references. Array indexes begin at zero, so the elements of x are:

Thus Array are special type of variables which can be used to store multiple values of same data type. Those values are stored and accessed using subscript or index.

Arrays occupy consecutive memory slots in the computer's memory.
x[0], x[1], x[2], ..., x[9]
If an array has n elements, the largest subscript is n-1.

Multiple-dimension arrays are provided. The declaration and use look like:
int name[10] [20];
n = name[i+j] [1] + name[k] [2];
Subscripts can be arbitrary integer expressions. Multi-dimension arrays are stored by row so the rightmost subscript varies fastest. In above example name has 10 rows and 20 columns.

Same way, arrays can be defined for any data type. Text is usually kept as an array of characters. By convention in C, the last character in a character array should be a `\0' because most programs that manipulate character arrays expect it. For example, printf uses the `\0' to detect the end of a character array when printing it out with a `%s'.

Here is a program which reads a line, stores it in a buffer, and prints its length (excluding the newline at the end).
 main( )
{
int n, c;
char line[100];
n = 0;
while( (c=getchar( )) != '\n' )
{
if( n < 100 )
line[n] = c;
n++;
}
printf("length = %d\n", n);
}
Array Initialization
·         As with other declarations, array declarations can include an optional initialization
·         Scalar variables are initialized with a single value
·         Arrays are initialized with a list of values
·         The list is enclosed in curly braces
int array [8] = {2, 4, 6, 8, 10, 12, 14, 16};
The number of initializes cannot be more than the number of elements in the array but it can be less in which case, the remaining elements are initialized to 0.if you like, the array size can be inferred from the number of initializes by leaving the square brackets empty so these are identical declarations:
int array1 [8] = {2, 4, 6, 8, 10, 12, 14, 16};
int array2 [] = {2, 4, 6, 8, 10, 12, 14, 16};
An array of characters ie string can be initialized as follows:
char string[10] = "Hello";
Variable Types
A variable is just a named area of storage that can hold a single value (numeric or character). The C language demands that you declare the name of each variable that you are going to use and its type, or class, before you actually try to do anything with it.

The Programming language C has two main variable types
·         Local Variables
·         Global Variables
Local Variables
·         Local variables scope is confined within the block or function where it is defined. Local variables must always be defined at the top of a block.
·         When a local variable is defined - it is not initialized by the system, you must initialize it yourself.
·         When execution of the block starts the variable is available, and when the block ends the variable 'dies'.
Check following example's output
 main()
{
int i=4;
int j=10;

i++;

if (j > 0)
{
/* i defined in 'main' can be seen */
printf("i is %d\n",i);
}

if (j > 0)
{
/* 'i' is defined and so local to this block */
int i=100;
printf("i is %d\n",i);
}/* 'i' (value 100) dies here */

printf("i is %d\n",i); /* 'i' (value 5) is now visable.*/
}

This will generate following output
i is 5
i is 100
i is 5
Here ++ is called incremental operator and it increase the value of any integer variable by 1. Thus i++ is equivalent to i = i + 1;

You will see -- operator also which is called decremental operator and it decrease the value of any integer variable by 1. Thus i-- is equivalent to i = i - 1;
Global Variables
Global variable is defined at the top of the program file and it can be visible and modified by any function that may reference it.

Global variables are initialized automatically by the system when you define them!
Data Type
Initialser
int
0
char
'\0'
float
0
pointer
NULL
If same variable name is being used for global and local variable then local variable takes preference in its scope. But it is not a good practice to use global variables and local variables with the same name.
int i=4;                 /* Global definition */

main()
{
i++;                     /* Global variable */
func();
printf( "Value of i = %d -- main function\n", i );
}

func()
{
int i=10;               /* Local definition */
i++;                      /* Local variable */
printf( "Value of i = %d -- func() function\n", i );
}

This will produce following result
Value of i = 11 -- func() function
Value of i = 5 -- main function
i in main function is global and will be incremented to 5. i in func is internal and will be incremented to 11. When control returns to main the internal variable will die and and any reference to i will be to the global.
Storage Classes
A storage class defines the scope (visibility) and life time of variables and/or functions within a C Program.

There are following storage classes which can be used in a C Program
·         auto
·         register
·         static
·         extern
auto - Storage Class
auto is the default storage class for all local variables.
{
int Count;
auto int Month;
}
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
register 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 cant have the unary '&' operator applied to it (as it does not have a memory location).
{
register int Miles;
}
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. It means that it MIGHT be stored in a register - depending on hardware and implementation restrictions.
static - Storage Class
static is the default storage class for global variables. The two variables below (count and road) both have a static storage class.
static int Count;
int Road;

{
printf("%d\n", Road);
}
static variables can be 'seen' within all functions in this source file. At link time, the static variables defined here will not be seen by the object modules that are brought in.

static can also be defined within a function. If this is done the variable is initialized at run time but is not reinitialized when the function is called. This inside a function static variable retains its value during various calls.
 void func(void);

static count=10;   /* Global variable - static is the default */

main()
{
while (count--)
{
func();
}

}

void func( void )
{
static i = 5;
i++;
printf("i is %d and count is %d\n", i, count);
}

This will produce following result

i is 6 and count is 9
i is 7 and count is 8
i is 8 and count is 7
i is 9 and count is 6
i is 10 and count is 5
i is 11 and count is 4
i is 12 and count is 3
i is 13 and count is 2
i is 14 and count is 1
i is 15 and count is 0
static variables can be 'seen' within all functions in this source file. At link time, the static variables defined here will not be seen by the object modules that are brought in.

static can also be defined within a function. If this is done the variable is initialized at run time but is not reinitialized when the function is called. This inside a function static variable retains its value during various calls.
 void func(void);

static count=10;    /* Global variable - static is the default */

main()
{
while (count--)
{
func();
}

}

void func( void )
{
static i = 5;
i++;
printf("i is %d and count is %d\n", i, count);
}

This will produce following result

i is 6 and count is 9
i is 7 and count is 8
i is 8 and count is 7
i is 9 and count is 6
i is 10 and count is 5
i is 11 and count is 4
i is 12 and count is 3
i is 13 and count is 2
i is 14 and count is 1
i is 15 and count is 0
NOTE : Here keyword void means function does not return anything and it does not take any parameter. You can memories void as nothing. static variables are initialized to 0 automatically.
Definition vs. Declaration :
Before proceeding, let us understand the difference between definition and declaration of a variable or function. Definition means where a variable or function is defined in reality and actual memory is allocated for variable or function. Declaration means just giving a reference of a variable and function. Through declaration we assure to the complier that this variable or function has been defined somewhere else in the program and will be provided at the time of linking. In the above examples char *func(void) has been put at the top which is a declaration of this function where as this function has been defined below to main() function.

There is one more very important use for 'static'. Consider this bit of code.
char *func(void);

main()
{
char *Text1;
Text1 = func();
}

char *func(void)
{
char Text2[10]="martin";
return(Text2);
}
Now, 'func' returns a pointer to the memory location where 'text2' starts BUT text2 has a storage class of 'auto' and will disappear when we exit the function and could be overwritten but something else. The answer is to specify
 static char Text[10]="martin";
The storage assigned to 'text2' will remain reserved for the duration if the program.
extern - Storage Class
extern is used to give a reference of a global variable that is visible to ALL the program files. When you 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 you 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.

File 1: main.c
int count=5;

main()
{
write_extern();
}
File 2: write.c
void write_extern(void);

extern int count;

void write_extern(void)
{
printf("count is %i\n", count);
}
Here extern keyword is being used to declare count in another file.

Now compile these two files as follows
 gcc main.c write.c -o write
This fill produce write program which can be executed to produce result.

Count in 'main.c' will have a value of 5. If main.c changes the value of count - write.c will see the new value
Using Constants
A C constant is usually just the written version of a number. For example 1, 0, 5.73, 12.5e9. We can specify our constants in octal or hexadecimal, or force them to be treated as long integers.
·         Octal constants are written with a leading zero - 015.
·         Hexadecimal constants are written with a leading 0x - 0x1ae.
·         Long constants are written with a trailing L - 890L.
Character constants are usually just the character enclosed in single quotes; 'a', 'b', 'c'. Some characters can't be represented in this way, so we use a 2 character sequence as follows.
'\n'
newline
'\t'
tab
'\\'
backslash
'\''
single quote
'\0'
null ( Used automatically to terminate character string )
In addition, a required bit pattern can be specified using its octal equivalent.

'\044' produces bit pattern 00100100.

Character constants are rarely used, since string constants are more convenient. A string constant is surrounded by double quotes eg "Brian and Dennis". The string is actually stored as an array of characters. The null character '\0' is automatically placed at the end of such a string to act as a string terminator.

A character is a different type to a single character string. This is important point to note.
Defining Constants
ANSI C allows you to declare constants. When you declare a constant it is a bit like a variable declaration except the value cannot be changed.

The const keyword is to declare a constant, as shown below:
int const a = 1;
const int a =2;
Note:
You can declare the const before or after the type. Choose one an stick to it.
It is usual to initialize a const with a value as it cannot get a value any other way.
The preprocessor #define is another more flexible (see Preprocessor Chapters) method to define constants in a program.
#define TRUE            1
#define FALSE           0
#define NAME_SIZE   20
Here TRUE, FALSE and NAME_SIZE are constant

You frequently see const declaration in function parameters. This says simply that the function is not going to change the value of the parameter.

The following function definition used concepts we have not met (see chapters on functions, strings, pointers, and standard libraries) but for completeness of this section it is is included here:
void strcpy(char *buffer, char const *string)
The enum Data type
enum is the abbreviation for ENUMERATE, and we can use this keyword to declare and initialize a sequence of integer constants. Here's an example:
enum colors {RED, YELLOW, GREEN, BLUE};
I've made the constant names uppercase, but you can name them which ever way you want.

Here, colors is the name given to the set of constants - the name is optional. Now, if you don't assign a value to a constant, the default value for the first one in the list - RED in our case, has the value of 0. The rest of the undefined constants have a value 1 more than the one before, so in our case, YELLOW is 1, GREEN is 2 and BLUE is 3.

But you can assign values if you wanted to:
enum colors {RED=1, YELLOW, GREEN=6, BLUE };
Now RED=1, YELLOW=2, GREEN=6 and BLUE=7.

The main advantage of enum is that if you don't initialize your constants, each one would have a unique value. The first would be zero and the rest would then count upwards.

You can name your constants in a weird order if you really wanted...
#include <stdio.h>

int main() {
enum {RED=5, YELLOW, GREEN=4, BLUE};

printf("RED = %d\n", RED);
printf("YELLOW = %d\n", YELLOW);
printf("GREEN = %d\n", GREEN);
printf("BLUE = %d\n", BLUE);
return 0;
}

This will produce following results

RED = 5
YELLOW = 6
GREEN = 4
BLUE = 5
Operator Types
What is Operator? Simple answer can be given using expression 4 + 5 is equal to 9. Here 4 and 5 are called operands and + is called operator. C language supports following type of operators.
·         Arithmetic Operators
·         Logical (or Relational) Operators
·         Bitwise Operators
·         Assignment Operators
·         Misc Operators
Lets have a look on all operators one by one.
Arithmetic Operators:
There are following arithmetic operators supported by C language:

Assume variable A holds 10 and variable holds 20 then:
Show Examples
Operator
Description
Example
+
Adds two operands
A + B will give 30
-
Subtracts second operand from the first
A - B will give -10
*
Multiply both operands
A * B will give 200
/
Divide numerator by denominator
B / A will give 2
%
Modulus Operator and remainder of after an integer division
B % A will give 0
++
Increment operator, increases integer value by one
A++ will give 11
--
Decrement operator, decreases integer value by one
A-- will give 9
Logical (or Relational) Operators:
There are following logical operators supported by C language

Assume variable A holds 10 and variable holds 20 then:
Show Examples
Operator
Description
Example
==
Checks if the value of two operands is equal or not, if yes then condition becomes true.
(A == B) is not true.
!=
Checks if the value of two operands is equal or not, if values are not equal then condition becomes true.
(A != B) is true.
> 
Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.
(A > B) is not true.
< 
Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.
(A < B) is true.
>=
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) is not true.
<=
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) is true.
&&
Called Logical AND operator. If both the operands are non zero then then condition becomes true.
(A && B) is true.
||
Called Logical OR Operator. If any of the two operands is non zero then then condition becomes true.
(A || B) is true.
!
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) is false.
Bitwise Operators:
Bitwise operator works on bits and perform bit by bit operation.

Assume if B = 60; and B = 13; Now in binary format they will be as follows:

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1000

A|B = 0011 1101

A^B = 0011 0001

~A = 1100 0011
Show Examples
There are following Bitwise operators supported by C language
Operator
Description
Example
&
Binary AND Operator copies a bit to the result if it exists in both operands.
(A & B) will give 12 which is 0000 1100
|
Binary OR Operator copies a bit if it exists in either operand.
(A | B) will give 61 which is 0011 1101
^
Binary XOR Operator copies the bit if it is set in one operand but not both.
(A ^ B) will give 49 which is 0011 0001
~
Binary Ones Complement Operator is unary and has the effect of 'flipping' bits.
(~A ) will give -60 which is 1100 0011
<< 
Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.
A << 2 will give 240 which is 1111 0000
>> 
Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.
A >> 2 will give 15 which is 0000 1111
Assignment Operators:
There are following assignment operators supported by C language:
Show Examples
Operator
Description
Example
=
Simple assignment operator, Assigns values from right side operands to left side operand
C = A + B will assign value of A + B into C
+=
Add AND assignment operator, It adds right operand to the left operand and assign the result to left operand
C += A is equivalent to C = C + A
-=
Subtract AND assignment operator, It subtracts right operand from the left operand and assign the result to left operand
C -= A is equivalent to C = C - A
*=
Multiply AND assignment operator, It multiplies right operand with the left operand and assign the result to left operand
C *= A is equivalent to C = C * A
/=
Divide AND assignment operator, It divides left operand with the right operand and assign the result to left operand
C /= A is equivalent to C = C / A
%=
Modulus AND assignment operator, It takes modulus using two operands and assign the result to left operand
C %= A is equivalent to C = C % A
<<=
Left shift AND assignment operator
C <<= 2 is same as C = C << 2
>>=
Right shift AND assignment operator
C >>= 2 is same as C = C >> 2
&=
Bitwise AND assignment operator
C &= 2 is same as C = C & 2
^=
bitwise exclusive OR and assignment operator
C ^= 2 is same as C = C ^ 2
|=
bitwise inclusive OR and assignment operator
C |= 2 is same as C = C | 2
Short Notes on L-VALUE and R-VALUE:
x = 1; takes the value on the right (e.g. 1) and puts it in the memory referenced by x. Here x and 1 are known as L-VALUES and R-VALUES respectively L-values can be on either side of the assignment operator where as R-values only appear on the right.

So x is an L-value because it can appear on the left as we've just seen, or on the right like this: y = x; However, constants like 1 are R-values because 1 could appear on the right, but 1 = x; is invalid.
Misc Operators
There are few other operators supported by C Language.
Show Examples
Operator
Description
Example
sizeof()
Returns the size of an variable.
sizeof(a), where a is integer, will return 4.
&
Returns the address of an variable.
&a; will give actual address of the variable.
*
Pointer to a variable.
*a; will pointer to a variable
? :
Conditional Expression
If Condition is true ? Then value X : Otherwise value Y
Operators Categories:
All the operators we have discussed above can be categorized into following categories:
·         Postfix operators, which follow a single operand.
·         Unary prefix operators, which precede a single operand.
·         Binary operators, which take two operands and perform a variety of arithmetic and logical operations.
·         The conditional operator (a ternary operator), which takes three operands and evaluates either the second or third expression, depending on the evaluation of the first expression.
·         Assignment operators, which assign a value to a variable.
·         The comma operator, which guarantees left-to-right evaluation of comma-separated expressions.
Precedence of C Operators:
Operator precedence determines the grouping of terms in an expression. This affects how an expression is evaluated. Certain operators have higher precedence than others; for example, the multiplication operator has higher precedence than the addition operator:

For example x = 7 + 3 * 2; Here x is assigned 13, not 20 because operator * has higher precedence than + so it first get multiplied with 3*2 and then adds into 7.

Here operators with the highest precedence appear at the top of the table, those with the lowest appear at the bottom. Within an expression, higher precedence operators will be evaluated first.
Category
Operator
Associativity
Postfix
() [] -> . ++ - -
Left to right
Unary
+ - ! ~ ++ - - (type) * & sizeof
Right to left
Multiplicative
* / %
Left to right
Additive
+ -
Left to right
Shift
<< >>
Left to right
Relational
< <= > >=
Left to right
Equality
== !=
Left to right
Bitwise AND
&
Left to right
Bitwise XOR
^
Left to right
Bitwise OR
|
Left to right
Logical AND
&&
Left to right
Logical OR
||
Left to right
Conditional
?:
Right to left
Assignment
= += -= *= /= %= >>= <<= &= ^= |=
Right to left
Comma
,
Left to right
Flow Control Statements
C provides two styles of flow control:
·         Branching
·         Looping
Branching is deciding what actions to take and looping is deciding how many times to take a certain action.
Branching:
Branching is so called because the program chooses to follow one branch or another.
if statement
This is the most simple form of the branching statements.

It takes an expression in parenthesis and an statement or block of statements. if the expression is true then the statement or block of statements gets executed otherwise these statements are skipped.

NOTE: Expression will be assumed to be true if its evaluated values is non-zero.

if statements take the following form:
Show Example
if (expression)
statement;

or

if (expression)
{
Block of statements;
}

or

if (expression)
{
Block of statements;
}
else
{
Block of statements;
}

or

if (expression)
{
Block of statements;
}
else if(expression)
{
Block of statements;
}
else
{
Block of statements;
}
? : Operator
The ? : operator is just like an if ... else statement except that because it is an operator you can use it within expressions.

? : is a ternary operator in that it takes three values, this is the only ternary operator C has.

? : takes the following form:
Show Example
if condition is true ? then X return value : otherwise Y value;
switch statement:
The switch statement is much like a nested if .. else statement. Its mostly a matter of preference which you use, switch statement can be slightly more efficient and easier to read.
Show Example
switch( expression )
{
case constant-expression1: statements1;
[case constant-expression2: statements2;]
[case constant-expression3: statements3;]
[default : statements4;]
}
Using break keyword:
If a condition is met in switch case then execution continues on into the next case clause also if it is not explicitly specified that the execution should exit the switch statement. This is achieved by using break keyword.
What is default condition:
If none of the listed conditions is met then default condition executed.
NEXT >> Looping
Looping
Loops provide a way to repeat commands and control how many times they are repeated. C provides a number of looping way.
while loop
The most basic loop in C is the while loop. A while statement is like a repeating if statement. Like an If statement, if the test condition is true: the statements get executed. The difference is that after the statements have been executed, the test condition is checked again. If it is still true the statements get executed again. This cycle repeats until the test condition evaluates to false.

Basic syntax of while loop is as follows:
Show Example
while ( expression )
{
Single statement
or
Block of statements;
}
for loop
for loop is similar to while, it's just written differently. for statements are often used to process lists such a range of numbers:

Basic syntax of for loop is as follows:
Show Example
for( expression1; expression2; expression3)
{
Single statement
or
Block of statements;
}
In the above syntax:
·         expression1 - Initializes variables.
·         expression2 - Conditional expression, as long as this condition is true, loop will keep executing.
·         expression3 - expression3 is the modifier which may be simple increment of a variable.
do...while loop
do ... while is just like a while loop except that the test condition is checked at the end of the loop rather than the start. This has the effect that the content of the loop are always executed at least once.

Basic syntax of do...while loop is as follows:
Show Example
do
{
Single statement
or
Block of statements;
}while(expression);
break and continue statements
C provides two commands to control how we loop:
·         break -- exit form loop or switch.
·         continue -- skip 1 iteration of loop.
You already have seen example of using break statement. Here is an example showing usage of continue statement.
#include

main()
{
int i;
int j = 10;

for( i = 0; i <= j; i ++ )
{
if( i == 5 )
{
continue;
}
printf("Hello %d\n", i );
}
}
This will produce following output:
Hello 0
Hello 1
Hello 2
Hello 3
Hello 4
Hello 6
Hello 7
Hello 8
Hello 9
Hello 10
Input and Output
Input : In any programming language input means to feed some data into program. This can be given in the form of file or from command line. C programming language provides a set of built-in functions to read given input and feed it to the program as per requirement.

Output : In any programming language output means to display some data on screen, printer or in any file. C programming language provides a set of built-in functions to output required data.
printf() function
This is one of the most frequently used functions in C for output. ( we will discuss what is function in subsequent chapter. ).

Try following program to understand printf() function.
#include <stdio.h>

main()
{
int dec = 5;
char str[] = "abc";
char ch = 's';
float pi = 3.14;

printf("%d %s %f %c\n", dec, str, pi, ch);
}
The output of the above would be:
 5 abc 3.140000 c
Here %d is being used to print an integer, %s is being usedto print a string, %f is being used to print a float and %c is being used to print a character.
scanf() function
This is the function which can be used to to read an input from the command line.

Try following program to understand scanf() function.
#include <stdio.h>

main()
{
int x;
int args;

printf("Enter an integer: ");
if (( args = scanf("%d", &x)) == 0)
{
printf("Error: not an integer\n");
} else {
printf("Read in %d\n", x);
}
}
Here %d is being used to read an integer value and we are passing &x to store the vale read input. Here &indicates the address of variable x.

This program will prompt you to enter a value. Whatever value you will enter at command prompt that will be output at the screen using printf() function. If you enter a non-integer value then it will display an error message.
Enter an integer: 20
Read in 20
Pointing to Data
A pointer is a special kind of variable. Pointers are designed for storing memory address i.e. the address of another variable. Declaring a pointer is the same as declaring a normal variable except you stick an asterisk '*' in front of the variables identifier.
·         There are two new operators you will need to know to work with pointers. The "address of" operator '&' and the "dereferencing" operator '*'. Both are prefix unary operators.
·         When you place an ampersand in front of a variable you will get it's address, this can be stored in a pointer variable.
·         When you place an asterisk in front of a pointer you will get the value at the memory address pointed to.
Here is an example to understand what I have stated above.
#include <stdio.h>

int main()
{
int my_variable = 6, other_variable = 10;
int *my_pointer;

printf("the address of my_variable is : %p\n", &my_variable);
printf("the address of other_variable is : %p\n", &other_variable);

my_pointer = &my_variable;

printf("\nafter \"my_pointer = &my_variable\":\n");
printf("\tthe value of my_pointer is %p\n", my_pointer);
printf("\tthe value at that address is %d\n", *my_pointer);

my_pointer = &other_variable;

printf("\nafter \"my_pointer = &other_variable\":\n");
printf("\tthe value of my_pointer is %p\n", my_pointer);
printf("\tthe value at that address is %d\n", *my_pointer);

return 0;
}
This will produce following result.
the address of my_variable is : 0xbfffdac4
the address of other_variable is : 0xbfffdac0

after "my_pointer = &my_variable":
the value of my_pointer is 0xbfffdac4
the value at that address is 6

after "my_pointer = &other_variable":
the value of my_pointer is 0xbfffdac0
the value at that address is 10
Pointers and Arrays
The most frequent use of pointers in C is for walking efficiently along arrays. In fact, in the implementation of an array, the array name represents the address of the zeroth element of the array, so you can't use it on the left side of an expression. For example:
 char *y;
char x[100];
y is of type pointer to character (although it doesn't yet point anywhere). We can make y point to an element of x by either of
 y = &x[0];
y = x;
Since x is the address of x[0] this is legal and consistent. Now `*y' gives x[0]. More importantly notice the following:
 *(y+1) gives x[1]
*(y+i) gives x[i]

and the sequence

y = &x[0];
y++;

leaves y pointing at x[1].
Pointer Arithmetic:
C is one of the few languages that allows pointer arithmetic. In other words, you actually move the pointer reference by an arithmetic operation. For example:
int x = 5, *ip = &x;

ip++;
On a typical 32-bit machine, *ip would be pointing to 5 after initialization. But ip++; increments the pointer 32-bits or 4-bytes. So whatever was in the next 4-bytes, *ip would be pointing at it.

Pointer arithmetic is very useful when dealing with arrays, because arrays and pointers share a special relationship in C.
Using Pointer Arithmetic With Arrays:
Arrays occupy consecutive memory slots in the computer's memory. This is where pointer arithmetic comes in handy - if you create a pointer to the first element, incrementing it one step will make it point to the next element.
#include <stdio.h>

int main() {
int *ptr;
int arrayInts[10] = {1,2,3,4,5,6,7,8,9,10};

ptr = arrayInts; /* ptr = &arrayInts[0]; is also fine */

printf("The pointer is pointing to the first ");
printf("array element, which is %d.\n", *ptr);
printf("Let's increment it.....\n");

ptr++;

printf("Now it should point to the next element,");
printf(" which is %d.\n", *ptr);
printf("But suppose we point to the 3rd and 4th: %d %d.\n",
*(ptr+1),*(ptr+2));

ptr+=2;

printf("Now skip the next 4 to point to the 8th: %d.\n",
*(ptr+=4));

ptr--;

printf("Did I miss out my lucky number %d?!\n", *(ptr++));
printf("Back to the 8th it is then..... %d.\n", *ptr);

return 0;
}
This will produce following result:
The pointer is pointing to the first array element, which is 1.
Let's increment it.....
Now it should point to the next element, which is 2.
But suppose we point to the 3rd and 4th: 3 4.
Now skip the next 4 to point to the 8th: 8.
Did I miss out my lucky number 7?!
Back to the 8th it is then..... 8.

See more examples on Pointers and Array

Modifying Variables Using Pointers:
You know how to access the value pointed to using the dereference operator, but you can also modify the content of variables. To achieve this, put the dereferenced pointer on the left of the assignment operator, as shown in this example, which uses an array:
#include <stdio.h>

int main() {
char *ptr;
char arrayChars[8] = {'F','r','i','e','n','d','s','\0'};

ptr = arrayChars;

printf("The array reads %s.\n", arrayChars);
printf("Let's change it..... ");

*ptr = 'f'; /* ptr points to the first element */

printf(" now it reads %s.\n", arrayChars);
printf("The 3rd character of the array is %c.\n",
*(ptr+=2));
printf("Let's change it again..... ");

*(ptr - 1) = ' ';

printf("Now it reads %s.\n", arrayChars);
return 0;
}
This will produce following result:
The array reads Friends.
Let's change it..... now it reads friends.
The 3rd character of the array is i.
Let's change it again..... Now it reads f iends.
Generic Pointers: ( void Pointer )
When a variable is declared as being a pointer to type void it is known as a generic pointer. Since you cannot have a variable of type void, the pointer will not point to any data and therefore cannot be dereferenced. It is still a pointer though, to use it you just have to cast it to another kind of pointer first. Hence the term Generic pointer. This is very useful when you want a pointer to point to data of different types at different times.

Try the following code to understand Generic Pointers.
#include <stdio.h>

int main()
{
int i;
char c;
void *the_data;

i = 6;
c = 'a';

the_data = &i;
printf("the_data points to the integer value %d\n",
*(int*) the_data);

the_data = &c;
printf("the_data now points to the character %c\n",
*(char*) the_data);

return 0;
}
NOTE-1 : Here in first print statement, the_data is prefixed by *(int*). This is called type casting in C language. Type is used to caste a variable from one data type to another datatype to make it compatible to the lvalue.

NOTE-2 : lvalue is something which is used to left side of a statement and in which we can assign some value. A constant can't be an lvalue because we can not assign any value in contact. For example x = y, here x is lvalue and y is rvalue.

However, above example will produce following result:
the_data points to the integer value 6
the_data now points to the character a

NEXT >> Using Functions

Using Functions
A function is a module or block of program code which deals with a particular task. Making functions is a way of isolating one block of code from other independent blocks of code.

Functions serve two purposes.
·         They allow a programmer to say: `this piece of code does a specific job which stands by itself and should not be mixed up with anything else',
·         Second they make a block of code reusable since a function can be reused in many different contexts without repeating parts of the program text.
A function can take a number of parameters, do required processing and then return a value. There may be a function which does not return any value.

You already have seen couple of built-in functions like printf(); Similar way you can define your own functions in C language.

Consider the following chunk of code
 int total = 10;
printf("Hello World");
total = total + l;
To turn it into a function you simply wrap the code in a pair of curly brackets to convert it into a single compound statement and write the name that you want to give it in front of the brackets:
Demo()
{
int total = 10;
printf("Hello World");
total = total + l;
}
curved brackets after the function's name are required. You can pass one or more parameters to a function as follows:
Demo( int par1, int par2)
{
int total = 10;
printf("Hello World");
total = total + l;
}
By default function does not return anything. But you can make a function to return any value as follows:
int Demo( int par1, int par2)
{
int total = 10;
printf("Hello World");
total = total + l;

return total;
}
A return keyword is used to return a value and datatype of the returned value is specified before the name of function. In this case function returns total which is int type. If a function does not return a value then void keyword can be used as return value.

Once you have defined your function you can use it within a program:
main()
{
Demo();
}
Functions and Variables:
Each function behaves the same way as C language standard function main(). So a function will have its own local variables defined. In the above example total variable is local to the function Demo.

A global variable can be accessed in any function in similar way it is accessed in main() function.

Declaration and Definition

Declaration and Definition
When a function is defined at any place in the program then it is called function definition. At the time of definition of a function actual logic is implemented with-in the function.

A function declaration does not have any body and they just have their interfaces.

A function declaration is usually declared at the top of a C source file, or in a separate header file.

A function declaration is sometime called function prototype or function signature. For the above Demo() function which returns an integer, and takes two parameters a function declaration will be as follows:
int Demo( int par1, int par2);
Passing Parameters to a Function
There are two ways to pass parameters to a function:
·         Pass by Value: mechanism is used when you don't want to change the value of passed parameters. When parameters are passed by value then functions in C create copies of the passed in variables and do required processing on these copied variables.
·         Pass by Reference mechanism is used when you want a function to do the changes in passed parameters and reflect those changes back to the calling function. In this case only addresses of the variables are passed to a function so that function can work directly over the addresses.
Here are two programs to understand the difference: First example is for Pass by value:
#include <stdio.h>

/* function declaration goes here.*/
void swap( int p1, int p2 );

int main()
{
int a = 10;
int b = 20;

printf("Before: Value of a = %d and value of b = %d\n", a, b );
swap( a, b );
printf("After: Value of a = %d and value of b = %d\n", a, b );
}

void swap( int p1, int p2 )
{
int t;

t = p2;
p2 = p1;
p1 = t;
printf("Value of a (p1) = %d and value of b(p2) = %d\n", p1, p2 );
}
Here is the result produced by the above example. Here the values of a and b remain unchanged before calling swap function and after calling swap function.
Before: Value of a = 10 and value of b = 20
Value of a (p1) = 20 and value of b(p2) = 10
After: Value of a = 10 and value of b = 20
Following is the example which demonstrate the concept of pass by reference
#include <stdio.h>

/* function declaration goes here.*/
void swap( int *p1, int *p2 );

int main()
{
int a = 10;
int b = 20;

printf("Before: Value of a = %d and value of b = %d\n", a, b );
swap( &a, &b );
printf("After: Value of a = %d and value of b = %d\n", a, b );
}

void swap( int *p1, int *p2 )
{
int t;

t = *p2;
*p2 = *p1;
*p1 = t;
printf("Value of a (p1) = %d and value of b(p2) = %d\n", *p1, *p2 );
}
Here is the result produced by the above example. Here the values of a and b are changes after calling swap function.
Before: Value of a = 10 and value of b = 20
Value of a (p1) = 20 and value of b(p2) = 10
After: Value of a = 20 and value of b = 10
NEXT >> Strings
Strings
·         In C language Strings are defined as an array of characters or a pointer to a portion of memory containing ASCII characters. A string in C is a sequence of zero or more characters followed by a NULL '\0' character:
·         It is important to preserve the NULL terminating character as it is how C defines and manages variable length strings. All the C standard library functions require this for successful operation.
·         All the string handling functions are prototyped in: string.h or stdio.h standard header file. So while using any string related function, don't forget to include either stdio.h or string.h. May be your compiler differs so please check before going ahead.
·         If you were to have an array of characters WITHOUT the null character as the last element, you'd have an ordinary character array, rather than a string constant.
·         String constants have double quote marks around them, and can be assigned to char pointers as shown below. Alternatively, you can assign a string constant to a char array - either with no size specified, or you can specify a size, but don't forget to leave a space for the null character!
char *string_1 = "Hello";
char string_2[] = "Hello";
char string_3[6] = "Hello";
Reading and Writing Strings:
One possible way to read in a string is by using scanf. However, the problem with this, is that if you were to enter a string which contains one or more spaces, scanf would finish reading when it reaches a space, or if return is pressed. As a result, the string would get cut off. So we could use the gets function

A gets takes just one argument - a char pointer, or the name of a char array, but don't forget to declare the array / pointer variable first! What's more, is that it automatically prints out a newline character, making the output a little neater.

A puts function is similar to gets function in the way that it takes one argument - a char pointer. This also automatically adds a newline character after printing out the string. Sometimes this can be a disadvantage, so printf could be used instead.
#include <stdio.h>

int main() {
char array1[50];
char *array2;

printf("Now enter another string less than 50");
printf(" characters with spaces: \n");
gets(array1);

printf("\nYou entered: ");
puts(array1);

printf("\nTry entering a string less than 50");
printf(" characters, with spaces: \n");
scanf("%s", array2);

printf("\nYou entered: %s\n", array2);

return 0;
}
This will produce following result:
Now enter another string less than 50 characters with spaces:
hello world

You entered: hello world

Try entering a string less than 50 characters, with spaces:
hello world

You entered: hello
String Manipulation Functions:
·         char *strcpy (char *dest, char *src);
Copy src string into dest string.
strcpy function
Synopsis:
#include <stdio.h>

char *strcpy (char *dest, char *src);
Description:
The strcpy function copies characters from src to dest up to and including the terminating null character.
Return Value
The strcpy function returns dest.
Example
#include <stdio.h>

int main()
{
char input_str[20];
char *output_str;

strcpy(input_str, "Hello");
printf("input_str: %s\n", input_str);

output_str = strcpy(input_str, "World");

printf("input_str: %s\n", input_str);
printf("output_str: %s\n", output_str);

return 0;
}
It will produce following result:
input_str: Hello
input_str: World
output_str: World

·         char *strncpy(char *string1, char *string2, int n);
Copy first n characters of string2 to stringl .
strncpy function
Synopsis:
#include <stdio.h>

char *strncpy (char *dest, char *src, int n);
Description:
The strcpy function copies n characters from src to dest up to and including the terminating null character if length of src is less than n.
Return Value
The strncpy function returns dest.
Example
#include <stdio.h>

int main() {
char input_str[20];
char *output_str;

strncpy(input_str, "Hello", 20);
printf("input_str: %s\n", input_str);

/* Reset string */
memset(input_str, '\0', sizeof( input_str ));

strncpy(input_str, "Hello", 2);
printf("input_str: %s\n", input_str);

/* Reset string */
memset(input_str, '\0', sizeof( input_str ));
output_str = strncpy(input_str, "World", 3);

printf("input_str: %s\n", input_str);
printf("output_str: %s\n", output_str);

return 0;
}
It will produce following result:
input_str: Hello
input_str: He
input_str: Wor
output_str: Wor

·         int strcmp(char *string1, char *string2);
Compare string1 and string2 to determine alphabetic order.
strcmp function
Synopsis:
#include <stdio.h>

int strcmp(char *string1, char *string2);
Description:
The strcmp function compares the contents of string1 and string2 and returns a value indicating their relationship.
Return Value
·         if Return value if < 0 then it indicates string1 is less than string2
·         if Return value if > 0 then it indicates string2 is less than string1
·         if Return value if = 0 then it indicates string1 is equal to string1
Example
#include <stdio.h>

int main() {
char string1[20];
char string2[20];

strcpy(string1, "Hello");
strcpy(string2, "Hellooo");
printf("Return Value is : %d\n", strcmp( string1, string2));

strcpy(string1, "Helloooo");
strcpy(string2, "Hellooo");
printf("Return Value is : %d\n", strcmp( string1, string2));

strcpy(string1, "Hellooo");
strcpy(string2, "Hellooo");
printf("Return Value is : %d\n", strcmp( string1, string2));

return 0;
}
It will produce following result:
Return Value is : -111
Return Value is : 111
Return Value is : 0

·         int strncmp(char *string1, char *string2, int n);
Compare first n characters of two strings.
strncmp function
Synopsis:
#include <stdio.h>

int strncmp(char *string1, char *string2, int n);
Description:
The strncmp function compares first n characters of string1 and string2 and returns a value indicating their relationship.
Return Value
·         if Return value if < 0 then it indicates string1 is less than string2
·         if Return value if > 0 then it indicates string2 is less than string1
·         if Return value if = 0 then it indicates string1 is equal to string1
Example
#include <stdio.h>

int main() {
char string1[20];
char string2[20];

strcpy(string1, "Hello");
strcpy(string2, "Hellooo");
printf("Return Value is : %d\n", strncmp( string1, string2, 4));

strcpy(string1, "Helloooo");
strcpy(string2, "Hellooo");
printf("Return Value is : %d\n", strncmp( string1, string2, 10));

strcpy(string1, "Hellooo");
strcpy(string2, "Hellooo");
printf("Return Value is : %d\n", strncmp( string1, string2, 20));

return 0;
}
It will produce following result:
Return Value is : 0
Return Value is : 111
Return Value is : 0

·         int strlen(char *string);
Determine the length of a string.
strlen function
Synopsis:
#include <stdio.h>

int strlen(char *src );
Description:
The strlen function calculates the length, in bytes, of src. This calculation does not include the null terminating character.
Return Value
The strlen function returns the length of src.
Example
#include <stdio.h>

int main() {
char string1[20];
char string2[20];

strcpy(string1, "Hello");
strcpy(string2, "Hellooo");

printf("Length of string1 : %d\n", strlen( string1 ));
printf("Length of string2 : %d\n", strlen( string2 ));

return 0;
}
It will produce following result:
Length of string1 : 5
Length of string2 : 7

·         char *strcat(char *dest, const char *src);
Concatenate string src to the string dest.
strcat function
Synopsis:
#include <stdio.h>

char *strcat(char *dest, const char *src);
Description:
The strcat function concatenates or appends src to dest. All characters from src are copied including the terminating null character.
Return Value
The strcat function returns dest.
Example
#include <stdio.h>

int main() {
char string1[20];
char string2[20];

strcpy(string1, "Hello");
strcpy(string2, "Hellooo");

printf("Returned String : %s\n", strcat( string1, string2 ));
printf("Concatenated String : %s\n", string1 );

return 0;
}
It will produce following result:
Returned String : HelloHellooo
Concatenated String : HelloHellooo

·         char *strncat(char *dest, const char *src, int n);
Concatenate n characters from string src to the string dest.
strncat function
Synopsis:
#include <stdio.h>

char *strncat(char *dest, const char *src, int n);
Description:
The strncat function concatenates or appends first n characters from src to dest. All characters from src are copied including the terminating null character.
Return Value
The strncat function returns dest.
Example
#include <stdio.h>

int main() {
char string1[20];
char string2[20];

strcpy(string1, "Hello");
strcpy(string2, "Hellooo");

printf("Returned String : %s\n", strncat( string1, string2, 4 ));
printf("Concatenated String : %s\n", string1 );

return 0;
}
It will produce following result:
Returned String : HelloHell
Concatenated String : HelloHell

·         char *strchr(char *string, int c);
Find first occurrence of character c in string.

strchr function
Synopsis:
#include <stdio.h>

char *strchr(char *string, int c);
Description:
The strchr function searches string for the first occurrence of c. The null character terminating string is included in the search.
Return Value
The strchr function returns a pointer to the first occurrence of character c in string or a null pointer if no matching character is found.
Example
#include <stdio.h>

int main()
{
char *s;
char buf [] = "This is a test";

s = strchr (buf, 't');

if (s != NULL)
printf ("found a 't' at %s\n", s);

return 0;
}
It will produce following result:
found a 't' at test




·         char *strrchr(char *string, int c);
Find last occurrence of character c in string.

strrchr function
Synopsis:
#include <stdio.h>

char *strrchr(char *string, int c);
Description:
The strrchr function searches string for the last occurrence of c. The null character terminating string is included in the search.
Return Value
The strrchr function returns a pointer to the last occurrence of character c in string or a null pointer if no matching character is found.
Example
#include <stdio.h>

int main()
{
char *s;
char buf [] = "This is a testing";

s = strrchr (buf, 't');

if (s != NULL)
printf ("found a 't' at %s\n", s);

return 0;
}
It will produce following result:
found a 't' at ting


·         char *strstr(char *string2, char string*1);
Find first occurrence of string string1 in string2.
strstr function
Synopsis:
#include <stdio.h>

char *strstr(char *string2, char string*1);
Description:
The strstr function locates the first occurrence of the string string1 in the string string2 and returns a pointer to the beginning of the first occurrence.
Return Value
The strstr function returns a pointer within string2 that points to a string identical to string1. If no such sub string exists in src a null pointer is returned.
Example
#include <stdio.h>

int main()
{
char s1 [] = "My House is small";
char s2 [] = "My Car is green";

printf ("Returned String 1: %s\n", strstr (s1, "House");
printf ("Returned String 2: %s\n", strstr (s2, "Car");
}
It will produce following result:
Returned String 1: House is small
Returned String 2: Car is green

·         char *strtok(char *s, const char *delim) ;
Parse the string s into tokens using delim as delimiter.
strtok function
Synopsis:
#include <stdio.h>

char *strtok(char *s, const char *delim) ;
Description:
A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.

On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of last token as the new starting location for scanning.

To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in separator (which becomes the beginning of the token). And then scans starting from this beginning of the token for the first character contained in separator, which becomes the end of the token.

This end of the token is automatically replaced by a null-character by the function, and the beginning of the token is returned by the function.
Return Value
·         A pointer to the last token found in string.
·         A null pointer is returned if there are no tokens left to retrieve.
Example
#include <stdio.h>

int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
It will produce following result:
Splitting string "- This, a sample string." into tokens:
This
a
sample
string

Structured Datatypes
·         A structure in C is a collection of items of different types. You can think of a structure as a "record" is in Pascal or a class in Java without methods.
·         Structures, or structs, are very useful in creating data structures larger and more complex than the ones we have discussed so far.
·         Simply you can group various built-in data types into a structure.
·         Object concepts was derived from Structure concept. You can achieve few object oriented goals using C structure but it is very complex.
Following is the example how how to define a structure.
struct student
{
char firstName[20];
char lastName[20];
char SSN[9];
float gpa;
};
Now you have a new datatype called student and you can use this datatype define your variables of student type:
struct student student_a, student_b;

or an array of students as

struct student students[50];
Another way to declare the same thing is:
struct {
char firstName[20];
char lastName[20];
char SSN[10];
float gpa;
} student_a, student_b;
All the variables inside an structure will be accessed using these values as student_a.firstName will give value of firstName variable. Similarly we can access other variables.
Structure Example:
Try out following example to understand the concept:
#include <stdio.h>
struct student {
char firstName[20];
char lastName[20];
char SSN[10];
float gpa;
};

main()
{
struct student student_a;

strcpy(student_a.firstName, "Deo");
strcpy(student_a.lastName, "Dum");
strcpy(student_a.SSN, "2333234" );
student_a.gpa = 2009.20;

printf( "First Name: %s\n", student_a.firstName );
printf( "Last Name: %s\n", student_a.lastName );
printf( "SNN : %s\n", student_a.SSN );
printf( "GPA : %f\n", student_a.gpa );
}
This will produce following results:
First Name: Deo
Last Name: Dum
SSN : 2333234
GPA : 2009.
Pointers to Structs:
Sometimes it is useful to assign pointers to structures (this will be evident in the next section with self-referential structures). Declaring pointers to structures is basically the same as declaring a normal pointer:
struct student *student_a;
To dereference, you can use the infix operator: ->.
printf("%s\n", student_a->SSN);
typedef Keyword
There is an easier way to define structs or you could "alias" types you create. For example:
typedef struct{
char firstName[20];
char lastName[20];
char SSN[10];
float gpa;
}student;
Now you can use student directly to define variables of student type without using struct keyword. Following is the example:
student student_a;
You can use typedef for non-structs:
typedef long int *pint32;

pint32 x, y, z;
x, y and z are all pointers to long ints
Unions Datatype
Unions are declared in the same fashion as structs, but have a fundamental difference. Only one item within the union can be used at any time, because the memory allocated for each item inside the union is in a shared memory location.

Here is how we define a Union
union Shape
{
int circle;
int triangle;
int ovel;
};
We use union in such case where only one condition will be applied and only one variable will be used.
Conclusion:
You can create arrays of structs.
Structs can be copied or assigned.
The & operator may be used with structs to show addresses.
Structs can be passed into functions. Structs can also be returned from functions.
Structs cannot be compared!
Structures can store non-homogenous data types into a single collection, much like an array does for common data (except it isn't accessed in the same manner).
Pointers to structs have a special infix operator: -> for dereferencing the pointer.
typedef can help you clear your code up and can help save some keystrokes.
Working with Files
When accessing files through C, the first necessity is to have a way to access the files. For C File I/O you need to use a FILE pointer, which will let the program keep track of the file being accessed. For Example:
FILE *fp;
To open a file you need to use the fopen function, which returns a FILE pointer. Once you've opened a file, you can use the FILE pointer to let the compiler perform input and output functions on the file.
FILE *fopen(const char *filename, const char *mode);
Here filename is string literal which you will use to name your file and mode can have one of the following values
w - open for writing (file need not exist)
a - open for appending (file need not exist)
r+ - open for reading and writing, start at beginning
w+ - open for reading and writing (overwrite file)
a+ - open for reading and writing (append if file exists)
Note that it's possible for fopen to fail even if your program is perfectly correct: you might try to open a file specified by the user, and that file might not exist (or it might be write-protected). In those cases, fopen will return 0, the NULL pointer.

Here's a simple example of using fopen:
FILE *fp;

fp=fopen("/home/techpreparation/test.txt", "r");
This code will open test.txt for reading in text mode. To open a file in a binary mode you must add a b to the end of the mode string; for example, "rb" (for the reading and writing modes, you can add the b either after the plus sign - "r+b" - or before - "rb+")

To close a function you can use the function:
int fclose(FILE *a_file);
fclose returns zero if the file is closed successfully.

An example of fclose is:
fclose(fp);
To work with text input and output, you use fprintf and fscanf, both of which are similar to their friends printf and scanf except that you must pass the FILE pointer as first argument.

Try out following example:
#include <stdio.h>

main()
{
FILE *fp;

fp = fopen("/tmp/test.txt", "w");
fprintf(fp, "This is testing...\n");
fclose(fp;);
}
This will create a file test.txt in /tmp directory and will write This is testing in that file.

Here is an example which will be used to read lines from a file:
#include <stdio.h>

main()
{
FILE *fp;
char buffer[20];

fp = fopen("/tmp/test.txt", "r");
fscanf(fp, "%s", buffer);
printf("Read Buffer: %s\n", %buffer );
flcose(fp;);

}
It is also possible to read (or write) a single character at a time--this can be useful if you wish to perform character-by-character input. The fgetc function, which takes a file pointer, and returns an int, will let you read a single character from a file:
int fgetc (FILE *fp);
The fgetc returns an int. What this actually means is that when it reads a normal character in the file, it will return a value suitable for storing in an unsigned char (basically, a number in the range 0 to 255). On the other hand, when you're at the very end of the file, you can't get a character value--in this case, fgetc will return "EOF", which is a constant that indicates that you've reached the end of the file.

The fputc function allows you to write a character at a time--you might find this useful if you wanted to copy a file character by character. It looks like this:
int fputc( int c, FILE *fp );
Note that the first argument should be in the range of an unsigned char so that it is a valid character. The second argument is the file to write to. On success, fputc will return the value c, and on failure, it will return EOF.
Binary I/O
There are following two functions which will be used for binary input and output:
size_t fread(void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);

size_t fwrite(const void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
Both of these functions deal with blocks of memories - usually arrays. Because they accept pointers, you can also use these functions with other data structures; you can even write structs to a file or a read struct into memory.
Bits Manipulation
Bit manipulation is the act of algorithmically manipulating bits or other pieces of data shorter than a byte. C language is very efficient in manipulating bits.

Here are following operators to perform bits manipulation:
Bitwise Operators:

Bitwise operator works on bits and perform bit by bit operation.

Assume if B = 60; and B = 13; Now in binary format they will be as follows:

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1000

A|B = 0011 1101

A^B = 0011 0001

~A = 1100 0011

Show Examples

There are following Bitwise operators supported by C language
Operator
Description
Example
&
Binary AND Operator copies a bit to the result if it exists in both operands.
(A & B) will give 12 which is 0000 1100
|
Binary OR Operator copies a bit if it exists in either operand.
(A | B) will give 61 which is 0011 1101
^
Binary XOR Operator copies the bit if it is set in one operand but not both.
(A ^ B) will give 49 which is 0011 0001
~
Binary Ones Complement Operator is unary and has the effect of 'flipping' bits.
(~A ) will give -60 which is 1100 0011
<< 
Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.
A << 2 will give 240 which is 1111 0000
>> 
Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.
A >> 2 will give 15 which is 0000 1111
The shift operators perform appropriate shift by operator on the right to the operator on the left. The right operator must be positive. The vacated bits are filled with zero.

For example: x << 2 shifts the bits in x by 2 places to the left.
if x = 00000010 (binary) or 2 (decimal)

then:
x >>= 2 => x = 00000000 or just 0 (decimal)

Also: if x = 00000010 (binary) or 2 (decimal)
then
x <<= 2 => x = 00001000 or 8 (decimal)
Therefore a shift left is equivalent to a multiplication by 2. Similarly a shift right is equal to division by 2. Shifting is much faster than actual multiplication (*) or division (/) by 2. So if you want fast multiplications or division by 2 use shifts.

To illustrate many points of bitwise operators let us write a function, Bitcount, that counts bits set to 1 in an 8 bit number (unsigned char) passed as an argument to the function.
int bitcount(unsigned char x)
{
int count;

for ( count=0; x != 0; x>>=1);
{
if ( x & 01)
count++;
}

return count;
}
This function illustrates many C program points:
·         for loop not used for simple counting operation.
·         x >>= 1 => x = x>> 1;
·         for loop will repeatedly shift right x until x becomes 0
·         use expression evaluation of x & 01 to control if
·         x & 01 masks of 1st bit of x if this is 1 then count++
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. Typical examples:
·         Packing several objects into a machine word. e.g. 1 bit flags can be compacted.
·         Reading external file formats -- non-standard file formats could be read in. E.g. 9 bit integers.
C allows us do this in a structure definition by putting :bit length after the variable. For example:
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.
Pre-Processors
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. We'll refer to the C Preprocessor as the CPP.

All preprocessor lines begin with #
·         The unconditional directives are:
#include - Inserts a particular header from another file
#define - Defines a preprocessor macro
#undef - Undefines a preprocessor macro
·         The conditional directives are:
#ifdef - If this macro is defined
#ifndef - If this macro is not defined
#if - Test if a compile time condition is true
#else - The alternative for #if
#elif - #else an #if in one statement
#endif - End preprocessor conditional
·         Other directives include:
# - Stringization, replaces a macro parameter with a string constant
## - Token merge, creates a single token from two adjacent ones
Pre-Processors Examples:
Analyze following examples to understand various directives
 #define MAX_ARRAY_LENGTH 20
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"
Tells the CPP to get stdio.h from System Libraries and add the text to this file. The next line tells CPP to get myheader.h from the local directory and add the text to the file.
 #undef FILE_SIZE
#define FILE_SIZE 42
Tells the CPP to undefined FILE_SIZE and define it for 42.
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif
Tells the CPP to define MESSAGE only if MESSAGE isn't defined already.
 #ifdef DEBUG
/* Your debugging statements here */
#endif
Tells the CPP to do the following statements if DEBUG is defined. This is useful if you pass the -DDEBUG flag to gcc. This will define DEBUG, so you can turn debugging on and off on the fly!
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.

When the stringize operator immediately precedes the name of one of the macro parameters, the parameter passed to the macro is enclosed within quotation marks and is treated as a string literal. For example:
#include <stdio.h>

#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")

int main(void)
{
message_for(Carole, Debra);
return 0;
}
This will produce following result using stringization macro message_for
Carole and Debra: We love you!
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.

If the name of a macro parameter used in the macro definition is immediately preceded or followed by the token-pasting operator, the macro parameter and the token-pasting operator are replaced by the value of the passed parameter. Text that is adjacent to the token-pasting operator that is not the name of a macro parameter is not affected. For example:
#define tokenpaster(n) printf ("token" #n " = %d", token##n)

tokenpaster(34);
This example results in the following actual output from the preprocessor:
printf ("token34 = %d", token34);
This example shows the concatenation of token##n into token34. Both the stringize and the token-pasting operators are used in this example.
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:
int square(int x)
{
return x * x;
}
We can instead rewrite this using a macro:
#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:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
Macro Caveats:
·         Macro definitions are not stored in the object file. They are only active for the duration of a single source file starting when they are defined and ending when they are undefined (using #undef), redefined, or when the end of the source file is found.
·         Macro definitions you wish to use in multiple source files may be defined in an include file which may be included in each source file where the macros are required.
·         When a macro with arguments is invoked, the macro processor substitutes the arguments into the macro body and then processes the results again for additional macro calls. This makes it possible, but confusing, to piece together a macro call from the macro body and from the macro arguments.
·         Most experienced C programmers enclose macro arguments in parentheses when they are used in the macro body. This technique prevents undesired grouping of compound expressions used as arguments and helps avoid operator precedence rules overriding the intended meaning of a macro.
·         While a macro may contain references to other macros, references to itself are not expanded. Self-referencing macros are a special feature of ANSI Standard C in that the self-reference is not interpreted as a macro call. This special rule also applies to indirectly self-referencing macros (or macros that reference themselves through another macro).
Useful Concepts
Error Reporting:
Many times it is useful to report errors in a C program. The standard library perror() is an easy to use and convenient function. It is used in conjunction with errno and frequently on encountering an error you may wish to terminate your program early. We will meet these concepts in other parts of the function reference chapter also.

void perror(const char *message) - produces a message on standard error output describing the last error encountered.

errno: - is a special system variable that is set if a system call cannot perform its set task. It is defined in #include <errno.h>.
Predefined Streams:
UNIX defines 3 predefined streams ie. virtual files
stdin, stdout, stderr
They all use text a the method of I/O. stdin and stdout can be used with files, programs, I/O devices such as keyboard, console, etc.. stderr always goes to the console or screen.

The console is the default for stdout and stderr. The keyboard is the default for stdin.
Dynamic Memory Allocation:
Dynamic allocation is a pretty unique feature to C. It enables us to create data types and structures of any size and length to suit our programs need within the program. We use dynamic memory allocation concept when we don't know how in advance about memory requirement.


There are following functions to use for dynamic memory manipulation:

void *calloc(size_t num elems, size_t elem_size) - Allocate an array and initialise all elements to zero .

void free(void *mem address) - Free a block of memory.

void *malloc(size_t num bytes) - Allocate a block of memory.

void *realloc(void *mem address, size_t newsize) - Reallocate (adjust size) a block of memory.
Command Line Arguments:
It is possible to pass arguments to C programs when they are executed. The brackets which follow main are used for this purpose. argc refers to the number of arguments passed, and argv[] is a pointer array which points to each argument which is passed to mainA simple example follows, which checks to see if a single argument is supplied on the command line when the program is invoked.
#include <stdio.>h
main( int argc, char *argv[] )
{
if( argc == 2 )
printf("The argument supplied is %s\n", argv[1]);
else if( argc > 2 )
printf("Too many arguments supplied.\n");
else
printf("One argument expected.\n");
}
Note that *argv[0] is the name of the program invoked, which means that *argv[1] is a pointer to the first argument supplied, and *argv[n] is the last argument. If no arguments are supplied, argc will be one. Thus for n arguments, argc will be equal to n + 1. The program is called by the command line:
$myprog argument1
More clearly, Suppose a program is compiled to an executable program myecho and that the program is executed with the following command.
$myeprog aaa bbb ccc
When this command is executed, the command interpreter calls the main() function of the myprog program with 4 passed as the argc argument and an array of 4 strings as the argv argument.
argv[0]  -  "myprog"
argv[1]  -  "aaa"
argv[2]  -  "bbb"
argv[3]  -  "ccc"
Multidimensional Arrays:
The array we used in the last example was a one dimensional array. Arrays can have more than one dimension, these arrays-of-arrays are called multidimensional arrays. They are very similar to standard arrays with the exception that they have multiple sets of square brackets after the array identifier. A two dimensional array can be though of as a grid of rows and columns.
#include <stdio.h>

const int num_rows = 7;
const int num_columns = 5;

int
main()
{
int box[num_rows][num_columns];
int row, column;

for(row = 0; row < num_rows; row++)
for(column = 0; column < num_columns; column++)
box[row][column] = column + (row * num_columns);

for(row = 0; row < num_rows; row++)
{
for(column = 0; column < num_columns; column++)
{
printf("%4d", box[row][column]);
}
printf("\n");
}
return 0;
}
This will produce following result:
 0    1    2    3    4
5     6    7    8    9
10  11  12  13  14
15  16  17  18  19
20  21  22  23  24
25  26  27  28  29
30  31  32  33  34
The above array has two dimensions and can be called a doubly subscripted array. GCC allows arrays of up to 29 dimensions although actually using an array of more than three dimensions is very rare.

     C Interview Questions

1.What is C language ?
The C programming language is a standardized programming language developed in the early 1970s by Ken Thompson and Dennis Ritchie for use on the UNIX operating system. It has since spread to many other operating systems, and is one of the most widely used programming languages. C is prized for its efficiency, and is the most popular programming language for writing system software, though it is also used for writing applications.
1.      What does static variable mean?
There are 3 main uses for the static.

1. If you declare within a function:
It retains the value between function calls

2.If it is declared for a function name:
By default function is extern..so it will be visible from other files if the function declaration is as static..it is invisible for the outer files

3. Static for global variables:
By default we can use the global variables from outside files If it is static global..that variable is limited to with in the file.
#include <stdio.h>

int t = 10;  

main(){

    int x = 0
    void funct1();
    funct1();            
    printf("After first call \n");
    funct1();            
    printf("After second call \n");
    funct1();            
    printf("After third call \n");

}
void funct1()
{
    static int y = 0;  
    int z = 10;             
    printf("value of y %d z %d",y,z);
    y=y+10;
}

value of y 0 z 10 After first call
      value of y 10 z 10 After second call
      value of y 20 z 10 After third call

2.      What are the different storage classes in C ?
C has three types of storage: automatic, static and allocated.

Variable having block scope and without static specifier have automatic storage duration.

Variables with block scope, and with static specifier have static scope. Global variables (i.e, file scope) with or without the the static specifier also have static scope.

Memory obtained from calls to malloc(), alloc() or realloc() belongs to allocated storage class.
3.      What is hashing ?
To hash means to grind up, and that’s essentially what hashing is all about. The heart of a hashing algorithm is a hash function that takes your nice, neat data and grinds it into some random-looking integer.

The idea behind hashing is that some data either has no inherent ordering (such as images) or is expensive to compare (such as images). If the data has no inherent ordering, you can’t perform comparison searches.

If the data is expensive to compare, the number of comparisons used even by a binary search might be too many. So instead of looking at the data themselves, you’ll condense (hash) the data to an integer (its hash value) and keep all the data with the same hash value in the same place. This task is carried out by using the hash value as an index into an array.

To search for an item, you simply hash it and look at all the data whose hash values match that of the data you’re looking for. This technique greatly lessens the number of items you have to look at. If the parameters are set up with care and enough storage is available for the hash table, the number of comparisons needed to find an item can be made arbitrarily close to one.

One aspect that affects the efficiency of a hashing implementation is the hash function itself. It should ideally distribute data randomly throughout the entire hash table, to reduce the likelihood of collisions. Collisions occur when two different keys have the same hash value.

There are two ways to resolve this problem. In open addressing, the collision is resolved by the choosing of another position in the hash table for the element inserted later. When the hash table is searched, if the entry is not found at its hashed position in the table, the search continues checking until either the element is found or an empty position in the table is found.

The second method of resolving a hash collision is called chaining. In this method, a bucket or linked list holds all the elements whose keys hash to the same value. When the hash table is searched, the list must be searched linearly.


4.      Can static variables be declared in a header file ?
You can’t declare a static variable without defining it as well (this is because the storage class modifiers static and extern are mutually exclusive). A static variable can be defined in a header file, but this would cause each source file that included the header file to have its own private copy of the variable, which is probably not what was intended.
5.      Can a variable be both constant and volatile ?
Yes. The const modifier means that this code cannot change the value of the variable, but that does not mean that the value cannot be changed by means outside this code. For instance, in the example in FAQ 8, the timer structure was accessed through a volatile const pointer.
The function itself did not change the value of the timer, so it was declared const. However, the value was changed by hardware on the computer, so it was declared volatile. If a variable is both const and volatile, the two modifiers can appear in either order.

6.      Can include files be nested?
Yes. Include files can be nested any number of times. As long as you use precautionary measures , you can avoid including the same file twice. In the past, nesting header files was seen as bad programming practice, because it complicates the dependency tracking function of the MAKE program and thus slows down compilation. Many of today’s popular compilers make up for this difficulty by implementing a concept called precompiled headers, in which all headers and associated dependencies are stored in a precompiled state.
Many programmers like to create a custom header file that has #include statements for every header needed for each module. This is perfectly acceptable and can help avoid potential problems relating to #include files, such as accidentally omitting an #include file in a module.


7.      What is a null pointer ?
There are times when it’s necessary to have a pointer that doesn’t point to anything. The macro NULL, defined in , has a value that’s guaranteed to be different from any valid pointer. NULL is a literal zero, possibly cast to void* or char*.
Some people, notably C++ programmers, prefer to use 0 rather than NULL.
The null pointer is used in three ways:
1) To stop indirection in a recursive data structure.
2) As an error value.
3) As a sentinel value.

8.      What is the output of printf("%d") ?
1. When we write printf("%d",x); this means compiler will print the value of x. But as here, there is nothing after %d so compiler will show in output window garbage value.
2. When we use %d the compiler internally uses it to access the argument in the stack (argument stack). Ideally compiler determines the offset of the data variable depending on the format specification string. Now when we write printf("%d",a) then compiler first accesses the top most element in the argument stack of the printf which is %d and depending on the format string it calculated to offset to the actual data variable in the memory which is to be printed. Now when only %d will be present in the printf then compiler will calculate the correct offset (which will be the offset to access the integer variable) but as the actual data object is to be printed is not present at that memory location so it will print what ever will be the contents of that memory location.
3. Some compilers check the format string and will generate an error without the proper number and type of arguments for things like printf(...) and scanf(...).
malloc()

9.      What is the difference between calloc() and malloc() ?
1. calloc(...) allocates a block of memory for an array of elements of a certain size. By default the block is initialized to 0. The total number of memory allocated will be (number_of_elements * size).
malloc(...) takes in only a single argument which is the memory required in bytes. malloc(...) allocated bytes of memory and not blocks of memory like calloc(...).
2. malloc(...) allocates memory blocks and returns a void pointer to the allocated space, or NULL if there is insufficient memory available.
calloc(...) allocates an array in memory with elements initialized to 0 and returns a pointer to the allocated space. calloc(...) calls malloc(...) in order to use the C++ _set_new_mode function to set the new handler mode.




10.  What is the difference between printf() and sprintf() ?
sprintf() writes data to the character array whereas printf(...) writes data to the standard output device.
11.  How to reduce a final size of executable ?
     Size of the final executable can be reduced using dynamic linking for libraries.
12.  Can you tell me how to check whether a linked list is circular ?
Create two pointers, and set both to the start of the list. Update each as follows:
while (pointer1) {
pointer1 = pointer1->next;
pointer2 = pointer2->next;
if (pointer2) pointer2=pointer2->next;
if (pointer1 == pointer2) {
print ("circular");
}
}

If a list is circular, at some point pointer2 will wrap around and be either at the item just before pointer1, or the item before that. Either way, its either 1 or 2 jumps until they meet.
13.  Advantages of a macro over a function ?
Macro gets to see the Compilation environment, so it can expand __ __TIME__ __FILE__ #defines. It is expanded by the preprocessor.

For example, you can’t do this without macros
#define PRINT(EXPR) printf( #EXPR “=%d\n”, EXPR)

PRINT( 5+6*7 ) // expands into printf(”5+6*7=%d”, 5+6*7 );

You can define your mini language with macros:
#define strequal(A,B) (!strcmp(A,B))

Macros are a necessary evils of life. The purists don’t like them, but without it no real work gets done.

14.  What is the difference between strings and character arrays ?
A major difference is: string will have static storage duration, whereas as a character array will not, unless it is explicity specified by using the static keyword.

Actually, a string is a character array with following properties:

* the multibyte character sequence, to which we generally call string, is used to initialize an array of static storage duration. The size of this array is just sufficient to contain these characters plus the terminating NUL character.

* it not specified what happens if this array, i.e., string, is modified.

* Two strings of same value[1] may share same memory area. For example, in the following declarations:

char *s1 = “Calvin and Hobbes”;
char *s2 = “Calvin and Hobbes”;

the strings pointed by s1 and s2 may reside in the same memory location. But, it is not true for the following:

char ca1[] = “Calvin and Hobbes”;
char ca2[] = “Calvin and Hobbes”;

[1] The value of a string is the sequence of the values of the contained characters, in order.

15.  Write down the equivalent pointer expression for referring the same element
a[i][j][k][l] ?
a[i] == *(a+i)
a[i][j] == *(*(a+i)+j)
a[i][j][k] == *(*(*(a+i)+j)+k)
a[i][j][k][l] == *(*(*(*(a+i)+j)+k)+l)
16.  Which bit wise operator is suitable for checking whether a particular bit is on or off ?
The bitwise AND operator. Here is an example:
enum {
KBit0 = 1,
KBit1,

KBit31,
};
if ( some_int & KBit24 )
printf ( “Bit number 24 is ON\n” );
else
printf ( “Bit number 24 is OFF\n” );


17.  Which bit wise operator is suitable for turning off a particular bit in a number ?
The bitwise AND operator, again. In the following code snippet, the bit number 24 is reset to zero.
some_int = some_int & ~KBit24;


18.  Which bit wise operator is suitable for putting on a particular bit in a number ?
The bitwise OR operator. In the following code snippet, the bit number 24 is turned ON:
some_int = some_int | KBit24;

19.  Does there exist any other function which can be used to convert an integer or a float to a string ?
Some implementations provide a nonstandard function called itoa(), which converts an integer to string.
#include

char *itoa(int value, char *string, int radix);
DESCRIPTION
The itoa() function constructs a string representation of an integer.
PARAMETERS
value:
Is the integer to be converted to string representation.

string:
Points to the buffer that is to hold resulting string.
The resulting string may be as long as seventeen bytes.

radix:
Is the base of the number; must be in the range 2 - 36.

A portable solution exists. One can use sprintf():
char s[SOME_CONST];
int i = 10;
float f = 10.20;

sprintf ( s, “%d %f\n”, i, f );


20.  Why does malloc(0) return valid memory address ? What's the use ?
malloc(0) does not return a non-NULL under every implementation.
An implementation is free to behave in a manner it finds
suitable, if the allocation size requested is zero. The
implmentation may choose any of the following actions:

* A null pointer is returned.

* The behavior is same as if a space of non-zero size
was requested. In this case, the usage of return
value yields to undefined-behavior.

Notice, however, that if the implementation returns a non-NULL
value for a request of a zero-length space, a pointer to object
of ZERO length is returned! Think, how an object of zero size
should be represented?

For implementations that return non-NULL values, a typical usage
is as follows:
void
func ( void )
{
int *p; /* p is a one-dimensional array,
whose size will vary during the
the lifetime of the program */
size_t c;

p = malloc(0); /* initial allocation */
if (!p)
{
perror (”FAILURE” );
return;
}

/* … */

while (1)
{
c = (size_t) … ; /* Calculate allocation size */
p = realloc ( p, c * sizeof *p );

/* use p, or break from the loop */
/* … */
}
return;
}
Notice that this program is not portable, since an implementation
is free to return NULL for a malloc(0) request, as the C Standard
does not support zero-sized objects.


21.  Difference between const char* p and char const* p
In const char* p, the character pointed by ‘p’ is constant, so u cant change the value of character pointed by p but u can make ‘p’ refer to some other location.
in char const* p, the ptr ‘p’ is constant not the character referenced by it, so u cant make ‘p’ to reference to any other location but u can change the value of the char pointed by ‘p’.



22.  What is the result of using Option Explicit ?
When writing your C program, you can include files in two ways.
The first way is to surround the file you want to include with the angled brackets < and >.
This method of inclusion tells the preprocessor to look for the file in the predefined default location.
This predefined default location is often an INCLUDE environment variable that denotes the path to your include files.
For instance, given the INCLUDE variable
INCLUDE=C:\COMPILER\INCLUDE;S:\SOURCE\HEADERS;
using the #include version of file inclusion, the compiler first checks the
C:\COMPILER\INCLUDE
directory for the specified file. If the file is not found there, the compiler then checks the
S:\SOURCE\HEADERS directory. If the file is still not found, the preprocessor checks the current directory.
The second way to include files is to surround the file you want to include with double quotation marks. This method of inclusion tells the preprocessor to look for the file in the current directory first, then look for it in the predefined locations you have set up. Using the #include file version of file inclusion and applying it to the preceding example, the preprocessor first checks the current directory for the specified file. If the file is not found in the current directory, the C:COMPILERINCLUDE directory is searched. If the file is still not found, the preprocessor checks the S:SOURCEHEADERS directory.
The #include method of file inclusion is often used to include standard headers such as stdio.h or
stdlib.h.
This is because these headers are rarely (if ever) modified, and they should always be read from your compiler’s standard include file directory.
The #include file method of file inclusion is often used to include nonstandard header files that you have created for use in your program. This is because these headers are often modified in the current directory, and you will want the preprocessor to use your newly modified version of the header rather than the older, unmodified version.
23.  What is the benefit of using an enum rather than a #define constant ?
The use of an enumeration constant (enum) has many advantages over using the traditional symbolic constant style of #define. These advantages include a lower maintenance requirement, improved program readability, and better debugging capability.
1) The first advantage is that enumerated constants are generated automatically by the compiler. Conversely, symbolic constants must be manually assigned values by the programmer.
For instance, if you had an enumerated constant type for error codes that could occur in your program, your enum definition could look something like this:
enum Error_Code
{
OUT_OF_MEMORY,
INSUFFICIENT_DISK_SPACE,
LOGIC_ERROR,
FILE_NOT_FOUND
};
In the preceding example, OUT_OF_MEMORY is automatically assigned the value of 0 (zero) by the compiler because it appears first in the definition. The compiler then continues to automatically assign numbers to the enumerated constants, making INSUFFICIENT_DISK_SPACE equal to 1, LOGIC_ERROR equal to 2, and FILE_NOT_FOUND equal to 3, so on.
If you were to approach the same example by using symbolic constants, your code would look something like this:
#define OUT_OF_MEMORY 0
#define INSUFFICIENT_DISK_SPACE 1
#define LOGIC_ERROR 2
#define FILE_NOT_FOUND 3
values by the programmer. Each of the two methods arrives at the same result: four constants assigned numeric values to represent error codes. Consider the maintenance required, however, if you were to add two constants to represent the error codes DRIVE_NOT_READY and CORRUPT_FILE. Using the enumeration constant method, you simply would put these two constants anywhere in the enum definition. The compiler would generate two unique values for these constants. Using the symbolic constant method, you would have to manually assign two new numbers to these constants. Additionally, you would want to ensure that the numbers you assign to these constants are unique.
2) Another advantage of using the enumeration constant method is that your programs are more readable and thus can be understood better by others who might have to update your program later.

3) A third advantage to using enumeration constants is that some symbolic debuggers can print the value of an enumeration constant. Conversely, most symbolic debuggers cannot print the value of a symbolic constant. This can be an enormous help in debugging your program, because if your program is stopped at a line that uses an enum, you can simply inspect that constant and instantly know its value. On the other hand, because most debuggers cannot print #define values, you would most likely have to search for that value by manually looking it up in a header file.



24.  What is the quickest sorting method to use ?
The answer depends on what you mean by quickest. For most sorting problems, it just doesn’t matter how quick the sort is because it is done infrequently or other operations take significantly more time anyway. Even in cases in which sorting speed is of the essence, there is no one answer. It depends on not only the size and nature of the data, but also the likely order. No algorithm is best in all cases.
There are three sorting methods in this author’s toolbox that are all very fast and that are useful in different situations. Those methods are quick sort, merge sort, and radix sort.
The Quick Sort
The quick sort algorithm is of the divide and conquer type. That means it works by reducing a sorting problem into several easier sorting problems and solving each of them. A dividing value is chosen from the input data, and the data is partitioned into three sets: elements that belong before the dividing value, the value itself, and elements that come after the dividing value. The partitioning is performed by exchanging elements that are in the first set but belong in the third with elements that are in the third set but belong in the first Elements that are equal to the dividing element can be put in any of the three setsthe algorithm will still work properly.
The Merge Sort
The merge sort is a divide and conquer sort as well. It works by considering the data to be sorted as a sequence of already-sorted lists (in the worst case, each list is one element long). Adjacent sorted lists are merged into larger sorted lists until there is a single sorted list containing all the elements. The merge sort is good at sorting lists and other data structures that are not in arrays, and it can be used to sort things that don’t fit into memory. It also can be implemented as a stable sort.
The Radix Sort
The radix sort takes a list of integers and puts each element on a smaller list, depending on the value of its least significant byte. Then the small lists are concatenated, and the process is repeated for each more significant byte until the list is sorted. The radix sort is simpler to implement on fixed-length data such as ints.


25.  When should the volatile modifier be used ?
The volatile modifier is a directive to the compiler’s optimizer that operations involving this variable should not be optimized in certain ways. There are two special cases in which use of the volatile modifier is desirable. The first case involves memory-mapped hardware (a device such as a graphics adaptor that appears to the computer’s hardware as if it were part of the computer’s memory), and the second involves shared memory (memory used by two or more programs running simultaneously).
Most computers have a set of registers that can be accessed faster than the computer’s main memory. A good compiler will perform a kind of optimization called redundant load and store removal. The compiler looks for places in the code where it can either remove an instruction to load data from memory because the value is already in a register, or remove an instruction to store data to memory because the value can stay in a register until it is changed again anyway.
If a variable is a pointer to something other than normal memory, such as memory-mapped ports on a peripheral, redundant load and store optimizations might be detrimental. For instance, here’s a piece of code that might be used to time some operation:
time_t time_addition(volatile const struct timer *t, int a)
{
int n;
int x;
time_t then;
x = 0;
then = t->value;
for (n = 0; n < 1000; n++)
{
x = x + a;
}
return t->value - then;
}
In this code, the variable t-> value is actually a hardware counter that is being incremented as time passes. The function adds the value of a to x 1000 times, and it returns the amount the timer was incremented by while the 1000 additions were being performed. Without the volatile modifier, a clever optimizer might assume that the value of t does not change during the execution of the function, because there is no statement that explicitly changes it. In that case, there’s no need to read it from memory a second time and subtract it, because the answer will always be 0.
The compiler might therefore optimize the function by making it always return 0.
If a variable points to data in shared memory, you also don’t want the compiler to perform redundant load and store optimizations. Shared memory is normally used to enable two programs to communicate with each other by having one program store data in the shared portion of memory and the other program read the same portion of memory. If the compiler optimizes away a load or store of shared memory, communication between the two programs will be affected.


26.  When should the register modifier be used? Does it really help ?
The register modifier hints to the compiler that the variable will be heavily used and should be kept in the CPU’s registers, if possible, so that it can be accessed faster.
There are several restrictions on the use of the register modifier.
First, the variable must be of a type that can be held in the CPU’s register. This usually means a single value of a size less than or equal to the size of an integer. Some machines have registers that can hold floating-point numbers as well.
Second, because the variable might not be stored in memory, its address cannot be taken with the unary & operator. An attempt to do so is flagged as an error by the compiler. Some additional rules affect how useful the register modifier is. Because the number of registers is limited, and because some registers can hold only certain types of data (such as pointers or floating-point numbers), the number and types of register modifiers that will actually have any effect are dependent on what machine the program will run on. Any additional register modifiers are silently ignored by the compiler.
Also, in some cases, it might actually be slower to keep a variable in a register because that register then becomes unavailable for other purposes or because the variable isn’t used enough to justify the overhead of loading and storing it.
So when should the register modifier be used? The answer is never, with most modern compilers. Early C compilers did not keep any variables in registers unless directed to do so, and the register modifier was a valuable addition to the language.
C compiler design has advanced to the point, however, where the compiler will usually make better decisions than the programmer about which variables should be stored in registers.
In fact, many compilers actually ignore the register modifier, which is perfectly legal, because it is only a hint and not a directive.

27.  How can you determine the size of an allocated portion of memory ?
You can’t, really. free() can , but there’s no way for your program to know the trick free() uses. Even if you disassemble the library and discover the trick, there’s no guarantee the trick won’t change with the next release of the compiler. 

28.  What is page thrashing ?
Some operating systems (such as UNIX or Windows in enhanced mode) use virtual memory. Virtual memory is a technique for making a machine behave as if it had more memory than it really has, by using disk space to simulate RAM (random-access memory).
In the 80386 and higher Intel CPU chips, and in most other modern microprocessors (such as the Motorola 68030, Sparc, and Power PC), exists a piece of hardware called the Memory Management Unit, or MMU.
The MMU treats memory as if it were composed of a series of pages. A page of memory is a block of contiguous bytes of a certain size, usually 4096 or 8192 bytes. The operating system sets up and maintains a table for each running program called the Process Memory Map, or PMM. This is a table of all the pages of memory that program can access and where each is really located.
Every time your program accesses any portion of memory, the address (called a virtual address) is processed by the MMU. The MMU looks in the PMM to find out where the memory is really located (called the physical address). The physical address can be any location in memory or on disk that the operating system has assigned for it. If the location the program wants to access is on disk, the page containing it must be read from disk into memory, and the PMM must be updated to reflect this action (this is called a page fault).
Because accessing the disk is so much slower than accessing RAM, the operating system tries to keep as much of the virtual memory as possible in RAM. If you’re running a large enough program (or several small programs at once), there might not be enough RAM to hold all the memory used by the programs, so some of it must be moved out of RAM and onto disk (this action is called paging out).
The operating system tries to guess which areas of memory aren’t likely to be used for a while (usually based on how the memory has been used in the past). If it guesses wrong, or if your programs are accessing lots of memory in lots of places, many page faults will occur in order to read in the pages that were paged out. Because all of RAM is being used, for each page read in to be accessed, another page must be paged out. This can lead to more page faults, because now a different page of memory has been moved to disk.
The problem of many page faults occurring in a short time, called page thrashing, can drastically cut the performance of a system. Programs that frequently access many widely separated locations in memory are more likely to cause page thrashing on a system. So is running many small programs that all continue to run even when you are not actively using them.
To reduce page thrashing, you can run fewer programs simultaneously. Or you can try changing the way a large program works to maximize the capability of the operating system to guess which pages won’t be needed. You can achieve this effect by caching values or changing lookup algorithms in large data structures, or sometimes by changing to a memory allocation library which provides an implementation of malloc() that allocates memory more efficiently. Finally, you might consider adding more RAM to the system to reduce the need to page out.


29.  When does the compiler not implicitly generate the address of the first element of an array ?
Whenever an array name appears in an expression such as
·         array as an operand of the sizeof operator
·         array as an operand of & operator
·         array as a string literal initializer for a character array
Then the compiler does not implicitly generate the address of the address of the first element of an array.


30.  What is the benefit of using #define to declare a constant ?
Using the #define method of declaring a constant enables you to declare a constant in one place and use it throughout your program. This helps make your programs more maintainable, because you need to maintain only the #define statement and not several instances of individual constants throughout your program.
For instance, if your program used the value of pi (approximately 3.14159) several times, you might want to declare a constant for pi as follows:
#define PI 3.14159
Using the #define method of declaring a constant is probably the most familiar way of declaring constants to traditional C programmers. Besides being the most common method of declaring constants, it also takes up the least memory.
Constants defined in this manner are simply placed directly into your source code, with no variable space allocated in memory. Unfortunately, this is one reason why most debuggers cannot inspect constants created using the #define method.

31.  How can I search for data in a linked list ?
Unfortunately, the only way to search a linked list is with a linear search, because the only way a linked list’s members can be accessed is sequentially.
Sometimes it is quicker to take the data from a linked list and store it in a different data structure so that searches can be more efficient.


32.  Why should we assign NULL to the elements (pointer) after freeing them ?
This is paranoia based on long experience. After a pointer has been freed, you can no longer use the pointed-to data. The pointer is said to dangle; it doesn’t point at anything useful.
If you NULL out or zero out a pointer immediately after freeing it, your program can no longer get in trouble by using that pointer. True, you might go indirect on the null pointer instead, but that’s something your debugger might be able to help you with immediately.
Also, there still might be copies of the pointer that refer to the memory that has been deallocated; that’s the nature of C. Zeroing out pointers after freeing them won’t solve all problems;


33.  What is a null pointer assignment error ? What are bus errors, memory faults, and core dumps ?

These are all serious errors, symptoms of a wild pointer or subscript.
Null pointer assignment is a message you might get when an MS-DOS program finishes executing. Some such programs can arrange for a small amount of memory to be available “where the NULL pointer points to (so to speak).
If the program tries to write to that area, it will overwrite the data put there by the compiler.
When the program is done, code generated by the compiler examines that area. If that data has been changed, the compiler-generated code complains with null pointer assignment.
This message carries only enough information to get you worried. There’s no way to tell, just from a null pointer assignment message, what part of your program is responsible for the error. Some debuggers, and some compilers, can give you more help in finding the problem.
Bus error: core dumped and Memory fault: core dumped are messages you might see from a program running under UNIX. They’re more programmer friendly. Both mean that a pointer or an array subscript was wildly out of bounds. You can get these messages on a read or on a write. They aren’t restricted to null pointer problems.
The core dumped part of the message is telling you about a file, called core, that has just been written in your current directory. This is a dump of everything on the stack and in the heap at the time the program was running. With the help of a debugger, you can use the core dump to find where the bad pointer was used.
That might not tell you why the pointer was bad, but it’s a step in the right direction. If you don’t have write permission in the current directory, you won’t get a core file, or the core dumped message

34.  When should a type cast be used ?
There are two situations in which to use a type cast. The first use is to change the type of an operand to an arithmetic operation so that the operation will be performed properly.
The second case is to cast pointer types to and from void * in order to interface with functions that expect or return void pointers.
For example, the following line type casts the return value of the call to malloc() to be a pointer to a foo structure.
struct foo *p = (struct foo *) malloc(sizeof(struct foo));

35.  What is the difference between a string copy (strcpy) and a memory copy (memcpy)? When should each be used?
The strcpy() function is designed to work exclusively with strings. It copies each byte of the source string to the destination string and stops when the terminating null character () has been moved.
On the other hand, the memcpy() function is designed to work with any type of data. Because not all data ends with a null character, you must provide the memcpy() function with the number of bytes you want to copy from the source to the destination.



The standard C library provides several functions for converting strings to numbers of all formats (integers, longs, floats, and so on) and vice versa.
The following functions can be used to convert strings to numbers:
Function Name Purpose
atof() Converts a string to a double-precision floating-point value.
atoi() Converts a string to an integer.
atol() Converts a string to a long integer.
strtod() Converts a string to a double-precision floating-point value and reports any leftover numbers that could not be converted.
strtol() Converts a string to a long integer and reports any leftover numbers that could not be converted.
strtoul() Converts a string to an unsigned long integer and reports any leftover numbers that could not be converted.


The standard C library provides several functions for converting numbers of all formats (integers, longs, floats, and so on) to strings and vice versa
The following functions can be used to convert integers to strings:
Function Name Purpose
itoa() Converts an integer value to a string.
ltoa() Converts a long integer value to a string.
ultoa() Converts an unsigned long integer value to a string.
The following functions can be used to convert floating-point values to strings:
Function Name Purpose
ecvt() Converts a double-precision floating-point value to a string without an embedded decimal point.
fcvt() Same as ecvt(), but forces the precision to a specified number of digits.
gcvt() Converts a double-precision floating-point value to a string with an embedded decimal point.


38.  Is it possible to execute code even after the program exits the main() function?
The standard C library provides a function named atexit() that can be used to perform cleanup operations when your program terminates.
You can set up a set of functions you want to perform automatically when your program exits by passing function pointers to the at exit() function.


39.  What is the stack ?
The stack is where all the functions’ local (auto) variables are created. The stack also contains some information used to call and return from functions.
A stack trace is a list of which functions have been called, based on this information. When you start using a debugger, one of the first things you should learn is how to get a stack trace.
The stack is very inflexible about allocating memory; everything must be deallocated in exactly the reverse order it was allocated in. For implementing function calls, that is all that’s needed. Allocating memory off the stack is extremely efficient. One of the reasons C compilers generate such good code is their heavy use of a simple stack.
There used to be a C function that any programmer could use for allocating memory off the stack. The memory was automatically deallocated when the calling function returned. This was a dangerous function to call; it’s not available anymore.


40.  How do you print an address ?
The safest way is to use printf() (or fprintf() or sprintf()) with the %P specification. That prints a void pointer (void*). Different compilers might print a pointer with different formats.
Your compiler will pick a format that’s right for your environment.
If you have some other kind of pointer (not a void*) and you want to be very safe, cast the pointer to a void*:
printf( %Pn, (void*) buffer );

41.  Can a file other than a .h file be included with #include ?
The preprocessor will include whatever file you specify in your #include statement. Therefore, if you have the line
#include
in your program, the file macros.inc will be included in your precompiled program. It is, however, unusual programming practice to put any file that does not have a .h or .hpp extension in an #include statement.
You should always put a .h extension on any of your C files you are going to include. This method makes it easier for you and others to identify which files are being used for preprocessing purposes.
For instance, someone modifying or debugging your program might not know to look at the macros.inc file for macro definitions. That person might try in vain by searching all files with .h extensions and come up empty.
If your file had been named macros.h, the search would have included the macros.h file, and the searcher would have been able to see what macros you defined in it.



42.  What is Preprocessor ?
The C preprocessor is used to modify your program according to the preprocessor directives in your source code. A preprocessor directive is a statement (such as #define) that gives the preprocessor specific instructions on how to modify your source code.
The preprocessor is invoked as the first part of your compiler program’s compilation step. It is usually hidden from the programmer because it is run automatically by the compiler.
The preprocessor reads in all of your include files and the source code you are compiling and creates a preprocessed version of your source code. This preprocessed version has all of its macros and constant symbols replaced by their corresponding code and value assignments.
If your source code contains any conditional preprocessor directives (such as #if), the preprocessor evaluates the condition and modifies your source code accordingly.


43.  How can you restore a redirected standard stream ?

The preceding example showed how you can redirect a standard stream from within your program. But what if later in your program you wanted to restore the standard stream to its original state?
By using the standard C library functions named dup() and fdopen(), you can restore a standard stream such as stdout to its original state.
The dup() function duplicates a file handle. You can use the dup() function to save the file handle corresponding to the stdout standard stream.
The fdopen() function opens a stream that has been duplicated with the dup() function.

44.  What is the purpose of realloc( ) ?
The function realloc(ptr,n) uses two arguments. the first argument ptr is a pointer to a block of memory for which the size is to be altered. The second argument n specifies the new size.
The size may be increased or decreased. If n is greater than the old size and if sufficient space is not available subsequent to the old region, the function realloc( ) may create a new region and all the old data are moved to the new region.


45.  What is the heap ?
The heap is where malloc(), calloc(), and realloc() get memory.
Getting memory from the heap is much slower than getting it from the stack. On the other hand, the heap is much more flexible than the stack. Memory can be allocated at any time and deallocated in any order. Such memory isn’t deallocated automatically; you have to call free().
Recursive data structures are almost always implemented with memory from the heap. Strings often come from there too, especially strings that could be very long at runtime.
If you can keep data in a local variable (and allocate it from the stack), your code will run faster than if you put the data on the heap. Sometimes you can use a better algorithm if you use the heap faster, or more robust, or more flexible.
It’s a tradeoff. If memory is allocated from the heap, it’s available until the program ends. That’s great if you remember to deallocate it when you’re done. If you forget, it’s a problem.
A memory leak is some allocated memory that’s no longer needed but isn’t deallocated. If you have a memory leak inside a loop, you can use up all the memory on the heap and not be able to get any more. (When that happens, the allocation functions return a null pointer.)
In some environments, if a program doesn’t deallocate everything it allocated, memory stays unavailable even after the program ends.



46.  How do you use a pointer to a function ?
The hardest part about using a pointer-to-function is declaring it.
Consider an example. You want to create a pointer, pf, that points to the strcmp() function.
The strcmp() function is declared in this way:
int strcmp(const char *, const char * )
To set up pf to point to the strcmp() function, you want a declaration that looks just like the strcmp() function’s declaration, but that has *pf rather than strcmp:
int (*pf)( const char *, const char * );
After you’ve gotten the declaration of pf, you can #include and assign the address of strcmp() to pf: pf = strcmp;


47.  What is the purpose of main( ) function ?
The function main( ) invokes other functions within it.It is the first function to be called when the program starts execution.
·         It is the starting function
·         It returns an int value to the environment that called the program
·         Recursive call is allowed for main( ) also.
·         It is a user-defined function
·         Program execution ends when the closing brace of the function main( ) is reached.
·         It has two arguments 1)argument count and 2) argument vector (represents strings passed).
·         Any user-defined name can also be used as parameters for main( ) instead of argc and argv


48.  Why n++ executes faster than n+1 ?
The expression n++ requires a single machine instruction such as INR to carry out the increment operation whereas, n+1 requires more instructions to carry out this operation.



49.  What will the preprocessor do for a program ?
The C preprocessor is used to modify your program according to the preprocessor directives in your source code. A preprocessor directive is a statement (such as #define) that gives the preprocessor specific instructions on how to modify your source code.
The preprocessor is invoked as the first part of your compiler program’s compilation step. It is usually hidden from the programmer because it is run automatically by the compiler.
The preprocessor reads in all of your include files and the source code you are compiling and creates a preprocessed version of your source code. This preprocessed version has all of its macros and constant symbols replaced by their corresponding code and value assignments.
If your source code contains any conditional preprocessor directives (such as #if), the preprocessor evaluates the condition and modifies your source code accordingly.


50.  What is the benefit of using const for declaring constants ?

The benefit of using the const keyword is that the compiler might be able to make optimizations based on the knowledge that the value of the variable will not change. In addition, the compiler will try to ensure that the values won’t be changed inadvertently.
Of course, the same benefits apply to #defined constants. The reason to use const rather than #define to define a constant is that a const variable can be of any type (such as a struct, which can’t be represented by a #defined constant).
Also, because a const variable is a real variable, it has an address that can be used, if needed, and it resides in only one place in memory

51.  What is the easiest sorting method to use ?
The answer is the standard library function qsort(). It’s the easiest sort by far for several reasons:
It is already written.
It is already debugged.
It has been optimized as much as possible (usually).
Void qsort(void *buf, size_t num, size_t size, int (*comp)(const void *ele1, const void *ele2));


52.  Is it better to use a macro or a function ?
The answer depends on the situation you are writing code for. Macros have the distinct advantage of being more efficient (and faster) than functions, because their corresponding code is inserted directly into your source code at the point where the macro is called.
There is no overhead involved in using a macro like there is in placing a call to a function. However, macros are generally small and cannot handle large, complex coding constructs.
A function is more suited for this type of situation. Additionally, macros are expanded inline, which means that the code is replicated for each occurrence of a macro. Your code therefore could be somewhat larger when you use macros than if you were to use functions.
Thus, the choice between using a macro and using a function is one of deciding between the tradeoff of faster program speed versus smaller program size. Generally, you should use macros to replace small, repeatable code sections, and you should use functions for larger coding tasks that might require several lines of code.



53.  What are the standard predefined macros ?
The ANSI C standard defines six predefined macros for use in the C language:
Macro Name Purpose
_ _LINE_ _ Inserts the current source code line number in your code.
_ _FILE_ _ Inserts the current source code filename in your code.
_ _ Inserts the current date of compilation in your code.
_ _TIME_ _ Inserts the current time of compilation in your code.
_ _STDC_ _ Is set to 1 if you are enforcing strict ANSI C conformity.
_ _cplusplus Is defined if you are compiling a C++ program.






  C APTITTUDE QUESTIONS

Predict the output or error(s) for the following:
1.    void main()
{
            int  const * p=5;
            printf("%d",++(*p));
}

Answer:
Compiler error: Cannot modify a constant value.
Explanation:   
p is a pointer to a "constant integer". But we tried to change the value of the "constant integer".
2.    main()
{
            char s[ ]="man";
            int i;
            for(i=0;s[ i ];i++)
            printf("\n%c%c%c%c",s[ i ],*(s+i),*(i+s),i[s]);
}

Answer:
                        mmmm
                       aaaa
                       nnnn
Explanation:
s[i], *(i+s), *(s+i), i[s] are all different ways of expressing the same idea. Generally  array name is the base address for that array. Here s is the base address. i is the index number/displacement from the base address. So, indirecting it with * is same as s[i]. i[s] may be surprising. But in the  case of  C  it is same as s[i].
3.      main()
{
            float me = 1.1;
            double you = 1.1;
            if(me==you)
printf("I love U");
else
                        printf("I hate U");
}

Answer:
I hate U

Explanation:
For floating point numbers (float, double, long double) the values cannot be predicted exactly. Depending on the number of bytes, the precession with of the value  represented varies. Float takes 4 bytes and long double takes 10 bytes. So float stores 0.9 with less precision than long double.
Rule of Thumb:
Never compare or at-least be cautious when using floating point numbers with relational operators (== , >, <, <=, >=,!= ) . 
4.      main()
            {
            static int var = 5;
            printf("%d ",var--);
            if(var)
                        main();
            }

Answer:
5 4 3 2 1

Explanation:
When static storage class is given, it is initialized once. The change in the value of a static variable is retained even between the function calls. Main is also treated like any other ordinary function, which can be called recursively. 
5.      main()
{
             int c[ ]={2.8,3.4,4,6.7,5};
             int j,*p=c,*q=c;
             for(j=0;j<5;j++) {
                        printf(" %d ",*c);
                        ++q;     }
             for(j=0;j<5;j++){
printf(" %d ",*p);
++p;     }
}

Answer:
                        2 2 2 2 2 2 3 4 6 5

Explanation:
Initially pointer c is assigned to both p and q. In the first loop, since only q is incremented and not c , the value 2 will be printed 5 times. In second loop p itself is incremented. So the values 2 3 4 6 5 will be printed.
6.      main()
{
            extern int i;
            i=20;
printf("%d",i);
}

Answer: 
Linker Error : Undefined symbol '_i'
Explanation:
                        extern storage class in the following declaration,
                                    extern int i;
specifies to the compiler that the memory for i is allocated in some other program and that address will be given to the current program at the time of linking. But linker finds that no other variable of name i is available in any other program with memory space allocated for it. Hence a linker error has occurred .
Predict the output or error(s) for the following:
7.      main()
{
            int i=-1,j=-1,k=0,l=2,m;
            m=i++&&j++&&k++||l++;
            printf("%d %d %d %d %d",i,j,k,l,m);
}

Answer:
                        0 0 1 3 1

Explanation :
Logical operations always give a result of 1 or 0 . And also the logical AND (&&) operator has higher priority over the logical OR (||) operator. So the expression  ‘i++ && j++ && k++’ is executed first. The result of this expression is 0    (-1 && -1 && 0 = 0). Now the expression is 0 || 2 which evaluates to 1 (because OR operator always gives 1 except for ‘0 || 0’ combination- for which it gives 0). So the value of m is 1. The values of other variables are also incremented by 1.
8.      main()
{
            char *p;
            printf("%d %d ",sizeof(*p),sizeof(p));
}

Answer:
                        1 2

Explanation:
The sizeof() operator gives the number of bytes taken by its operand. P is a character pointer, which needs one byte for storing its value (a character). Hence sizeof(*p) gives a value of 1. Since it needs two bytes to store the address of the character pointer sizeof(p) gives 2.
9.      main()
{
            int i=3;
            switch(i)
             {
                default:printf("zero");
                case 1: printf("one");
                           break;
               case 2:printf("two");
                          break;
              case 3: printf("three");
                          break;
              } 
}

Answer :
three

Explanation :
The default case can be placed anywhere inside the loop. It is executed only when all other cases doesn't match.
10.      main()
{
              printf("%x",-1<<4);
}

Answer:
fff0

Explanation :
-1 is internally represented as all 1's. When left shifted four times the least significant 4 bits are filled with 0's.The %x format specifier specifies that the integer value be printed as a hexadecimal value.
11.      main()
{
            char string[]="Hello World";
            display(string);
}
void display(char *string)
{
            printf("%s",string);
}

Answer:
Compiler Error : Type mismatch in redeclaration of function display

Explanation :
In third line, when the function display is encountered, the compiler doesn't know anything about the function display. It assumes the arguments and return types to be integers, (which is the default type). When it sees the actual function display, the arguments and type contradicts with what it has assumed previously. Hence a compile time error occurs.
12.      main()
{
            int c=- -2;
            printf("c=%d",c);
}

Answer:
                                    c=2;

Explanation:
Here unary minus (or negation) operator is used twice. Same maths  rules applies, ie. minus * minus= plus.
Note:
However you cannot give like --2. Because -- operator can  only be applied to variables as a decrement operator (eg., i--). 2 is a constant and not a variable.

13.      #define int char
main()
{
            int i=65;
            printf("sizeof(i)=%d",sizeof(i));
}

Answer:
                        sizeof(i)=1

Explanation:
Since the #define replaces the string  int by the macro char

14.      main()
{
int i=10;
i=!i>14;
Printf ("i=%d",i);
}

Answer:
i=0

Explanation:
In the expression !i>14 , NOT (!) operator has more precedence than ‘ >’ symbol.  ! is a unary logical operator. !i (!10) is 0 (not of true is false).  0>14 is false (zero).

15.      #include
main()
{
char s[]={'a','b','c','\n','c','\0'};
char *p,*str,*str1;
p=&s[3];
str=p;
str1=s;
printf("%d",++*p + ++*str1-32);
}

Answer:
77       

Explanation:
p is pointing to character '\n'. str1 is pointing to character 'a' ++*p. "p is pointing to '\n' and that is incremented by one." the ASCII value of '\n' is 10, which is then incremented to 11. The value of ++*p is 11. ++*str1, str1 is pointing to 'a' that is incremented by 1 and it becomes 'b'. ASCII value of 'b' is 98.
 Now performing (11 + 98 – 32), we get 77("M");
 So we get the output 77 :: "M" (Ascii is 77).
16.      #include
main()
{
int a[2][2][2] = { {10,2,3,4}, {5,6,7,8}  };
int *p,*q;
p=&a[2][2][2];
*q=***a;
printf("%d----%d",*p,*q);
}

Answer:
SomeGarbageValue---1

Explanation:
p=&a[2][2][2]  you declare only two 2D arrays, but you are trying to access the third 2D(which you are not declared) it will print garbage values. *q=***a starting address of a is assigned integer pointer. Now q is pointing to starting address of a. If you print *q, it will print first element of 3D array.
17.      #include
main()
{
struct xx
{
      int x=3;
      char name[]="hello";
 };
struct xx *s;
printf("%d",s->x);
printf("%s",s->name);
}

Answer:
Compiler Error

Explanation:
You should not initialize variables in declaration
18.      #include
main()
{
struct xx
{
int x;
struct yy
{
char s;
            struct xx *p;
};
struct yy *q;
};
}

Answer:
Compiler Error

Explanation:
The structure yy is nested within structure xx. Hence, the elements are of yy are to be accessed through the instance of structure xx, which needs an instance of yy to be known. If the instance is created after defining the structure the compiler will not know about the instance relative to xx. Hence for nested structure yy you have to declare member.
19.      main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}

Answer:
hai

Explanation:
\n  - newline
\b  - backspace
\r  - linefeed
20.      main()
{
int i=5;
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
}

Answer:
45545

Explanation:
The arguments in a function call are pushed into the stack from left to right. The evaluation is by popping out from the stack. and the  evaluation is from right to left, hence the result.
21.      #define square(x) x*x
main()
{
int i;
i = 64/square(4);
printf("%d",i);
}

Answer:
64

Explanation:
the macro call square(4) will substituted by 4*4 so the expression becomes i = 64/4*4 . Since / and * has equal priority the expression will be evaluated as (64/4)*4 i.e. 16*4 = 64
22.      main()
{
char *p="hai friends",*p1;
p1=p;
while(*p!='\0') ++*p++;
printf("%s   %s",p,p1);
}

Answer:
ibj!gsjfoet

Explanation:
                        ++*p++ will be parse in the given order
Ø  *p that is value at the location currently pointed by p will be taken
Ø  ++*p the retrieved value will be incremented
Ø  when ; is encountered the location will be incremented that is p++ will be executed
Hence, in the while loop initial value pointed by p is ‘h’, which is changed to ‘i’ by executing ++*p and pointer moves to point, ‘a’ which is similarly changed to ‘b’ and so on. Similarly blank space is converted to ‘!’. Thus, we obtain value in p becomes “ibj!gsjfoet” and since p reaches ‘\0’ and p1 points to p thus p1doesnot print anything.
23.      #include
#define a 10
main()
{
#define a 50
printf("%d",a);
}

Answer:
50

Explanation:
The preprocessor directives can be redefined anywhere in the program. So the most recently assigned value will be taken.
24.      #define clrscr() 100
main()
{
clrscr();
printf("%d\n",clrscr());
}

Answer:
100

Explanation:
Preprocessor executes as a seperate pass before the execution of the compiler. So textual replacement of clrscr() to 100 occurs.The input  program to compiler looks like this :
                        main()
                        {
                             100;
                             printf("%d\n",100);
                        }
            Note:  
100; is an executable statement but with no action. So it doesn't give any problem
Predict the output or error(s) for the following:
25.   main()
{
printf("%p",main);
}

Answer:
                        Some address will be printed.

Explanation:
            Function names are just addresses (just like array names are addresses).
main() is also a function. So the address of function main will be printed. %p in printf specifies that the argument is an address. They are printed as hexadecimal numbers.
26.       main()
{
clrscr();
}
clrscr();

           
Answer:
No output/error

Explanation:
The first clrscr() occurs inside a function. So it becomes a function call. In the second clrscr(); is a function declaration (because it is not inside any function).
27.       enum colors {BLACK,BLUE,GREEN}
 main()
{
 
 printf("%d..%d..%d",BLACK,BLUE,GREEN);
  
 return(1);
}

Answer:
0..1..2

Explanation:
enum assigns numbers starting from 0, if not explicitly defined.
28.       void main()
{
 char far *farther,*farthest;
 
 printf("%d..%d",sizeof(farther),sizeof(farthest));
  
 }

Answer:
4..2 

Explanation:
            the second pointer is of char type and not a far pointer
29.       main()
{
 int i=400,j=300;
 printf("%d..%d");
}

Answer:
400..300

Explanation:
printf takes the values of the first two assignments of the program. Any number of printf's may be given. All of them take only the first two values. If more number of assignments given in the program, then printf will take garbage values.
30.       main()
{
 char *p;
 p="Hello";
 printf("%c\n",*&*p);
}

Answer:
H

Explanation:
* is a dereference operator & is a reference  operator. They can be    applied any number of times provided it is meaningful. Here  p points to  the first character in the string "Hello". *p dereferences it and so its value is H. Again  & references it to an address and * dereferences it to the value H.
31.       main()
{
    int i=1;
    while (i<=5)
    {
       printf("%d",i);
       if (i>2)
              goto here;
       i++;
    }
}
fun()
{
   here:
     printf("PP");
}

Answer:
Compiler error: Undefined label 'here' in function main

Explanation:
Labels have functions scope, in other words The scope of the labels is limited to functions . The label 'here' is available in function fun() Hence it is not visible in function main.
32.       main()
{
   static char names[5][20]={"pascal","ada","cobol","fortran","perl"};
    int i;
    char *t;
    t=names[3];
    names[3]=names[4];
    names[4]=t;
    for (i=0;i<=4;i++)
           
printf("%s",names[i]);
}

Answer:
Compiler error: Lvalue required in function main

Explanation:
Array names are pointer constants. So it cannot be modified.
33.     void main()
{
            int i=5;
            printf("%d",i++ + ++i);
}

Answer:
Output Cannot be predicted  exactly.

Explanation:
Side effects are involved in the evaluation of   i
34.       void main()
{
            int i=5;
            printf("%d",i+++++i);
}

Answer:
Compiler Error

Explanation:
The expression i+++++i is parsed as i ++ ++ + i which is an illegal combination of operators.
35.       #include
main()
{
int i=1,j=2;
switch(i)
 {
 case 1:  printf("GOOD");
                break;
 case j:  printf("BAD");
               break;
 }
}

Answer:
Compiler Error: Constant expression required in function main.

Explanation:
The case statement can have only constant expressions (this implies that we cannot use variable names directly so an error).
            Note:
Enumerated types can be used in case statements.
Predict the output or error(s) for the following:
36.    main()
{
int i;
printf("%d",scanf("%d",&i));  // value 10 is given as input here
}

Answer:
1

Explanation:
Scanf returns number of items successfully read and not 1/0.  Here 10 is given as input which should have been scanned successfully. So number of items read is 1.
37.       #define f(g,g2) g##g2
main()
{
int var12=100;
printf("%d",f(var,12));
            }


Answer:
100
38.      main()
{
int i=0;
 
for(;i++;printf("%d",i)) ;
printf("%d",i);
}

Answer:
            1

Explanation:
before entering into the for loop the checking condition is "evaluated". Here it evaluates to 0 (false) and comes out of the loop, and i is incremented (note the semicolon after the for loop).
39.       #include
main()
{
  char s[]={'a','b','c','\n','c','\0'};
  char *p,*str,*str1;
  p=&s[3];
  str=p;
  str1=s;
  printf("%d",++*p + ++*str1-32);
}

Answer:
M

Explanation:
p is pointing to character '\n'.str1 is pointing to character 'a' ++*p meAnswer:"p is pointing to '\n' and that is incremented by one." the ASCII value of '\n' is 10. then it is incremented to 11. the value of ++*p is 11. ++*str1 meAnswer:"str1 is pointing to 'a' that is incremented by 1 and it becomes 'b'. ASCII value of 'b' is 98. both 11 and 98 is added and result is subtracted from 32.
i.e. (11+98-32)=77("M");
40.       #include
main()
{
  struct xx
   {
      int x=3;
      char name[]="hello";
   };
struct xx *s=malloc(sizeof(struct xx));
printf("%d",s->x);
printf("%s",s->name);
}

Answer:
Compiler Error

Explanation:
Initialization should not be done for structure members inside the structure declaration
41.       #include
main()
{
struct xx
 {
              int x;
              struct yy
               {
                 char s;
                 struct xx *p;
               };
                         struct yy *q;
            };
            }


Answer:
Compiler Error

Explanation:
in the end of nested structure yy a member have to be declared
42.       main()
{
 extern int i;
 i=20;
 printf("%d",sizeof(i));
}

Answer:
Linker error: undefined symbol '_i'.

Explanation:
extern declaration specifies that the variable i is defined somewhere else. The compiler passes the external variable to be resolved by the linker. So compiler doesn't find an error. During linking the linker searches for the definition of i. Since it is not found the linker flags an error.
43.       main()
{
printf("%d", out);
}

int out=100;
Answer:
Compiler error: undefined symbol out in function main.

Explanation:
The rule is that a variable is available for use from the point of declaration. Even though a is a global variable, it is not available for main. Hence an error.
Predict the output or error(s) for the following:
44.    main()
{
 extern out;
 printf("%d", out);
}
 int out=100;

Answer:
100     

            Explanation:  
This is the correct way of writing the previous program.
45.       main()
{
 show();
}
void show()
{
 printf("I'm the greatest");
}

Answer:
Compier error: Type mismatch in redeclaration of show.

Explanation:
When the compiler sees the function show it doesn't know anything about it. So the default return type (ie, int) is assumed. But when compiler sees the actual definition of show mismatch occurs since it is declared as void. Hence the error.
The solutions are as follows:
1. declare void show() in main() .
2. define show() before main().
3. declare extern void show() before the use of show().
46.  main( )
{
  int a[2][3][2] = {{{2,4},{7,8},{3,4}},{{2,2},{2,3},{3,4}}};
  printf(“%u %u %u %d \n”,a,*a,**a,***a);
        printf(“%u %u %u %d \n”,a+1,*a+1,**a+1,***a+1);
       }

Answer:
100, 100, 100, 2
114, 104, 102, 3
47.   main( )
{
  int a[ ] = {10,20,30,40,50},j,*p;
  for(j=0; j<5; j++)
    {
printf(“%d” ,*a);
a++;
    }
    p = a;
   for(j=0; j<5; j++)
      {
printf(“%d ” ,*p);
p++;
      }
 }

Answer:
Compiler error: lvalue required.
                       
Explanation:
Error is in line with statement a++. The operand must be an lvalue and may be of any of scalar type for the any operator, array name only when subscripted is an lvalue. Simply array name is a non-modifiable lvalue.
48.       main( )
{
 static int  a[ ]   = {0,1,2,3,4};
 int  *p[ ] = {a,a+1,a+2,a+3,a+4};
 int  **ptr =  p;
 ptr++;
 printf(“\n %d  %d  %d”, ptr-p, *ptr-a, **ptr);
 *ptr++;
 printf(“\n %d  %d  %d”, ptr-p, *ptr-a, **ptr);
 *++ptr;
 printf(“\n %d  %d  %d”, ptr-p, *ptr-a, **ptr);
 ++*ptr;
       printf(“\n %d  %d  %d”, ptr-p, *ptr-a, **ptr);
}

Answer:
            111
            222
            333
            344
49.       main( )
{
 void *vp;
 char ch = ‘g’, *cp = “goofy”;
 int j = 20;
 vp = &ch;
 printf(“%c”, *(char *)vp);
 vp = &j;
 printf(“%d”,*(int *)vp);
 vp = cp;
 printf(“%s”,(char *)vp + 3);
}

Answer:
            g20fy

Explanation:
Since a void pointer is used it can be type casted to any  other type pointer. vp = &ch  stores address of char ch and the next statement prints the value stored in vp after type casting it to the proper data type pointer. the output is ‘g’. Similarly  the output from second printf is ‘20’. The third printf statement type casts it to print the string from the 4th value hence the output is ‘fy’.
50.    main ( )
{
 static char *s[ ]  = {“black”, “white”, “yellow”, “violet”};
 char **ptr[ ] = {s+3, s+2, s+1, s}, ***p;
 p = ptr;
 **++p;
 printf(“%s”,*--*++p + 3);
}

Answer:
            ck

Explanation:
In this problem we have an array of char pointers pointing to start of 4 strings. Then we have ptr which is a pointer to a pointer of type char and a variable p which is a pointer to a pointer to a pointer of type char. p hold the initial value of ptr, i.e. p = s+3. The next statement increment value in p by 1 , thus now value of p =  s+2. In the printf statement the expression is evaluated *++p causes gets value s+1 then the pre decrement is executed and we get s+1 – 1 = s . the indirection operator now gets the value from the array of s and adds 3 to the starting address. The string is printed starting from this position. Thus, the output is ‘ck’.
51.    main()
{
 int  i, n;
 char *x = “girl”;
 n = strlen(x);
 *x = x[n];
 for(i=0; i

   {
printf(“%s\n”,x);
x++;
   }
 }

Answer:
(blank space)
irl
rl
l

Explanation:
Here a string (a pointer to char) is initialized with a value “girl”.  The strlen function returns the length of the string, thus n has a value 4. The next statement assigns value at the nth location (‘\0’) to the first location. Now the string becomes “\0irl” . Now the printf statement prints the string after each iteration it increments it starting position.  Loop starts from 0 to 4. The first time x[0] = ‘\0’ hence it prints nothing and pointer value is incremented. The second time it prints from x[1] i.e “irl” and the third time it prints “rl” and the last time it prints “l” and the loop terminates.
Predict the output or error(s) for the following:
52.     int i,j;
            for(i=0;i<=10;i++)
            {
            j+=5;
            assert(i<5);
            }

Answer:
Runtime error: Abnormal program termination.
                                    assert failed (i<5), ,

Explanation:
asserts are used during debugging to make sure that certain conditions are satisfied. If assertion fails, the program will terminate reporting the same. After debugging use,
            #undef NDEBUG
and this will disable all the assertions from the source code. Assertion
is a good debugging tool to make use of. 
53.       main()
            {
            int i=-1;
            +i;
            printf("i = %d, +i = %d \n",i,+i);
            }


Answer:
 i = -1, +i = -1

Explanation:
Unary + is the only dummy operator in C. Where-ever it comes you can just ignore it just because it has no effect in the expressions (hence the name dummy operator).
54. What are the files which are automatically opened when a C file is executed?
Answer:
stdin, stdout, stderr (standard input,standard output,standard error).
55.  what will be the position of the file marker?
            a: fseek(ptr,0,SEEK_SET);
            b: fseek(ptr,0,SEEK_CUR);

Answer :
            a: The SEEK_SET sets the file position marker to the starting of the file.
                        b: The SEEK_CUR sets the file position marker to the current position
            of the file.
56.       main()
            {
            char name[10],s[12];
            scanf(" \"%[^\"]\"",s);
            }
            How scanf will execute?

Answer:
First it checks for the leading white space and discards it.Then it matches with a quotation mark and then it  reads all character upto another quotation mark.
57.       What is the problem with the following code segment?
            while ((fgets(receiving array,50,file_ptr)) != EOF)

                                    ;
Answer & Explanation:
fgets returns a pointer. So the correct end of file check is checking for != NULL.
58.   main()
            {
            main();
            }

Answer:
 Runtime error : Stack overflow.

Explanation:
main function calls itself again and again. Each time the function is called its return address is stored in the call stack. Since there is no condition to terminate the function call, the call stack overflows at runtime. So it terminates the program and results in an error.
59.      main()
            {
            char *cptr,c;
            void *vptr,v;
            c=10;  v=0;
            cptr=&c; vptr=&v;
            printf("%c%v",c,v);
            }

Answer:
Compiler error (at line number 4): size of v is Unknown.

Explanation:
You can create a variable of type void * but not of type void, since void is an empty type. In the second line you are creating variable vptr of type void * and v of type void hence an error.
60.       main()
            {
            char *str1="abcd";
            char str2[]="abcd";
            printf("%d %d %d",sizeof(str1),sizeof(str2),sizeof("abcd"));
            }

Answer:
2 5 5

Explanation:
In first sizeof, str1 is a character pointer so it gives you the size of the pointer variable. In second sizeof the name str2 indicates the name of the array whose size is 5 (including the '\0' termination character). The third sizeof is similar to the second one.
61.      main()
            {
            char not;
            not=!2;
            printf("%d",not);
            }

Answer:
0

Explanation:
! is a logical operator. In C the value 0 is considered to be the boolean value FALSE, and any non-zero value is considered to be the boolean value TRUE. Here 2 is a non-zero value so TRUE. !TRUE is FALSE (0) so it prints 0.
62.       #define FALSE -1
            #define TRUE   1
            #define NULL   0
            main() {
               if(NULL)
                        puts("NULL");
               else if(FALSE)
                        puts("TRUE");
               else
                        puts("FALSE");
               }

Answer:
TRUE

Explanation:
The input program to the compiler after processing by the preprocessor is,
            main(){
                        if(0)
                                    puts("NULL");
            else if(-1)
                                    puts("TRUE");
            else
                                    puts("FALSE");
                        }
Preprocessor doesn't replace the values given inside the double quotes. The check by if condition is boolean value false so it goes to else. In second if -1 is boolean value true hence "TRUE" is printed.
Predict the output or error(s) for the following:
63.     main()
            {
            int k=1;
            printf("%d==1 is ""%s",k,k==1?"TRUE":"FALSE");
            }

Answer:
1==1 is TRUE

Explanation:
When two strings are placed together (or separated by white-space) they are concatenated (this is called as "stringization" operation). So the string is as if it is given as "%d==1 is %s". The conditional operator( ?: ) evaluates to "TRUE".
64.       main()
            {
            int y;
            scanf("%d",&y); // input given is 2000
            if( (y%4==0 && y%100 != 0) || y%100 == 0 )
                 printf("%d is a leap year");
            else
                 printf("%d is not a leap year");
            }

Answer:
2000 is a leap year

Explanation:
An ordinary program to check if leap year or not.
65.       #define max 5
            #define int arr1[max]
            main()
            {
            typedef char arr2[max];
            arr1 list={0,1,2,3,4};
            arr2 name="name";
            printf("%d %s",list[0],name);
            }

Answer:
Compiler error (in the line arr1 list = {0,1,2,3,4})

Explanation:
arr2 is declared of type array of size 5 of characters. So it can be used to declare the variable name of the type arr2. But it is not the case of arr1. Hence an error.
Rule of Thumb:
#defines are used for textual replacement whereas typedefs are used for declaring new types.
66.       int i=10;
            main()
            {
             extern int i;
              {
                 int i=20;
                        {
                         const volatile unsigned i=30;
                         printf("%d",i);
                        }
                  printf("%d",i);
               }
            printf("%d",i);
            }

Answer:
30,20,10

Explanation:
'{' introduces new block and thus new scope. In the innermost block i is declared as,
            const volatile unsigned
which is a valid declaration. i is assumed of type int. So printf prints 30. In the next block, i has value 20 and so printf prints 20. In the outermost block, i is declared as extern, so no storage space is allocated for it. After compilation is over the linker resolves it to global variable i (since it is the only variable visible there). So it prints i's value as 10.
67.       main()
            {
                int *j;
                {
                 int i=10;
                 j=&i;
                 }
                 printf("%d",*j);
}

Answer:
10

Explanation:
The variable i is a block level variable and the visibility is inside that block only. But the lifetime of i is lifetime of the function so it lives upto the exit of main function. Since the i is still allocated space, *j prints the value stored in i since j points i.
68.      main()
            {
            int i=-1;
            -i;
            printf("i = %d, -i = %d \n",i,-i);
            }

Answer:
i = -1, -i = 1

Explanation:
-i is executed and this execution doesn't affect the value of i. In printf first you just print the value of i. After that the value of the expression -i = -(-1) is printed.
69.       #include
main()
 {
   const int i=4;
   float j;
   j = ++i;
   printf("%d  %f", i,++j);
 }

Answer:
Compiler error

Explanation:
i is a constant. you cannot change the value of constant
70.       #include
main()
{
  int a[2][2][2] = { {10,2,3,4}, {5,6,7,8}  };
  int *p,*q;
  p=&a[2][2][2];
  *q=***a;
  printf("%d..%d",*p,*q);
}

Answer:
garbagevalue..1

Explanation:
p=&a[2][2][2]  you declare only two 2D arrays. but you are trying to access the third 2D(which you are not declared) it will print garbage values. *q=***a starting address of a is assigned integer pointer. now q is pointing to starting address of a.if you print *q meAnswer:it will print first element of 3D array.
71.      #include
main()
  {
    register i=5;
    char j[]= "hello";                    
     printf("%s  %d",j,i);
}

Answer:
hello 5

Explanation:
if you declare i as register  compiler will treat it as ordinary integer and it will take integer value. i value may be  stored  either in register  or in memory.
72.      main()
{
              int i=5,j=6,z;
              printf("%d",i+++j);
             }

Answer:
11

Explanation:
the expression i+++j is treated as (i++ + j)   
C Aptitude Questions-2
Predict the output or error(s) for the following:
1.     struct aaa{
struct aaa *prev;
int i;
struct aaa *next;
};
main()
{
 struct aaa abc,def,ghi,jkl;
 int x=100;
 abc.i=0;abc.prev=&jkl;
 abc.next=&def;
 def.i=1;def.prev=&abc;def.next=&ghi;
 ghi.i=2;ghi.prev=&def;
 ghi.next=&jkl;
 jkl.i=3;jkl.prev=&ghi;jkl.next=&abc;
 x=abc.next->next->prev->next->i;
 printf("%d",x);
}

Answer:
2
Explanation:
above all statements form a double circular linked list;
abc.next->next->prev->next->i
this one points to "ghi" node the value of at particular node is 2.
2.       struct point
 {
 int x;
 int y;
 };
struct point origin,*pp;
main()
{
pp=&origin;
printf("origin is(%d%d)\n",(*pp).x,(*pp).y);
printf("origin is (%d%d)\n",pp->x,pp->y);
}

           
Answer:
origin is(0,0)
origin is(0,0)

Explanation:
pp is a pointer to structure. we can access the elements of the structure either with arrow mark or with indirection operator.
Note:
Since structure point  is globally declared x & y are initialized as zeroes
3.       main()
{
 int i=_l_abc(10);
             printf("%d\n",--i);
}
int _l_abc(int i)
{
 return(i++);
}

Answer:
9

Explanation:
return(i++) it will first return i and then increments. i.e. 10 will be returned.
4.       main()
{
 char *p;
 int *q;
 long *r;
 p=q=r=0;
 p++;
 q++;
 r++;
 printf("%p...%p...%p",p,q,r);
}

Answer:
0001...0002...0004

Explanation:
++ operator  when applied to pointers increments address according to their corresponding data-types.
5.      main()
{
 char c=' ',x,convert(z);
 getc(c);
 if((c>='a') && (c<='z'))
 x=convert(c);
 printf("%c",x);
}
convert(z)
{
  return z-32;
}

Answer:
Compiler error

Explanation:
declaration of convert and format of getc() are wrong.
6.      main(int argc, char **argv)
{
 printf("enter the character");
 getchar();
 sum(argv[1],argv[2]);
}
sum(num1,num2)
int num1,num2;
{
 return num1+num2;
}

Answer:
Compiler error.

Explanation:
argv[1] & argv[2] are strings. They are passed to the function sum without converting it to integer values. 
7.       # include
int one_d[]={1,2,3};
main()
{
 int *ptr;
 ptr=one_d;
 ptr+=3;
 printf("%d",*ptr);
}

Answer:
garbage value

Explanation:
ptr pointer is pointing to out of the array range of one_d.
Predict the output or error(s) for the following:
8.       # include
aaa() {
  printf("hi");
 }
bbb(){
 printf("hello");
 }
ccc(){
 printf("TechPreparation.com");
 }
main()
{
  int (*ptr[3])();
  ptr[0]=aaa;
  ptr[1]=bbb;
  ptr[2]=ccc;
  ptr[2]();
}

Answer:
TechPreparation.com


Explanation:
ptr is array of pointers to functions of return type int.ptr[0] is assigned to address of the function aaa. Similarly ptr[1] and ptr[2] for bbb and ccc respectively. ptr[2]() is in effect of writing ccc(), since ptr[2] points to ccc.
9.       #include
main()
{
FILE *ptr;
char i;
ptr=fopen("zzz.c","r");
while((i=fgetch(ptr))!=EOF)
printf("%c",i);
}

Answer:
contents of zzz.c followed by an infinite loop 

Explanation:
The condition is checked against EOF, it should be checked against NULL.
10.       main()
{
 int i =0;j=0;
 if(i && j++)
            printf("%d..%d",i++,j);
printf("%d..%d,i,j);
}

Answer:
0..0

Explanation:
The value of i is 0. Since this information is enough to determine the truth value of the boolean expression. So the statement following the if statement is not executed.  The values of i and j remain unchanged and get printed.
11.     main()
{
 int i;
 i = abc();
 printf("%d",i);
}
abc()
{
 _AX = 1000;
}

Answer:
1000

Explanation:
Normally the return value from the function is through the information from the accumulator. Here _AH is the pseudo global variable denoting the accumulator. Hence, the value of the accumulator is set 1000 so the function returns value 1000.
12.       int i;
            main(){
int t;
for ( t=4;scanf("%d",&i)-t;printf("%d\n",i))
                        printf("%d--",t--);
                        }
            // If the inputs are 0,1,2,3 find the o/p

Answer:
            4--0
                        3--1
                        2--2     

Explanation:
Let us assume some x= scanf("%d",&i)-t the values during execution
                        will be,
          t        i       x
          4       0      -4
          3       1      -2
          2       2       0
13.       main(){
  int a= 0;int b = 20;char x =1;char y =10;
  if(a,b,x,y)
        printf("hello");
 }

Answer:
hello

Explanation:
The comma operator has associativity from left to right. Only the rightmost value is returned and the other values are evaluated and ignored. Thus the value of last variable y is returned to check in if. Since it is a non zero value if becomes true so, "hello" will be printed.
14.       main(){
 unsigned int i;
 for(i=1;i>-2;i--)
                        printf("c aptitude");
}

Explanation:
i is an unsigned integer. It is compared with a signed value. Since the both types doesn't match, signed is promoted to unsigned value. The unsigned equivalent of -2 is a huge value so condition becomes false and control comes out of the loop.
15. In the following pgm add a  stmt in the function  fun such that the address of
'a' gets stored in 'j'.
main(){
  int * j;
  void fun(int **);
  fun(&j);
 }
 void fun(int **k) {
  int a =0;
  /* add a stmt here*/
 }

Answer:
                        *k = &a
Explanation:
The argument of the function is a pointer to a pointer.
16. What are the following notations of defining functions known as?
i.      int abc(int a,float b)
                        {
                        /* some code */
 }
ii.    int abc(a,b)
        int a; float b;
                        {
                        /* some code*/
                        }

Answer:
i.  ANSI C notation
ii. Kernighan & Ritche notation
Predict the output or error(s) for the following:
16.      main()
{
char *p;
p="%d\n";
           p++;
           p++;
           printf(p-2,300);
}

Answer:
300

Explanation:
The pointer points to % since it is incremented twice and again decremented by 2, it points to '%d\n' and 300 is printed.
17.       main(){
 char a[100];
 a[0]='a';a[1]]='b';a[2]='c';a[4]='d';
 abc(a);
}
abc(char a[]){
 a++;
             printf("%c",*a);
 a++;
 printf("%c",*a);
}
Explanation:
The base address is modified only in function and as a result a points to 'b' then after incrementing to 'c' so bc will be printed.
18.      func(a,b)
int a,b;
{
 return( a= (a==b) );
}
main()
{
int process(),func();
printf("The value of process is %d !\n ",process(func,3,6));
}
process(pf,val1,val2)
int (*pf) ();
int val1,val2;
{
return((*pf) (val1,val2));
 }

Answer:
The value if process is 0 !

Explanation:
The function 'process' has 3 parameters - 1, a pointer to another function  2 and 3, integers. When this function is invoked from main, the following substitutions for formal parameters take place: func for pf, 3 for val1 and 6 for val2. This function returns the result of the operation performed by the function 'func'. The function func has two integer parameters. The formal parameters are substituted as 3 for a and 6 for b. since 3 is not equal to 6, a==b returns 0. therefore the function returns 0 which in turn is returned by the function 'process'.
19.       void main()
{
            static int i=5;
            if(--i){
                        main();
                        printf("%d ",i);
            }
}

Answer:
 0 0 0 0

Explanation:
            The variable "I" is declared as static, hence memory for I will be allocated for only once, as it encounters the statement. The function main() will be called recursively unless I becomes equal to 0, and since main() is recursively called, so the value of static I ie., 0 will be printed every time the control is returned.
20.       void main()
{
            int k=ret(sizeof(float));
            printf("\n here value is %d",++k);
}
int ret(int ret)
{
            ret += 2.5;
            return(ret);
}

Answer:
Here value is 7

Explanation:
The int ret(int ret), ie., the function name and the argument name can be the same.
            Firstly, the function ret() is called in which the sizeof(float) ie., 4 is passed,  after the first expression the value in ret will be 6, as ret is integer hence the value stored in ret will have implicit type conversion from float to int. The ret is returned in main() it is printed after and preincrement.
21.       void main()
{
            char a[]="12345\0";
            int i=strlen(a);
            printf("here in 3 %d\n",++i);
}

Answer:
here in 3 6

Explanation:
The char array 'a' will hold the initialized string, whose length will be counted from 0 till the null character. Hence the 'I' will hold the value equal to 5, after the pre-increment in the printf statement, the 6 will be printed.
22.       void main()
{
            unsigned giveit=-1;
            int gotit;
            printf("%u ",++giveit);
            printf("%u \n",gotit=--giveit);
}

Answer:
 0 65535
23.    void main()
{
            int i;
            char a[]="\0";
            if(printf("%s\n",a))
                        printf("Ok here \n");
            else
                        printf("Forget it\n");
}

Answer:
 Ok here

Explanation:
Printf will return how many characters does it print. Hence printing a null character returns 1 which makes the if statement true, thus "Ok here" is printed.
Predict the output or error(s) for the following:
24.      void main()
{
            void *v;
            int integer=2;
            int *i=&integer;
            v=i;
            printf("%d",(int*)*v);
}

Answer:
Compiler Error. We cannot apply indirection on type void*.

Explanation:
Void pointer is a generic pointer type. No pointer arithmetic can be done on it. Void pointers are normally used for,
1.      Passing generic pointers to functions and returning such pointers.
2.      As a intermediate pointer type.
3.      Used when the exact pointer type will be known at a later point of time.
25.     void main()
{
            int i=i++,j=j++,k=k++;
printf(“%d%d%d”,i,j,k);
}
Answer:
Garbage values.

Explanation:
An identifier is available to use in program code from the point of its declaration.
So expressions such as  i = i++ are valid statements. The i, j and k are automatic variables and so they contain some garbage value. Garbage in is garbage out (GIGO).
26.     void main()
{
            static int i=i++, j=j++, k=k++;
printf(“i = %d j = %d k = %d”, i, j, k);
}

Answer:
i = 1 j = 1 k = 1

Explanation:
Since static variables are initialized to zero by default.
27.      void main()
{
            while(1){
                        if(printf("%d",printf("%d")))
                                    break;
                        else
                                    continue;
            }
}

Answer:
Garbage values

Explanation:
The inner printf executes first to print some garbage value. The printf returns no of characters printed and this value also cannot be predicted. Still the outer printf  prints something and so returns a non-zero value. So it encounters the break statement and comes out of the while statement.
28.        main()
{
            unsigned int i=10;
            while(i-->=0)
                        printf("%u ",i);
 
}

Answer:
10 9 8 7 6 5 4 3 2 1 0 65535 65534…..

Explanation:
Since i is an unsigned integer it can never become negative. So the expression i-- >=0  will always be true, leading to an infinite loop.
29.        #include
main()
{
            int x,y=2,z,a;
            if(x=y%2) z=2;
            a=2;
            printf("%d %d ",z,x);
}

 Answer:
Garbage-value 0

Explanation:
The value of y%2 is 0. This value is assigned to x. The condition reduces to if (x) or in other words if(0) and so z goes uninitialized.
Thumb Rule: Check all control paths to write bug free code.
30.        main()
{
            int a[10];
            printf("%d",*a+1-*a+3);
}

Answer:


Explanation:
            *a and -*a cancels out. The result is as simple as 1 + 3 = 4 ! 
31.        #define prod(a,b) a*b
main()
{
            int x=3,y=4;
            printf("%d",prod(x+2,y-1));
}

Answer:
10
Explanation:
            The macro expands and evaluates to as:
            x+2*y-1 => x+(2*y)-1 => 10
32.        main()
{
            unsigned int i=65000;
            while(i++!=0);
            printf("%d",i);
}

Answer:
 1

Explanation:
Note the semicolon after the while statement. When the value of i becomes 0 it comes out of while loop. Due to post-increment on i the value of i while printing is 1.
Predict the output or error(s) for the following:
33.       main()
{
            int i=0;
            while(+(+i--)!=0)
                        i-=i++;
            printf("%d",i);
}

Answer:
-1

Explanation:
Unary + is the only dummy operator in C. So it has no effect on the expression and now the while loop is,             while(i--!=0) which is false and so breaks out of while loop. The value –1 is printed due to the post-decrement operator.
34.       main()
{
            float f=5,g=10;
            enum{i=10,j=20,k=50};
            printf("%d\n",++k);
            printf("%f\n",f<<2);
            printf("%lf\n",f%g);
            printf("%lf\n",fmod(f,g));
}
Answer:
Line no 5: Error: Lvalue required
Line no 6: Cannot apply leftshift to float
Line no 7: Cannot apply mod to float

Explanation:
                        Enumeration constants cannot be modified, so you cannot apply ++.
                        Bit-wise operators and % operators cannot be applied on float values.
                        fmod() is to find the modulus values for floats as % operator is for ints. 
35.       main()
{
            int i=10;
            void pascal f(int,int,int);
f(i++,i++,i++);
            printf(" %d",i);
}
void pascal f(integer :i,integer:j,integer :k)
{
write(i,j,k);
}

Answer:
Compiler error:  unknown type integer
Compiler error:  undeclared function write

Explanation:
Pascal keyword doesn’t mean that pascal code can be used. It means that the function follows Pascal argument passing mechanism in calling the functions.
36.    void pascal f(int i,int j,int k)
{
printf(“%d %d %d”,i, j, k);
}
void cdecl f(int i,int j,int k)
{
printf(“%d %d %d”,i, j, k);
}
main()
{
            int i=10;
f(i++,i++,i++);
            printf(" %d\n",i);
i=10;
f(i++,i++,i++);
printf(" %d",i);
}

Answer:
10 11 12 13
12 11 10 13

Explanation:
Pascal argument passing mechanism forces the arguments to be called from left to right. cdecl is the normal C argument passing mechanism where the arguments are passed from right to left.
37. What is the output of the program given below
 
main()
    {
       signed char i=0;
       for(;i>=0;i++) ;
       printf("%d\n",i);
    }

Answer
                        -128

Explanation
Notice the semicolon at the end of the for loop. THe initial value of the i is set to 0. The inner loop executes to increment the value from 0 to 127 (the positive range of char) and then it rotates to the negative value of -128. The condition in the for loop fails and so comes out of the for loop. It prints the current value of i that is -128.
38.  main()
    {
       unsigned char i=0;
       for(;i>=0;i++) ;
       printf("%d\n",i);
    }

Answer
            infinite loop

Explanation
The difference between the previous question and this one is that the char is declared to be unsigned. So the i++ can never yield negative value and i>=0 never becomes false so that it can come out of the for loop.
39.   main()
            {
       char i=0;
       for(;i>=0;i++) ;
       printf("%d\n",i);
       
 }

Answer:
                        Behavior is implementation dependent.

Explanation:
The detail if the char is signed/unsigned by default is implementation dependent. If the implementation treats the char to be signed by default the program will print –128 and terminate. On the other hand if it considers char to be unsigned by default, it goes to infinite loop.
Rule:
You can write programs that have implementation dependent behavior. But dont write programs that depend on such behavior.
40. Is the following statement a declaration/definition. Find what does it mean?
int (*x)[10];

Answer
                        Definition.
            x is a pointer to array of(size 10) integers.

                        Apply clock-wise rule to find the meaning of this definition.
41. What is the output for the program given below
 
     typedef enum errorType{warning, error, exception,}error;
     main()
    {
        error g1;
        g1=1;
        printf("%d",g1);
     }

Answer
                        Compiler error: Multiple declaration for error

Explanation
The name error is used in the two meanings. One means that it is a enumerator constant with value 1. The another use is that it is a type name (due to typedef) for enum errorType. Given a situation the compiler cannot distinguish the meaning of error to know in what sense the error is used:
            error g1;
g1=error;
            // which error it refers in each case?
When the compiler can distinguish between usages then it will not issue error (in pure technical terms, names can only be overloaded in different namespaces).
Note: the extra comma in the declaration,
enum errorType{warning, error, exception,}
is not an error. An extra comma is valid and is provided just for programmer’s convenience.
42.  typedef struct error{int warning, error, exception;}error;
     main()
    {
        error g1;
        g1.error =1;
        printf("%d",g1.error);
     }


Answer
                        1

Explanation
The three usages of name errors can be distinguishable by the compiler at any instance, so valid (they are in different namespaces).
Typedef struct error{int warning, error, exception;}error;
This error can be used only by preceding the error by struct kayword as in:
struct error someError;
typedef struct error{int warning, error, exception;}error;
This can be used only after . (dot) or -> (arrow) operator preceded by the variable
name as in :
g1.error =1;
            printf("%d",g1.error);
                        typedef struct error{int warning, error, exception;}error;
This can be used to define variables without using the preceding struct keyword as in:
error g1;
Since the compiler can perfectly distinguish between these three usages, it is perfectly legal and valid.

Note
This code is given here to just explain the concept behind. In real programming don’t use such overloading of names. It reduces the readability of the code. Possible doesn’t mean that we should use it!
Predict the output or error(s) for the following:
43. #ifdef something
int some=0;
#endif
 
main()
{
int thing = 0;
printf("%d %d\n", some ,thing);
}

Answer:
Compiler error : undefined symbol some

Explanation:
This is a very simple example for conditional compilation. The name something is not already known to the compiler making the declaration
int some = 0;
effectively removed from the source code.
44.  #if something == 0
int some=0;
#endif
 
main()
{
int thing = 0;
printf("%d %d\n", some ,thing);
}

Answer
0 0

Explanation
This code is to show that preprocessor expressions are not the same as the ordinary expressions. If a name is not known the preprocessor treats it to be equal to zero.
45. What is the output for the following program
 
            main()
                            {
      int arr2D[3][3];
       printf("%d\n", ((arr2D==* arr2D)&&(* arr2D == arr2D[0])) );
               }

Answer
1
46.    void main()
         {
if(~0 == (unsigned int)-1)
printf(“You can answer this if you know how values are represented in memory”);
         }

 Answer
You can answer this if you know how values are represented in memory

Explanation
~ (tilde operator or bit-wise negation operator) operates on 0 to produce all ones to fill the space for an integer. –1 is represented in unsigned value as all 1’s and so both are equal.
47. int swap(int *a,int *b)
{
 *a=*a+*b;*b=*a-*b;*a=*a-*b;
}
main()
{
                        int x=10,y=20;
            swap(&x,&y);
                        printf("x= %d y = %d\n",x,y);
}

Answer
            x = 20 y = 10

Explanation
This is one way of swapping two values. Simple checking will help understand this.
48.    main()
{         
char *p = “ayqm”;
printf(“%c”,++*(p++));
}

Answer:
b
49.      main()
            {
             int i=5;
             printf("%d",++i++);
}


Answer:
Compiler error: Lvalue required in function main
Explanation:
                        ++i yields an rvalue.  For postfix ++ to operate an lvalue is required.
50.     main()
{
char *p = “ayqm”;
char c;
c = ++*p++;
printf(“%c”,c);
}

Answer:
b

Explanation:
There is no difference between the expression ++*(p++) and ++*p++. Parenthesis just works as a visual clue for the reader to see which expression is first evaluated.
51.
int aaa() {printf(“Hi”);}
int bbb(){printf(“hello”);}
iny ccc(){printf(“bye”);}
 
main()
{
int ( * ptr[3]) ();
ptr[0] = aaa;
ptr[1] = bbb;
ptr[2] =ccc;
ptr[2]();
}

Answer:
 bye

Explanation:
int (* ptr[3])() says that ptr is an array of pointers to functions that takes no arguments and returns the type int. By the assignment ptr[0] = aaa; it means that the first function pointer in the array is initialized with the address of the function aaa. Similarly, the other two array elements also get initialized with the addresses of
the functions bbb and ccc. Since ptr[2] contains the address of the function ccc, the call to the function ptr[2]() is same as calling ccc(). So it results in printing  "bye".
52.
main()
{
int i=5;
printf(“%d”,i=++i ==6);
}

Answer:
1

Explanation:
The expression can be treated as i = (++i==6), because == is of higher precedence than = operator. In the inner expression, ++i is equal to 6 yielding true(1). Hence the result.
Predict the output or error(s) for the following:
53.    main()
{
                        char p[ ]="%d\n";
p[1] = 'c';
printf(p,65);
}

Answer:
A

Explanation:
Due to the assignment p[1] = ‘c’ the string becomes, “%c\n”. Since this string becomes the format string for printf and ASCII value of 65 is ‘A’, the same gets printed.
54.     void ( * abc( int, void ( *def) () ) ) ();

Answer::
 abc is a  ptr to a  function which takes 2 parameters .(a). an integer variable.(b).        a ptrto a funtion which returns void. the return type of the function is  void.
Explanation:
                        Apply the clock-wise rule to find the result.
55.     main()
{
while (strcmp(“some”,”some\0”))
printf(“Strings are not equal\n”);
            }

Answer:
No output

Explanation:
Ending the string constant with \0 explicitly makes no difference. So “some” and “some\0” are equivalent. So, strcmp returns 0 (false) hence breaking out of the while loop.
56.     main()
{
char str1[] = {‘s’,’o’,’m’,’e’};
char str2[] = {‘s’,’o’,’m’,’e’,’\0’};
while (strcmp(str1,str2))
printf(“Strings are not equal\n”);
}

Answer:
“Strings are not equal”
“Strings are not equal”
….

Explanation:
If a string constant is initialized explicitly with characters, ‘\0’ is not appended automatically to the string. Since str1 doesn’t have null termination, it treats whatever the values that are in the following positions as part of the string until it randomly reaches a ‘\0’. So str1 and str2 are not the same, hence the result.
57.     main()
{
int i = 3;
for (;i++=0;) printf(“%d”,i);
}

Answer:
Compiler Error: Lvalue required.

Explanation:
As we know that increment operators return rvalues and  hence it cannot appear on the left hand side of an assignment operation.
58.     void main()
{
int *mptr, *cptr;
mptr = (int*)malloc(sizeof(int));
printf(“%d”,*mptr);
int *cptr = (int*)calloc(sizeof(int),1);
printf(“%d”,*cptr);
}

Answer:
garbage-value 0

Explanation:
The memory space allocated by malloc is uninitialized, whereas calloc returns the allocated memory space initialized to zeros.
59.      void main()
{
static int i;
while(i<=10)
(i>2)?i++:i--;
            printf(“%d”, i);
}

Answer:
32767

Explanation:
Since i is static it is initialized to 0. Inside the while loop the conditional operator evaluates to false, executing i--. This continues till the integer value rotates to positive value (32767). The while condition becomes false and hence, comes out of the while loop, printing the i value.
60.      main()
{
                        int i=10,j=20;
            j = i, j?(i,j)?i:j:j;
                        printf("%d %d",i,j);
}

Answer:
10 10

Explanation:
                        The Ternary operator ( ? : ) is equivalent for if-then-else statement. So the question can be written as:
                        if(i,j)
                             {
if(i,j)
                             j = i;
                        else
                            j = j;                        
                        }
               else
                        j = j;      
61.     1. const char *a;
2. char* const a;
3. char const *a;
-Differentiate the above declarations.


Answer:
1. 'const' applies to char * rather than 'a' ( pointer to a constant char )
            *a='F'       : illegal
                                    a="Hi"       : legal

2. 'const' applies to 'a'  rather than to the value of a (constant pointer to char )
            *a='F'       : legal
            a="Hi"       : illegal
 
3. Same as 1.
62.     main()
{
                        int i=5,j=10;
            i=i&=j&&10;
                        printf("%d %d",i,j);
}

Answer:
1 10

Explanation:
The expression can be written as i=(i&=(j&&10)); The inner expression (j&&10) evaluates to 1 because j==10. i is 5. i = 5&1 is 1. Hence the result.
Predict the output or error(s) for the following:
63.     main()
{
                        int i=4,j=7;
            j = j || i++ && printf("YOU CAN");
                        printf("%d %d", i, j);
}

Answer:
4 1

Explanation:
The boolean expression needs to be evaluated only till the truth value of the expression is not known. j is not equal to zero itself means that the expression’s truth value is 1. Because it is followed by || and true || (anything) => true where (anything) will not be evaluated. So the remaining expression is not evaluated and so the value of i remains the same.
Similarly when && operator is involved in an expression, when any of the operands become false, the whole expression’s truth value becomes false and hence the remaining expression will not be evaluated.    
            false && (anything) => false where (anything) will not be evaluated.
64.    main()
{
                        register int a=2;
            printf("Address of a = %d",&a);
                        printf("Value of a   = %d",a);
}

Answer:
Compier Error: '&' on register variable
Rule to Remember:
                         & (address of ) operator cannot be applied on register variables.
65.     main()
{
                        float i=1.5;
            switch(i)
                        {
                        case 1: printf("1");
                                    case 2: printf("2");
                                    default : printf("0");
            }
}

Answer:
Compiler Error: switch expression not integral

Explanation:
Switch statements can be applied only to integral types.
66.     main()
{         
                        extern i;
            printf("%d\n",i);
                        {
                                    int i=20;
                        printf("%d\n",i);
                        }
}

Answer:
Linker Error : Unresolved external symbol i

Explanation:
The identifier i is available in the inner block and so using extern has no use in resolving it.
67.       main()
{
                        int a=2,*f1,*f2;
            f1=f2=&a;
                        *f2+=*f2+=a+=2.5;
            printf("\n%d %d %d",a,*f1,*f2);
}

Answer:
16 16 16

Explanation:
f1 and f2 both refer to the same memory location a. So changes through f1 and f2 ultimately affects only the value of a.
68.     main()
{
                        char *p="GOOD";
            char a[ ]="GOOD";
printf("\n sizeof(p) = %d, sizeof(*p) = %d, strlen(p) = %d", sizeof(p), sizeof(*p), strlen(p));
            printf("\n sizeof(a) = %d, strlen(a) = %d", sizeof(a), strlen(a));
}

Answer:
                        sizeof(p) = 2, sizeof(*p) = 1, strlen(p) = 4
            sizeof(a) = 5, strlen(a) = 4

Explanation:
                        sizeof(p) => sizeof(char*) => 2
            sizeof(*p) => sizeof(char) => 1
                        Similarly,
            sizeof(a) => size of the character array => 5
When sizeof operator is applied to an array it returns the sizeof the array and it is not the same as the sizeof the pointer variable. Here the sizeof(a) where a is the character array and the size of the array is 5 because the space necessary for the terminating NULL character should also be taken into account.
69.     #define DIM( array, type) sizeof(array)/sizeof(type)
main()
{
int arr[10];
printf(“The dimension of the array is %d”, DIM(arr, int));   
}

Answer:
10  

Explanation:
The size  of integer array of 10 elements is 10 * sizeof(int). The macro expands to sizeof(arr)/sizeof(int) => 10 * sizeof(int) / sizeof(int) => 10.
70.     int DIM(int array[])
{
return sizeof(array)/sizeof(int );
}
main()
{
int arr[10];
printf(“The dimension of the array is %d”, DIM(arr));   
}

Answer:
1  

Explanation:
Arrays cannot be passed to functions as arguments and only the pointers can be passed. So the argument is equivalent to int * array (this is one of the very few places where [] and * usage are equivalent). The return statement becomes, sizeof(int *)/ sizeof(int) that happens to be equal in this case.
71.    main()
{
            static int a[3][3]={1,2,3,4,5,6,7,8,9};
            int i,j;
            static *p[]={a,a+1,a+2};
                        for(i=0;i<3;i++)
            {
                                    for(j=0;j<3;j++)
 
                                   printf("%d\t%d\t%d\t%d\n",*(*(p+i)+j),
                                    *(*(j+p)+i),*(*(i+p)+j),*(*(p+j)+i));
                        }
}

Answer:
                                    1       1       1       1
                                    2       4       2       4
                                    3       7       3       7
                                    4       2       4       2
                                    5       5       5       5
                                    6       8       6       8
                                    7       3       7       3
                                    8       6       8       6
                                    9       9       9       9
Explanation:
                        *(*(p+i)+j) is equivalent to p[i][j].
Predict the output or error(s) for the following:
72.   main()
{
                        void swap();
            int x=10,y=8;    
                        swap(&x,&y);
            printf("x=%d y=%d",x,y);
}
void swap(int *a, int *b)
{
   *a ^= *b,  *b ^= *a, *a ^= *b;
}      
  

Answer:
x=10 y=8

Explanation:
Using ^ like this is a way to swap two variables without using a temporary variable and that too in a single statement.
Inside main(), void swap(); means that swap is a function that may take any number of arguments (not no arguments) and returns nothing. So this doesn’t issue a compiler error by the call swap(&x,&y); that has two arguments.
This convention is historically due to pre-ANSI style (referred to as Kernighan and Ritchie style) style of function declaration. In that style, the swap function will be defined as follows,
void swap()
int *a, int *b
{
   *a ^= *b,  *b ^= *a, *a ^= *b;
}
where the arguments follow the (). So naturally the declaration for swap will look like, void swap() which means the swap can take any number of arguments.
73.      main()
{
                        int i = 257;
            int *iPtr = &i;
                        printf("%d %d", *((char*)iPtr), *((char*)iPtr+1) );
}

Answer:
                        1 1

Explanation:
The integer value 257 is stored in the memory as, 00000001 00000001, so the individual bytes are taken by casting it to char * and get printed.
74.     main()
{
                        int i = 258;
            int *iPtr = &i;
                        printf("%d %d", *((char*)iPtr), *((char*)iPtr+1) );
}  
 
    
Answer:
                        2 1

Explanation:
The integer value 257 can be represented in binary as, 00000001 00000001. Remember that the INTEL machines are ‘small-endian’ machines. Small-endian means that the lower order bytes are stored in the higher memory addresses and the higher order bytes are stored in lower addresses. The integer value 258 is stored in memory as: 00000001 00000010.  
75.     main()
{
                        int i=300;
            char *ptr = &i;
                        *++ptr=2;
            printf("%d",i);
}

Answer:
556

Explanation:
The integer value 300  in binary notation is: 00000001 00101100. It is  stored in memory (small-endian) as: 00101100 00000001. Result of the expression *++ptr = 2 makes the memory representation as: 00101100 00000010. So the integer corresponding to it  is  00000010 00101100 => 556.
76.     #include
main()
{
char * str = "hello";
char * ptr = str;
char least = 127;
while (*ptr++)
                  least = (*ptr

printf("%d",least);
}

Answer:
0

Explanation:  
After ‘ptr’ reaches the end of the string the value pointed by ‘str’ is ‘\0’. So the value of ‘str’ is less than that of ‘least’. So the value of ‘least’ finally is 0.
77. Declare an array of N pointers to functions returning pointers to functions returning pointers to characters?
Answer:
                        (char*(*)( )) (*ptr[N])( );
78.     main()
{
struct student
{
char name[30];
struct date dob;
}stud;
struct date
        { 
         int day,month,year;
         };
     scanf("%s%d%d%d", stud.rollno, &student.dob.day, &student.dob.month,      &student.dob.year);
}

Answer:
Compiler Error: Undefined structure date

Explanation:
Inside the struct definition of ‘student’ the member of type struct date is given. The compiler doesn’t have the definition of date structure (forward  reference is not allowed in C in this case) so it issues an error.
79.     main()
{
struct date;
struct student
{
char name[30];
struct date dob;
}stud;
struct date
            {
         int day,month,year;
 };
scanf("%s%d%d%d", stud.rollno, &student.dob.day, &student.dob.month, &student.dob.year);
}

Answer:
Compiler Error: Undefined structure date

Explanation:
Only declaration of struct date is available inside the structure definition of ‘student’ but to have a variable of type struct date the definition of the structure is required.
80.  There were 10 records stored in “somefile.dat” but the following program printed 11 names. What went wrong?
void main()
{
struct student
{         
char name[30], rollno[6];
}stud;
FILE *fp = fopen(“somefile.dat”,”r”);
while(!feof(fp))
 {
                        fread(&stud, sizeof(stud), 1 , fp);
puts(stud.name);
}
}

Explanation:
fread reads 10 records and prints the names successfully. It will return EOF only when fread tries to read another record and fails reading EOF (and returning EOF). So it prints the last record again. After this only the condition feof(fp) becomes false, hence comes out of the while loop.
Predict the output or error(s) for the following:
81. Is there any difference between the two declarations,
1.      int foo(int *arr[]) and
2.      int foo(int *arr[2])

Answer:
No

Explanation:
Functions can only pass pointers and not arrays. The numbers that are allowed inside the [] is just for more readability. So there is no difference between the two declarations.
82.  What is the subtle error in the following code segment?
void fun(int n, int arr[])
{
int *p=0;
int i=0;
while(i++

                        p = &arr[i];
*p = 0;
}

Answer & Explanation:
If the body of the loop never executes p is assigned no address. So p remains NULL where *p =0 may result in problem (may rise to runtime error “NULL pointer assignment” and terminate the program).    
83.  What is wrong with the following code? 
int *foo()
{
int *s = malloc(sizeof(int)100);
assert(s != NULL);
return s;
}

Answer & Explanation:
assert macro should be used for debugging and finding out bugs. The check s != NULL is for error/exception handling and for that assert shouldn’t be used. A plain if and the corresponding remedy statement has to be given.
84.  What is the hidden bug with the following  statement?
assert(val++ != 0);


Answer & Explanation:
Assert macro is used for debugging and removed in release version. In assert, the experssion involves side-effects. So the behavior of the code becomes different in case of debug version and the release version thus leading to a subtle bug.
Rule to Remember:
Don’t use expressions that have side-effects in assert statements. 
85.    void main()
{
int *i = 0x400;  // i points to the address 400
*i = 0;              // set the value of memory location pointed by i;
}

Answer:
Undefined behavior

Explanation:
The second statement results in undefined behavior because it points to some location whose value may not be available for modification.  This type of pointer in which the non-availability of the implementation of the referenced location is known as 'incomplete type'.
86.     #define assert(cond) if(!(cond)) \
  (fprintf(stderr, "assertion failed: %s, file %s, line %d \n",#cond,\
 __FILE__,__LINE__), abort())
 
void main()
{
int i = 10;
if(i==0)           
    assert(i < 100);
else
    printf("This statement becomes else for if in assert macro");
}

Answer:
No output

Explanation:
The else part in which the printf is there becomes the else for if in the assert macro. Hence nothing is printed.
The solution is to use conditional operator instead of if statement,
#define assert(cond) ((cond)?(0): (fprintf (stderr, "assertion failed: \ %s, file %s, line %d \n",#cond, __FILE__,__LINE__), abort()))

Note:
However this problem of “matching with nearest else” cannot be solved by the usual method of placing the if statement inside a block like this,
#define assert(cond) { \
if(!(cond)) \
  (fprintf(stderr, "assertion failed: %s, file %s, line %d \n",#cond,\
 __FILE__,__LINE__), abort()) \
}
87.    Is the following code legal?
struct a
    {
int x;
 struct a b;
    }

Answer:
No

Explanation:
Is it not legal for a structure to contain a member that is of the same
type as in this case. Because this will cause the structure declaration to be recursive without end.
88. Is the following code legal?
struct a
    {
int x;
            struct a *b;
    }

Answer:
Yes.

Explanation:
*b is a pointer to type struct a and so is legal. The compiler knows, the size of the pointer to a structure even before the size of the structure
is determined(as you know the pointer to any type is of same size). This type of structures is known as ‘self-referencing’ structure. 
Predict the output or error(s) for the following:
89.  Is the following code legal?
typedef struct a
    {
int x;
 aType *b;
    }aType

Answer:
No

Explanation:
The typename aType is not known at the point of declaring the structure (forward references are not made for typedefs).
90. Is the following code legal?
typedef struct a aType;
struct a
{
int x;
aType *b;
};
Answer:
Yes

Explanation:
The typename aType is known at the point of declaring the structure, because it is already typedefined.
91.  Is the following code legal?
void main()
{
typedef struct a aType;
aType someVariable;
struct a
{
int x;
      aType *b;
              };
}

Answer:
No

Explanation:
                        When the declaration,
typedef struct a aType;
is encountered body of struct a is not known. This is known as ‘incomplete types’.
92.   void main()
{
printf(“sizeof (void *) = %d \n“, sizeof( void *));
            printf(“sizeof (int *)    = %d \n”, sizeof(int *));
            printf(“sizeof (double *)  = %d \n”, sizeof(double *));
            printf(“sizeof(struct unknown *) = %d \n”, sizeof(struct unknown *));
            }

Answer            :
sizeof (void *) = 2
sizeof (int *)    = 2
sizeof (double *)  =  2
sizeof(struct unknown *) =  2

Explanation:
The pointer to any type is of same size.
93.     char inputString[100] = {0};
To get string input from the keyboard which one of the following is better?
            1) gets(inputString)
            2) fgets(inputString, sizeof(inputString), fp)

Answer & Explanation:
The second one is better because gets(inputString) doesn't know the size of the string passed and so, if a very big input (here, more than 100 chars) the charactes will be written past the input string. When fgets is used with stdin performs the same operation as gets but is safe.
94.  Which version do you prefer of the following two,
1) printf(“%s”,str);      // or the more curt one
2) printf(str);

Answer & Explanation:
Prefer the first one. If the str contains any  format characters like %d then it will result in a subtle bug.
95.  void main()
{
int i=10, j=2;
int *ip= &i, *jp = &j;
int k = *ip/*jp;
printf(“%d”,k);
    
  
Answer:
Compiler Error: “Unexpected end of file in comment started in line 5”.

Explanation:
The programmer intended to divide two integers, but by the “maximum munch” rule, the compiler treats the operator sequence / and * as /* which happens to be the starting of comment. To force what is intended by the programmer,
int k = *ip/ *jp;           
// give space explicity separating / and *
//or
int k = *ip/(*jp);
// put braces to force the intention 
will solve the problem. 
96.    void main()
{
char ch;
for(ch=0;ch<=127;ch++)
printf(“%c   %d \n“, ch, ch);
}

Answer:
Implemention dependent

Explanation:
The char type may be signed or unsigned by default. If it is signed then ch++ is executed after ch reaches 127 and rotates back to -128. Thus ch is always smaller than 127.
97.   Is this code legal?
int *ptr;
ptr = (int *) 0x400;

Answer:
                        Yes

Explanation:
The pointer ptr will point at the integer in the memory location 0x400.
98.     main()
{
char a[4]="HELLO";
printf("%s",a);
}        
 

Answer:
Compiler error: Too many initializers
Explanation:
The array a is of size 4 but the string constant requires 6 bytes to get stored.
99.     main()
{         
char a[4]="HELL";
printf("%s",a);
}

Answer:
                        HELL%@!~@!@???@~~!

Explanation:
The character array has the memory just enough to hold the string “HELL” and doesnt have enough space to store the terminating null character. So it prints the HELL correctly and continues to print garbage values till it    accidentally comes across a NULL character. 
Predict the output or error(s) for the following:
100.  main()
{
                        int a=10,*j;
            void *k;
                        j=k=&a;
            j++; 
                        k++;
            printf("\n %u %u ",j,k);
}

Answer:
Compiler error: Cannot increment a void pointer

Explanation:
Void pointers are generic pointers and they can be used only when the type is not known and as an intermediate address storage type. No pointer arithmetic can be done on it and you cannot apply indirection operator (*) on void pointers.
101.    Printf can be implemented by using  __________ list.

Answer:
Variable length argument lists
102.     char *someFun()
            {
            char *temp = “string constant";
            return temp;
            }
            int main()
            {
            puts(someFun());
            }

Answer:
string constant

Explanation:
            The program suffers no problem and gives the output correctly because the character constants are stored in code/data area and not allocated in stack, so this doesn’t lead to dangling pointers.
103.     char *someFun1()
            {
            char temp[ ] = “string";
            return temp;
            }
            char *someFun2()
            {
            char temp[ ] = {‘s’, ‘t’,’r’,’i’,’n’,’g’};
            return temp;
            }
            int main()
            {
            puts(someFun1());
            puts(someFun2());
            }

Answer:
Garbage values.

Explanation:
            Both the functions suffer from the problem of dangling pointers. In someFun1() temp is a character array and so the space for it is allocated in heap and is initialized with character string “string”. This is created dynamically as the function is called, so is also deleted dynamically on exiting the function so the string data is not available in the calling function main() leading to print some garbage values. The function someFun2() also suffers from the same problem but the problem can be easily identified in this case.
104.  There were 10 records stored in “somefile.dat” but the following program printed 11 names. What went wrong?
void main()
{
struct student
{         
char name[30], rollno[6];
}stud;
FILE *fp = fopen(“somefile.dat”,”r”);
while(!feof(fp))
 {
                        fread(&stud, sizeof(stud), 1 , fp);
puts(stud.name);
}
}

Explanation:
fread reads 10 records and prints the names successfully. It will return EOF only when fread tries to read another record and fails reading EOF (and returning EOF). So it prints the last record again. After this only the condition feof(fp) becomes false, hence comes out of the while loop.




Edited By::Vignesh.j
See The Comment To download This::

3 comments:

  1. To Download This Use This Link::

    http://www.ziddu.com/download/13847961/cquestions.doc.html

    ReplyDelete
  2. Great post. Articles that have meaningful and insightful comments are more enjoyable, at least to me. It’s interesting to read what other people thought. full size air hockey table

    ReplyDelete