Sunday, 31 August 2014

Expressions in C and type casting

Expressions in C are basically operators acting on operands. Statements like a = b + 3++z and 300 > (8 * k) are all expressions. Strictly speaking, even a single variable or constant can be considered an expression. You have seen several expressions in the previous C tutorial on Operators in which the examples involved expressions.

Precedence and Associativity

When an expression can be interpreted in more than one way, there are rules that govern how the expression gets interpreted by the compiler. Such expressions follow C’s precedence and associativity rules. The precedence of operators determine a rank for the operators. The higher an operator’s precedence, the higher “binding” it has on the operands.
For example, the expression a * b + c can be interpreted as (a * b) + c or a * (b + c), but the first interpretation is the one that is used because the multiplication operator has higher precedence than addition.
Associativity determines the grouping of operations among operators of the same precedence. In the expression a * b / c, since multiplication and division have the same precedence we must use the associativity to determine the grouping. These operators are left associative which means they are grouped left to right as if the expression was (a * b) / c.
The operators’ order of precedence from highest to lowest and their associativity is shown in this table:
Identifier, constant or string literal, parenthesized expression
[] func( arglist ) . -> ++ —
Left associative
++ — & * + – ~ ! sizeof
Right associative
(type-name)
Right associative
* / %
Left associative
+ –
Left associative
<< >>
Left associative
< <= > >=
Left associative
== !=
Left associative
&
Left associative
^
Left associative
|
Left associative
&&
Left associative
||
Left associative
?:
Right associative
= *= /= %= += -= <<= >>= &= ^= |=
Right associative
,
Left associative
The ++ and – on the second row of the table are the postfix increment and decrement operators. The func(arglist) on the second row is a function call. Functions will be covered in detail in another tutorial.
The ++ and – on the third row are the prefix increment and decrement operators. The single + and – on the third row are unary operators used to indicate a positive value or negate a value such as +3 or-a. The & on the third row is the address-of operator; the & on the 10th row is the bitwise AND operator. The (type-name) on the fourth row is an explicit cast which will be covered later in this tutorial.
Example
  1. int a = 9;
  2. int b = 4;
  3. int c = 6;
  4.  
  5. printf(%dn”, a + b * c );
The output will be 33 because the b * c multiplication has higher precedence.
The next example demonstrates the usage assignment and relational operators. Say func() is a function that returns some value. You want to assign the returned value to a variable and perform some action if the value is 3:
  1. int a;
  2.  
  3. if ( a = func() == 3 )
  4. {
  5. 	/* do something */
  6. }
  7. /* do something with a */
However this will not work because the == has higher precedence than =, so the expression in the if statement is parsed as if (a = (func() == 3)). Therefore a is not assigned to the return value of func(), it will be set to 1 if func() returns 3, or 0 if func() does not return 3. The correct way is to use a parenthesized expression:
if (( a = func()) == 3) 
 

This example shows associativity:
int a = 3 + 4 – 2 + 7;
 
This works as you would expect. The expression is parsed as ((3 + 4) – 2) + 7 and 12 is assigned to a. Here is another dealing with associativity:
  1.  #include <stdio.h>
  2.  
  3.  void main()
  4.  {
  5.          int a = 0;
  6.          int b = !++*&a;
  7.          printf( "a = %d, b = %dn", a, b );
  8.  }

This program outputs:
a = 1, b = 0
All the operators on line 6 ( logical not, prefix increment, dereference and address-of) all have the same precedence but they are right associative. So the right operand of the = on line 6 can be written like this: ! ( ++ ( * (&a))).
This takes the address of a, then de-references it to get a again, increments it which stores 1 in a and returns 1, then takes the logical not of 1 which is 0 and assigns that to b.
These examples show that you must pay attention to operator precedence and associativity when writing expressions. Most expressions will work as expected but there are few that can surprise you.
Pay attention to the relational operators which have higher precedence than bitwise, logical and assignment operators. If you are not sure about how an expression will be interpreted then either breaks up the expression into several expressions over multiple statements or fully parenthesize the expression.
Here is a simple example of how to break up or parenthesize an expression. Suppose the original code is like this:
  1. int a;
  2. int c;
  3.  
  4. /* calculate a and c */
  5.  
  6. if ( a & 0x01 == c >> 2 )
  7. {
  8. 	/* do something */
  9. }
