Operators in C language

Arithmetic operators:
These operators are used to perform arithmetic operations. The arithmetic operators are: +, -, *, / and %. The operations performed by these operators are well known to us. Now, go through the following program and predict the output. After this, execute the program and check the result.
#include<stdio.h>  
main()  
{  
 int a=10,b=20,c;  
 c=a+5-b/4*2;  
 printf("a=%d\tb=%d\tc=%d\n",a,b,c);  
}  
It is ambiguous for us to expect the output of the assignment expression c=a+5-b/4*2, so does the compiler. In order to eliminate such ambiguities precedence of the operator was introduced. Within the five arithmetic operators available, the following is the order of precedence i.e., when multiple operators occur in same statement, the compiler computes the operation based upon the precedence of the operator.
+             -              -> lower precedence
*             /              %            -> higher precedence
In, the expression c=a+5-b/4*2, / operator is of highest precedence followed by *, - and +. Hence, the operators and operands of this expression are grouped as c=(a+(5-((b/4)*2))). b/4 is computed first and the result is multiplied with 2, which is subtracted from 5, which is in turn added with a. After all the operations are performed, the result is assigned to c.
Consider the following program.
#include<stdio.h>  
main()  
{  
 int a=10,b=20;  
 b=a*b/a=b;  
 printf("a=%d\tb=%d\n",a,b);  
}  
In this, the expression b=a*b/a=b consists of the operators *, / and =. Out of these operators, * and / have same precedence. Also, there are two assignment operators. The compiler now follows associativity of the operators. Associativity gives the orientation in which the compiler should start performing the operation with the given operators on the given operands. The expression is evaluated as: b=((a*b)/(a=b)) in left-to-right fashion i.e., first a*b is evaluated, then a=b and then both the results are divided. At last, the result is assigned to b.
Click here to get the precedence and associativity table of operators in C language.
 *Remember that modulo division is not possible for real datatypes.