This will be interpreted as if (a & (0x01 == (c >> 2))) which is probably not what you wanted. You could use temporary variables like this:
  1. int expr1 = a & 0x01;
  2. int expr2 = c >> 2;
  3. if ( expr1 == expr2 )
  4. {
  5. 	/* do something */
  6. }
The other way is to add parentheses:
  1. if ((a & 0x01) == (c >> 2))
  2. {
  3. 	/* do something */
  4. }
{mospagebreak title=C Expressions – Evaluation}

C Expressions – Evaluation

It is important to note that the above section on operator precedence and associativity does not define the order that the operands are evaluated; it only defines how an expression is interpreted.  The operands to most operators may be evaluated in any order.
For example the simple expression a * b + c  is interpreted as (a * b) + c according to the precedence rules. But that does not mean a * b is evaluated first. The c variable could be evaluated first, then a * b, which in turn could evaluate either a or b.
When dealing with simple variables this is not a problem. However consider what happens if the operands to an operator have side effects:
  1.  #include <stdio.h>
  2.  
  3.    int a = 0;
  4.  
  5.    int func1()
  6.    {
  7.            a *= 3;
  8.            return a;
  9.    }
  10.  
  11.   int func2()
  12.   {
  13.           a += 3;
  14.           return a;
  15.   }
  16.  
  17.   void main()
  18.   {
  19.           int b = func1() + func2();
  20.  
  21.           printf("a = %d, b = %dn", a, b );
  22.   }
In this example both functions func1() and func2() modify the variable a and return its value. The output of the program depends on which order these functions are called on line 19. If func1() is called first it will assign 0 to a and return 0, then when func2() is called it will assign 3 to a and return 3. This leaves a and b both set to 3.
If func2() is called first, it will set a to 3 and return 3, then when func1() is called it will set a to 9 and return 9. This leaves a set to 9 and b set to 12.
Both outputs would be valid since C does not specify which operand should be evaluated first. C also does not specify in which order arguments to functions are evaluated. If in the previous example we had a function like this:
  1. int func3( int arg1, int arg2 )
  2. {
  3. 	return arg1 + arg2;
  4. }
and we changed line 19 to:
  1.          int b = func3( func1(), func2() );
We still have the same problem. Either func1() or func2() could be called first which will change the arguments passed to func3().
These examples have emphasized the fact that the order of evaluation of operands may not be what you expect. You must be especially careful with expressions that cause side effects. They could cause situations where the program works in one environment but fails in another.
{mospagebreak title=C Expressions – Type Conversions}

C Expressions – Type Conversions

Sometimes when expressions are evaluated the type of an operand is converted. These conversions may happen implicitly or explicitly. Implicit conversion is done automatically. For example when the operands to some operators have different types the smaller operand is converted to the larger operand’s type. You have already seen several examples of implicit type conversion in the tutorial on operators.
One thing to note here is that operators that take integers usually perform what is called “integer promotion” – converting smaller integral types such as char and short into int before carrying out the operation. Let us look at an example of integer promotion:
  1.    #include <stdio.h>
  2.  
  3.    void main()
  4.    {
  5.            char a = 100;
  6.            char b = 28;
  7.            int  c;
  8.            char d;
  9.  
  10.           c = a + b;
  11.           d = a + b;
  12.           printf( "c = %d, d = %dn", c, d );
  13.   }
c = 128, d = -128
 
The addition operator performs implicit integer promotion. On this environment a char is a signed 8 bit value, which has a range of -128 to 127. On line 10, though both a and b are chars they are converted into int before the addition is done, then the result is assigned to c. On line 11 the same thing happens, but the int result of 128 is converted back into a char, which causes the value to “wrap around” to -128 since a positive 128 is not within the range of a char.

C Expressions – Explicit Type Conversion

With explicit type conversion you can tell the compiler to treat a value as a certain type. The way to do explicit type conversion is with the “casting” operator.
The syntax for explicit type conversion is :
(type-name) expression
For example the expression (char *) ptr + 1 will force the compiler to treat ptr as a char pointer (“cast ptr as a char pointer”) and then add one to it. Looking at the operator precedence table above, you can see that the casting operator (on row 4) has higher precedence than the addition operator, so the cast is done first, then the addition is done.
Casting is done when the normal type conversions will not give you the result you want. This example shows the difference:
  1.  #include <stdio.h>
  2.  
  3.    void main()
  4.    {
  5.            int i = 5;
  6.            double d = i / 6;
  7.  
  8.            printf( "d = %fn", d );
  9.  
  10.           d = (double) i / 6;
  11.           printf( "d = %fn", d );
  12.   }
The output is:
d = 0.000000 d = 0.833333
 

On line 6, since i and the constant 6 are both integers an integer division is done which gives 0. On line 10 i is cast to a double, which forces the division to be done using double precision floating point values. This gives the result 0.83.
Another way to get the right result on line 10 would have been to not use the cast and instead change the constant 6 to 6.0:
  1. 10         d = i / 6.0;
Explicit type conversion is also used to change the compiler’s idea of what type a pointer is pointing to. In this next example we use void * which is basically a pointer to any type.
  1.  #include <stdio.h>
  2.  
  3.   typedef enum { INT_ARG, CHAR_ARG, DBL_ARG } ArgType;
  4.  
  5.   void printit( ArgType type, void * data )
  6.   {
  7.            switch( type )
  8.            {
  9.              case INT_ARG:
  10.                   printf("data is %dn", *(int *)data );
  11.                   break;
  12.             case CHAR_ARG:
  13.                   printf("data is %cn", *(char *)data );
  14.                   break;
  15.             case DBL_ARG:
  16.                   printf("data is %fn", *(double *)data );
  17.                   break;
  18.           }
  19.   }
  20.  
  21.   void main()
  22.   {
  23.           int i = 20;
  24.           double d = 78.9571;
  25.           char c = 'A';
  26.  
  27.           printit( CHAR_ARG, &c );
  28.           printit( INT_ARG, &i );
  29.           printit( DBL_ARG, &d );
  30.   }

The output follows:
data is A
data is 20
data is 78.957100
 

This example uses some features of C you probably have not seen before. On line 3 we define a new type called ArgType that can have one of three values: INT_ARGCHAR_ARG or DBL_ARG. The switch statement on line 7 works basically like multiple if statements, comparing type to each case value and executing the statements after the case if it is a match.
The important part for this tutorial is the code in lines 10,13 and 16. The printit() function takes two arguments. The first argument (type) tells what kind of variable the second argument (data) is pointing to. When the printit() function is called data is a pointer to void, which is basically type-less, so it may point to any different type.
However we cannot de-reference a void pointer because the compiler does not know what type it is pointing to. On line 10, if type is an INT_ARG data is cast into a pointer to an int which is then de-referenced to get the integer value. On line 13 if type is a CHAR_ARG data is cast into a pointer to char which is de-referenced to get the char value. Line 16 is similar except data is cast into a pointer to a  double.

Sunday, 24 August 2014

Some thing about Variables

A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable in C has a specific type, which determines the size and layout of the variable's memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.
The name of a variable can be composed of letters, digits, and the underscore character. It must begin with either a letter or an underscore. Upper and lowercase letters are distinct because C is case-sensitive. Based on the basic types explained in previous chapter, there will be the following basic variable types:
TypeDescription
charTypically a single octet(one byte). This is an integer type.
intThe most natural size of integer for the machine.
floatA single-precision floating point value.
doubleA double-precision floating point value.
voidRepresents the absence of type.
C programming language also allows to define various other types of variables, which we will cover in subsequent chapters like Enumeration, Pointer, Array, Structure, Union, etc. For this chapter, let us study only basic variable types.

Variable Definition in C:

A variable definition means to tell the compiler where and how much to create the storage for the variable. A variable definition specifies a data type and contains a list of one or more variables of that type as follows:
type variable_list;
Here, type must be a valid C data type including char, w_char, int, float, double, bool or any user-defined object, etc., and variable_list may consist of one or more identifier names separated by commas. Some valid declarations are shown here:
int    i, j, k;
char   c, ch;
float  f, salary;
double d;
The line int i, j, k; both declares and defines the variables i, j and k; which instructs the compiler to create variables named i, j and k of type int.
Variables can be initialized (assigned an initial value) in their declaration. The initializer consists of an equal sign followed by a constant expression as follows:
type variable_name = value;
Some examples are:
extern int d = 3, f = 5;    // declaration of d and f. 
int d = 3, f = 5;           // definition and initializing d and f. 
byte z = 22;                // definition and initializes z. 
char x = 'x';               // the variable x has the value 'x'.
For definition without an initializer: variables with static storage duration are implicitly initialized with NULL (all bytes have the value 0); the initial value of all other variables is undefined.

Variable Declaration in C:

A variable declaration provides assurance to the compiler that there is one variable existing with the given type and name so that compiler proceed for further compilation without needing complete detail about the variable. A variable declaration has its meaning at the time of compilation only, compiler needs actual variable declaration at the time of linking of the program.
A variable declaration is useful when you are using multiple files and you define your variable in one of the files which will be available at the time of linking of the program. You will use extern keyword to declare a variable at any place. Though you can declare a variable multiple times in your C program but it can be defined only once in a file, a function or a block of code.

Example

Try following example, where variables have been declared at the top, but they have been defined and initialized inside the main function:
#include <stdio.h>

// Variable declaration:
extern int a, b;
extern int c;
extern float f;

int main ()
{
  /* variable definition: */
  int a, b;
  int c;
  float f;
 
  /* actual initialization */
  a = 10;
  b = 20;
  
  c = a + b;
  printf("value of c : %d \n", c);

  f = 70.0/3.0;
  printf("value of f : %f \n", f);
 
  return 0;
}
When the above code is compiled and executed, it produces the following result:
value of c : 30
value of f : 23.333334
Same concept applies on function declaration where you provide a function name at the time of its declaration and its actual definition can be given anywhere else. For example:
// function declaration
int func();

int main()
{
    // function call
    int i = func();
}

// function definition
int func()
{
    return 0;
}

Lvalues and Rvalues in C:

There are two kinds of expressions in C:
  1. lvalue : Expressions that refer to a memory location is called "lvalue" expression. An lvalue may appear as either the left-hand or right-hand side of an assignment.
  2. rvalue : The term rvalue refers to a data value that is stored at some address in memory. An rvalue is an expression that cannot have a value assigned to it which means an rvalue may appear on the right- but not left-hand side of an assignment.
Variables are lvalues and so may appear on the left-hand side of an assignment. Numeric literals are rvalues and so may not be assigned and can not appear on the left-hand side. Following is a valid statement:
int g = 20;
But following is not a valid statement and would generate compile-time error:
10 = 20;

Sunday, 17 August 2014

About header files in C

A header file is a file with extension .h which contains C function declarations and macro definitions and to be shared between several source files. There are two types of header files: the files that the programmer writes and the files that come with your compiler.
You request the use of a header file in your program by including it, with the C preprocessing directive #include like you have seen inclusion of stdio.h header file, which comes along with your compiler.
Including a header file is equal to copying the content of the header file but we do not do it because it will be very much error-prone and it is not a good idea to copy the content of header file in the source files, specially if we have multiple source file comprising our program.
A simple practice in C or C++ programs is that we keep all the constants, macros, system wide global variables, and function prototypes in header files and include that header file wherever it is required.

Include Syntax

Both user and system header files are included using the preprocessing directive #include. It has following two forms:
#include <file>
This form is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the -I option while compiling your source code.
#include "file"
This form is used for header files of your own program. It searches for a file named file in the directory containing the current file. You can prepend directories to this list with the -I option while compiling your source code.

Include Operation