Relational operators:
Relational operators are used for comparison and the result is given as 0 for false and 1 for true. The relational operators in C language are <,<=,>,>=,== and !=. The functionality of all these operators are well known. Execute the following program and check the output.
#include<stdio.h>  
main()  
{  
 char ch;  
 int x=5;  
 unsigned int y=5;  
 int a=5.5;  
 float b=5.5;  
 int c;  
 c=a==b;  
 printf("c=%d\n",c);  
 c=x>y;  
 printf("c=%d\n",c);  
 ch='B';  
 c=ch>'A';  
 printf("c=%d\n",c);  
}  
In the program mentioned above, we have comparisons between variables of different datatypes. The variable x stores the integer value 5. The variable y also stores 5, the difference is the MSB in x is used for representing the sign but not the MSB of y. Though the variable a is of integer datatype, we are explicitly storing a real value into it. The variable b is of float type and 5.5 is stored into it. Observe that data from different datatypes are being compared in the latter statements.
In order to compare data of different datatypes, data is “type casted”. When compiling the above program, the compiler itself typecasts the data, which is called implicit type casting. On the other hand, if the programmer typecasts the data, it is called explicit type casting. The concept of typecasting is discussed in latter sections. As of now, just assume that type casting is converting one data type to the other.
Logical operators:
Logical AND (&&), Logical OR (||) and Logical NOT (!) are the three logical operators in C language. Execute the following program to know these logical operators.
#include<stdio.h>  
main()  
{  
 int a=0,b=10,c,d;  
 d=a&&b;  
 printf("AND:d=%d\n",d);  
 d=a||b;  
 printf("OR:d=%d\n",d);  
 d=!a;  
 printf("NOT:d=%d\n",d);  
 if((c=a&&b)&&(d=a||b))  
  printf("In if block..\n");  
 else  
  printf("In else block..\n");  
}  
*Note that any non-zero value (even if it is negative) is considered as true and only zero is considered as false. Now, execute the following program and check the output. 
#include<stdio.h>  
main()  
{  
 int a=20,b=-10,c,=0,d;  
 d=(a=b)||(b=c)||(c=a);  
 printf("a:%d\tb:%d\tc:%d\td:%d\n");  
 d=(a=b)&&(b=c)&&(c=a);  
 printf("a:%d\tb:%d\tc:%d\td:%d\n");  
}  
In this program, the outputs are not according to the expectations. Because, the gcc compiler omits executing all other conditions when any one of the conditions is false for AND and when any one of the conditions is true for OR.
In the expression d=(a=b)||(b=c)||(c=a), the expression a=b is evaluated first, which results in a non-zero value, hence true. Therefore, the other two expression b=c and c=a are omitted, as the complete expression results a non-zero value irrespective of other conditions.
In the expression d=(a=b)&&(b=c)&&(c=a), a=b results in a non-zero value, which is true. Then the compiler moves to next condition b=c, which results in a zero value, which is false. Hence, the compiler skips the expression c=a, as the complete AND results in zero irrespective of other conditions.
Bitwise operators:
As far as embedded systems are concerned, bitwise operators play a major role. The bitwise operators present in C are &,|,^,<<,>> and ~.  We are very familiar with the operations of these bitwise operators. Note that bitwise operations cannot be performed on real values.
Bitwise AND (&), OR (|), and XOR (^) performs respective operations on every single bit of the given data. The left shift operator (>>) and the right shift operator (<<) shift the bits of the given data. The complement operator (~) performs bitwise complement of the given data. Execute the following program and predict the output before executing it. Compare the expected results with the output produced after execution.
#include<stdio.h>  
main()  
{  
 int a=20,b=-100,c=0,d;  
 printf("a>>2:%d\n",a>>2);  
 printf("b>>3:%d\n",b>>3);  
 printf("b&-1:%d\n",b&-1);  
 printf("a|-1:%d\n",a|-1);  
 printf("a&0:%d\n",a&0);  
 printf("b|0:%d\n",b|0);  
 printf("a&(1<<4):%d\n",a&(1<<4));  
 printf("(a<<4)&1:%d\n",(a<<4)&1);  
 printf("1<<35:%d\n",1<<35);  
 printf("1>>35:%d\n",1>>35);  
}  
Points to remember about bitwise operators:
*Remember that any of the bitwise operators does not affect the value contained by the operators.
*Bitwise AND (&) with -1 always results in second operand.
*Any number is reduced by half, for every right shift.
Now, checkout the following program.
#include<stdio.h>  
main()  
{  
 int a=20,b=100,c=0,d;  
 printf("-30>>1:%d\n",-30>>1);  
 printf("-31>>1:%d\n",-31>>1);  
 printf("-32>>1:%d\n",-32>>1);  
}  
The output of this program is -16 and -16 for both the expression -31>>1 and -32>>1. Recollect that negative numbers are stored in their respective 2s complement format. Go through the following explanation and observe that the LBS in -31>>1 and -32>>1 goes out of the 8-bit limit of the binary representation. (For easy representation, only 8 bits were considered, which can be extrapolated to 32 bits perfectly). Observe that -30>>1 can be converted to -15, by applying 2s complement on the bits.
Example for bitwise operators
Now, check out the following program that illustrates complement operator (~). The complement of ‘a’ here is fetched as a negative value by the compiler, as the MSB is 1 in the result. Hence, the output.
In complement, the result can be expected using the equation: ~b=-b-1
#include<stdio.h>  
main()  
{  
 int a=20,b;  
 b=~a;  
 printf("a:%d\tb:%d\n",a,b);  
}  
sizeof operator:
sizeof is the operator that gives the size of the given data in bytes. Execute the following program and check the output.
#include<stdio.h>  
main()  
{  
 int a=20,b=100,c=0,d;  
 d=sizeof(a);  
 printf("%d\n",d);  
 d=sizeof(int);  
 printf("%d\n",d);  
 d=sizeof(-100);  
 printf("%d\n",d);  
 d=sizeof(1.0);  
 printf("%d\n",d);  
 d=sizeof('1');  
 printf("%d\n",d);  
}  
As the variable a is integer, it gives 4 bytes. The datatype int is of 4 bytes in size. The signed integral value -100 occupies, it gives 4 bytes. Generally, we consider the real data as floating. But, the gcc compiler considers every real data as double by default. Hence sizeof(1.0) gives 8 bytes. In the last statement, ‘1’ is considered as a character. Though it is considered as character, it is stored in the memory in the form of equivalent ASCII, which is nothing but an integer. Hence, it gives 4 bytes.
Now, consider the following program with strings.
#include<stdio.h>  
main()  
{  
 int a;  
 a=sizeof("A");  
 printf("%d\n",a);  
 a=sizeof("gcchub");  
 printf("%d\n",a);  
 a=sizeof("123.45");  
 printf("%d\n",a);  
}  
When the data to the sizeof operator is given in double quotations then every character is considered as one byte; at the same time, the string is appended with the NULL character – ‘\0’, which also needs one byte of memory. Hence, “A” gives 2 bytes, “gcchub” gives 7 bytes and “123.45” gives 6 bytes.
Finally, execute the following program to get some more details about sizeof operator.
#include<stdio.h>  
main()  
{  
 int a=20,b=100,c=50;  
 printf("%d\n",sizeof(a)>a);  
 printf("%d\n",sizeof(a)>a);  
 printf("%d\n",sizeof(c++));  
 printf("%d\n",c);  
}  
The result given by sizeof operator is of unsigned int datatype. Hence, both the comparisons sizeof(a)>a and sizeof(b)>b produce 0 as the output, as a and b are integers. In the next statement, there is sizeof(c++) and then we have printed the value of c. For our surprise, c gives the output as 50 though c++ mentioned. This is because sizeof is an operator but not a function. Hence, c++ operation cannot be performed with sizeof operator.
Ternary operator:
This is the short form of if-else statement. This operator consists of three operands and hence the name ternary operator. The syntax of ternary operator is given below.
(condition)?(operand1):(operand2);
In this, if the condition is true, then operand1 is executed and operand2 is executed otherwise.
Increment/decrement operators:
These operators are used to increment/decrement the given variable by 1.
If the increment operator is placed “post” to the operand, then it is called post increment operator; if placed before is called pre-increment operator.
If the decrement operator is placed “post” to the operand, then it is called post decrement operator; if placed before is called pre-decrement operator.
Checkout the following example to differentiate pre/post increment/decrement operators.
#include<stdio.h>  
main()  
{  
 int v=1,r;  
 r=++v;  
 printf("r:%d\tv:%d\n",r,v);  
 r=v++;  
 printf("r:%d\tv:%d\n",r,v);  
 r=--v;  
 printf("r:%d\tv:%d\n",r,v);  
 r=v--;  
 printf("r:%d\tv:%d\n",r,v);  
}  
In r=++v, v is first incremented by 1 (pre-increment) and then the value is assigned to x. In r=v++, the current value of v is assigned to x and the value of v is incremented by 1 (post increment). The same can be extrapolated to decrement operator. To be still more precise about pre/post increment/decrement operators, checkout the following program and give a try to predict the output.
#include<stdio.h>  
main()  
{  
 int a=1,b=2,c=3,r;  
 r=a++ + ++b + ++c;  
 printf("a:%d\tb:%d\tc:%d\tr:%d\n",a,b,c,r);  
 c=r++ + a-- + b--;  
 printf("a:%d\tb:%d\tc:%d\tr:%d\n",a,b,c,r);  
 b=c-- + a ++ + --r;  
 printf("a:%d\tb:%d\tc:%d\tr:%d\n",a,b,c,r);  
}  
In the statement r=a++ + ++b + ++c, initially, a=1, b=2 and c=3. Here, a is post increment, b and c are pre-increment. So, r is computed as r=1+3+4 i.e., 8. After calculating the sum, a is incremented by 1 and then, the result is assigned to r. After the execution of this statement, the status is a=2, b=3, c=4 and r=8.
In the statement c=r++ + a-- + b--, the current values are considered for operation. So, c is computed as c=8+2+3. After computing the sum, r is incremented and a, and b are decremented. After the execution of this statement, the status is a=1, b=2, c=13 and r=9.
The statement b=c-- + a++ + --r is computed as b=13+1+8. After the execution of this statement, c is decremented and a is incremented. The status is a=2, b=22, c=12 and r=8.
Share:

0 comments:

Post a Comment