The #include directive works by directing the C preprocessor to scan the specified file as input before continuing with the rest of the current source file. The output from the preprocessor contains the output already generated, followed by the output resulting from the included file, followed by the output that comes from the text after the #include directive. For example, if you have a header file header.h as follows:
char *test (void);
and a main program called program.c that uses the header file, like this:
int x;
#include "header.h"

int main (void)
{
   puts (test ());
}
the compiler will see the same token stream as it would if program.c read
int x;
char *test (void);

int main (void)
{
   puts (test ());
}

Once-Only Headers

If a header file happens to be included twice, the compiler will process its contents twice and will result an error. The standard way to prevent this is to enclose the entire real contents of the file in a conditional, like this:
#ifndef HEADER_FILE
#define HEADER_FILE

the entire header file file

#endif
This construct is commonly known as a wrapper #ifndef. When the header is included again, the conditional will be false, because HEADER_FILE is defined. The preprocessor will skip over the entire contents of the file, and the compiler will not see it twice.

Computed Includes

Sometimes it is necessary to select one of several different header files to be included into your program. They might specify configuration parameters to be used on different sorts of operating systems, for instance. You could do this with a series of conditionals as follows:
#if SYSTEM_1
   # include "system_1.h"
#elif SYSTEM_2
   # include "system_2.h"
#elif SYSTEM_3
   ...
#endif
But as it grows, it becomes tedious, instead the preprocessor offers the ability to use a macro for the header name. This is called a computed include. Instead of writing a header name as the direct argument of #include, you simply put a macro name there instead:
 #define SYSTEM_H "system_1.h"
 ...
 #include SYSTEM_H
SYSTEM_H will be expanded, and the preprocessor will look for system_1.h as if the #include had been written that way originally. SYSTEM_H could be defined by your Makefile with a -D option

Sunday, 10 August 2014

C language keywords..

Keywords in C Programming Language :

  1. Keywords are those words whose meaning is already defined by Compiler
  2. Cannot be used as Variable Name
  3. There are 32 Keywords in C
  4. C Keywords are also called as Reserved words .

32 Keywords in C Programming Language


autodoubleintstruct
breakelselongswitch
caseenumregistertypedef
charexternreturnunion
constfloatshortunsigned
continueforsignedvoid
defaultgotosizeofvolatile
doifstaticwhile

Simple Tip :

We cannot Use Keywords for – For Declaring Variable Name,For Function Name and for declaring Constant Variable

Sunday, 3 August 2014

C – data types:


C – data types:

C data types are defined as the data storage format that a variable can store a data to perform a specific operation.

Data types are used to define a variable before to use in a program.

Size of variable, constant and array are determined by data types.

There are four data types in C language. They are,

S.no
Types
Data Types
1Basic data typesint, char, float, double
2Enumeration data typeenum
3Derived data typepointer, array, structure, union
4Void data typevoid

1. Basic data types in C:

1.1. Integer data type:

Integer data type allows a variable to store numeric values.


int” keyword is used to refer integer data type.

The storage size of int data type is 2 or 4 or 8 byte.

It varies depend upon the processor in the CPU that we use.  If we are using 16 bit processor, 2 byte  (16 bit) of memory will be allocated for int data type.

Like wise, 4 byte (32 bit) of memory for 32 bit processor and 8 byte (64 bit) of memory for 64 bit processor is allocated for int datatype.

int (2 byte) can store values from -32,768 to +32,767

int (4 byte) can store values from -2,147,483,648 to +2,147,483,647.

If you want to use the integer value that crosses the above limit, you can go for “long int” and “long long int” for which the limits are very high.

Note:



We can’t store decimal values using int data type.

If we use int data type to store decimal values, decimal values will be truncated and we will get only whole number.

In this case, float data type can be used to store decimal values in a variable.

1.2. Character data type:

  • Character data type allows a variable to store only one character.
  • Storage size of character data type is 1. We can store only one character using character data type.
  • “char” keyword is used to refer character data type.
  • For example, ‘A’ can be stored using char datatype. You can’t store more than one character using char data type.
  • Please refer C – Strings topic to know how to store more than one characters in a variable.

1.3. Floating point data type:

Floating point data type consists of 2 types. They are,
  1. float
  2. double

1. float:

Float data type allows a variable to store decimal values.

Storage size of float data type is 4. This also varies depend upon the processor in the CPU as “int” data type.

We can use up-to 6 digits after decimal using float data type.

For example, 10.456789 can be stored in a variable using float data type.

2. double:

Double data type is also same as float data type which allows up-to 10 digits after decimal.

The range for double datatype is from 1E–37 to 1E+37.

1.3.1. sizeof() function in C:

sizeof() function is used to find the memory space allocated for each C data types.

#include <stdio.h>
#include <limits.h>
int main()
{
int a;
char b;
float c;
double d;
printf(“Storage size for int data type:%d \n”,sizeof(a));
printf(“Storage size for char data type:%d \n”,sizeof(b));
printf(“Storage size for float data type:%d \n”,sizeof(c));
printf(“Storage size for double data type:%d\n”,sizeof(d));
return 0;
}                                                                                                                                                                                                   .
Output:
Storage size for int data type:4
Storage size for char data type:1
Storage size for float data type:4
Storage size for double data type:8                                                                                                                                                 .

1.3.2. Modifiers in C:

The amount of memory space to be allocated for a variable is derived by modifiers.

Modifiers are prefixed with basic data types to modify (either increase or decrease) the amount of storage space allocated to a variable.

For example, storage space for int data type is 4 byte for 32 bit processor. We can increase the range by using long int which is 8 byte. We can decrease the range by using short int which is 2 byte.


There are 5 modifiers available in C language. They are,
  1. short
  2. long
  3. signed
  4. unsigned
  5. long long


Below table gives the detail about the storage size of each C basic data type in 16 bit processor.

Please keep in mind that storage size and range for int and float datatype will vary depend on the CPU processor (8,16, 32 and 64 bit)



S.NoC Data typesstorage SizeRange
1char1–127 to 127
2int2–32,767 to 32,767
3float41E–37 to 1E+37 with six digits of precision
4double81E–37 to 1E+37 with ten digits of precision
5long double101E–37 to 1E+37 with ten digits of precision
6long int4–2,147,483,647 to 2,147,483,647
7short int2–32,767 to 32,767
8unsigned short int20 to 65,535
9signed short int2–32,767 to 32,767
10long long int8–(2power(63) –1) to 2(power)63 –1
11signed long int4–2,147,483,647 to 2,147,483,647
12unsigned long int40 to 4,294,967,295
13unsigned long long int82(power)64 –1

2. Enumeration data type in C:

  • Enumeration data type consists of named integer constants as a list.
  • It start with 0 (zero) by default and value is incremented by 1 for the sequential identifiers in the list.
  • Enum syntax in C:
enum identifier [optional{ enumerator-list }];
  • Enum example in C: 
enum month { Jan, Feb, Mar }; or
/* Jan, Feb and Mar variables will be assigned to 0, 1 and 2 respectively by default */
enum month { Jan = 1, Feb, Mar };
/* Feb and Mar variables will be assigned to 2 and 3 respectively by default */
enum month { Jan = 20, Feb, Mar };
/* Jan is assigned to 20. Feb and Mar variables will be assigned to 21 and 22 respectively by default */
  • The above enum functionality can also be implemented by “#define” preprocessor directive as given below. Above enum example is same as given below.
#define Jan 20;
#define Feb 21;
#define Mar 22;

C – enum example program:

#include <stdio.h>
int main()
{
enum MONTH { Jan = 0, Feb, Mar };
enum MONTH month = Mar;
if(month == 0)
printf(“Value of Jan”);
else if(month == 1)
printf(“Month is Feb”);
if(month == 2)
printf(“Month is Mar”);
}                                                                                                                                                                                                    .
Output:
Month is March                                                                                                                                                                                .

3. Derived data type in C:

Array, pointer, structure and union are called derived data type in C language.

4. Void data type in C:

Void is an empty data type that has no value.

This can be used in functions and pointers.