The assignment operator is used for assigning the value of an expression to a variable. The general format for an assignment operator is var = expression.
You can use other formats such as var += expression, which means var = var + expression.
Program
#include main( ) { int a,b,c,d; printf("ENTER VALUES OF a,b, c, d"); scanf("%d%d%d",&a,&b,&c); a += b*c+d; printf(" a = %d",a); } Input a = 5, b= 5, c = 7, d = 8. Output ENTER VALUES OF a,b, c, d 5 5 7 8 a = 48
Explanation
The assignment operators have the lowest priority and they are evaluated from right to left. The assignment operators are as follows:
=, +=, -=, *=, /=, %=.
Suppose the expression is
a = 5; a += 5*7+8;
You will get the value 48. It is evaluated by the following steps:
You can assign a value to multiple variables in one statement as:
i = j = k = 10 which gives value 10 to i, j, k.
You can process data using arithmetic operators such as +, -, *, and the modulus operator %. % indicates the remainder after integer division; % cannot be used for float data type or double data type. If both operands i1 and i2 are integers, the expression i1/i2 provides integer division, even if the target is a floating point variable. The operators have normal precedence rules, as follows:
Program
#include main( ) { int a,b,c,d; int sum,sub,mul,rem; float div; printf("ENTER VALUES OF b, c, d"); scanf("%d%d%d",&b&c,&d); sum = b+c; sub = b-c; mul = b*c; div = b/c; rem = b%d; a = b/c * d; printf(" sum = %d, sub = %d, mul = %d, div = %f",sum,sub,mul,div); printf(" remainder of division of b & d is %d",rem); printf(" a = %d",a); }
Input
b = 10, c = 5, d= 3.
Output
ENTER VALUES OF b, c, d 10 5 3 sum = 15, sub = 5, mul = 50, div = 2.0 remainder of division of b & d is 1 a = 6
Explanation
a = b/c * d
Here / and * both have the same priority. b/c first is evaluated because the expression is evaluated from left to right.
Relational operators are used in Boolean conditions or expressions, that is, the expressions that return either true or false. The relational operator returns zero values or nonzero values. The zero value is taken as false while the nonzero value is taken as true.
Program
Th relational operators are as follows:
<, <=, >, >=, ==, !=
The priority of the first four operators is higher than that of the later two operators. These operators are used in relational expressions such as:
7 > 12 // false 20.1 < 20.2 // true 'b' < 'c' // true "abb" < "abc" // true
The strings are compared according to dictionary comparison, so if the first characters are equal, the condition is checked for the second characters. If they are also equal then it is checked for the third character, etc. The relational operators return integer values of either zero or non zero.
Note that the equality operator is == and not =. ‘=’ is an assignment operator.
If you want to compare a and b for equality then you should write a == b, not a = b because a = b means you are assigning the value of b to a, as shown in Table 3.1.
Case |
a |
b |
a = b |
a == b |
---|---|---|---|---|
1 |
5 |
3 |
a = 3 (true) |
false |
2 |
7 |
0 |
a = 0 (false) |
false |
3 |
0 |
0 |
a = 0 (false) |
true |
In case 1, the value of a = 5 and b = 3. The assignment expression assigns the value of b to a, so a will be 3. The expression returns a true value because 3 is not zero. For the same case a == b does not make any assignment and returns a false value because in the value of a does not equal that of b.
In case 2, the value of a = 7 and b = 0. The assignment expression assigns the value of b to a, so a will be 0. The expression returns a false value of zero. For the same case, a == b does not make any assignment and returns a false value because the value of a does not equal that of b.
In case 3, the values of a and b are both 0. The assignment expression assigns the value of b to a, so a will be 0. The expression returns a false value of zero. For the same case, a == b does not make any assignment and returns a true value because the value of a equals that of b.
You can combine results of multiple relations or logical operations by using logical operation. The logical operators are negation (!), logical AND (&&), and logical OR (||), in the same order of preference.
Program
#include main( ) { int c1,c2,c3; printf("ENTER VALUES OF c1, c2 AND c3"); scanf("%d%d%d",&c1.&c2,&c3); if((c1 < c2)&&(c1
Input
c1= 2; c2= 3; c3= 4;
Output
ENTER VALUES OF c1, c2 AND c3 2 3 4 c1 is less than c2 and c3 c1 is less than c2 or c3 or both
R1 |
R2 |
R1 && R2 |
R1 || R2 |
! R1 |
---|---|---|---|---|
T |
T |
T |
T |
F |
T |
F |
F |
T |
F |
F |
T |
F |
T |
T |
F |
F |
F |
F |
T |
C1 && C2 && C3 && C4 if C1 is true
then only C2 is evaluated. If C1 is false, the expression returns false even if C2, C3, and C4 are true. So if C1 is false C2, C3, and C4 are not evaluated. Remember this when you are doing something such as searching in an array. For example, if you want to search for K in an array, the last value of which is subscript N, you can write the search condition in two ways:
I - (a [i] == K) && (i <= N) II - (i <= N) && (a[i] == K)
The technique of short-circuiting is applicable to the OR operator also. Thus if the expression is:
C1 || C2 || C3 || C4 if C1 is true
then the expression returns true and C2, C3 and C4 are not evaluated.
Ternary operators return values based on the outcomes of relational expressions. For example, if you want to return the value of 1 if the expression is true and 2 if it is false, you can use the ternary operator.
Program/Example
If you want to assign the maximum values of i and j to k then you can write the statement
k = ( i>j ) ? i : j;
If i > j then k will get the value equal to i, otherwise it will get the value equal to j.
The general form of the ternary operator is:
(expr 1) ? expr2 : expr3
If expr1 returns true then the value of expr2 is returned as a result; otherwise the value of expr3 is returned.
You can increment or decrement the value of variable using the increment or decrement operator. These operators can be applied only to variables and they can be applied using prefix form or postfix form.
Program
#include main( ) { int I,j,k; i = 3; j =4; k = i++ + --j; printf("i = %d, j = %d, k = %d",i,j,k); }
Input
i =3, j = 4.
Output
i = 4, j = 3, k = 6.
Explanation
When the prefix form is used, the value of the variable is incremented/decremented first and then applied. In the postfix form, the value is applied and only after the assignment operator is done is the value incremented or decremented.
i = 3; j =4; k = i++ + -j;
you will get the value of k as 6, i as 4 and j as 3. The order of evaluation is as follows:
i = 5; i = i++ * i++
Then you will get the value of i as 27. This is because first the value 5 is used as to make i = 25 and then i is incremented twice. The increment and decrement operators have higher priority than the arithmetic operators.
You can combine multiple expressions in a single expression using the comma operator.
Program
#include main() { int i,j,k; k = (i = 4, j = 5); printf("k = %d",k); }
Input
i = 4,j = 5.
Output
k = 5.
Explanation
For example, you can write: k = (i = 4, j = 5)
Here the expression is evaluated from left to right, that is, i = 4 is evaluated first then j = 5 is evaluated. The value of the rightmost expression is specified as output, thus k will get the value 5.
Bitwise operators interpret operands as strings of bits. Bit operations are performed on this data to get the bit strings. These bit strings are then interpreted according to data type. There are six bit operators: bitwise AND(&), bitwise OR(|), bitwise XOR(^), bitwise complement(~), left shift(<<), and right shift(>>).
Program
# include main() { char c1,c2,c3; printf("ENTER VAULES OF c1 and c2"); scanf("%c,%c",&c1,&c2); c3 = c1 & c2; printf(" Bitwise AND i.e. c1 & c2 = %c",c3); c3 = c1 | c2; printf(" Bitwise OR i.e. c1 | c2 = %c",c3); c3 = c1 ^ c2; printf(" Bitwise XOR i.e. c1 ^ c2 = %c",c3); c3 = ~c1; printf(" ones complement of c1 = %c",c3); c3 = c1<<2; printf(" left shift by 2 bits c1 << 2 = %c",c3); c3 = c1>>2; printf(" right shift by 2 bits c1 >> 2 = %c",c3); }
Input
c1 = 4; c2 = 6;
Output
ENTER VALUES OF c1 and c2 4 6 Bitwise AND i.e. c1 & c2 = 4 Bitwise OR i.e. c1 | c2 = 6 Bitwise XOR i.e. c1 ^ c2 = 2 ones compliment of c1 = -4 left shift by 2 bits c1 << 2 = 16 right shift by 2 bits c1 >> 2 = 1
Explanation
char c1, c2, c3; c1 = 4; c2 = 6;
The binary values are
c1 = 0000 0100 c2 = 0000 0110
c3 = c1 & c2;
The value of c3 is interpreted as follows:
0000 0100 & 0000 0110 ----------. 0000 0100
Each bit of c1 is compared with the corresponding bit of c2. If both bits are 1 then the corresponding bit is set as 1, otherwise it is set as 0. Thus the value of c3 is 4.
The value of c3 is interpreted as follows:
0000 0100 | 0000 0110 -----------. 0000 0110
Each bit of c1 is compared with the corresponding bit of c2. If any of the bits are 1 then the corresponding bit is set as 1; otherwise it is set as 0. Thus the value of c3 is 6.
The value of c3 is interpreted as follows:
0000 0100 ^ 0000 0110 ----------. 0000 0010
Each bit of c1 is compared with the corresponding bit of c2. If only one bit is 1, the corresponding bit is set to 1; otherwise it is set to 0. Thus you will get the value of c3 as 2 because in the second position for c1, the bit is 0 and for c2, the bit is 1. So only one bit is set.
The value of c3 is interpreted as follows:
~ 0000 0100 ----------. 1111 1011
Each bit of c1 is complemented; for 1 the complement is 0. Thus you will get the value of c3 as −4, because the leftmost bit is set as 1.
This is a left-shift operation. The bits are shifted left by two places. c1 indicates the operand that should be an expression returning a whole number. 2 indicates a shift that should not be negative, and its value must be less than the number of bits allocated to that data type.
It is evaluated as follows:
c1 is 0000 0100
It is shifted 2 bits to the left to produce
0001 00**
While shifting, the high-order (left) bits are discarded. Since a vacuum is created on the right side, it is filled with 0s to get 0001 0000. Thus the value is 16.
This is a right shift operation. The bits are shifted right by two places. c1 indicates the operand that should be an expression returning a whole number. 2 indicates a shift that should not be negative, and its value must be less than the number of bits allocated to that data type.
It is evaluated as follows:
c1 is 0000 0100
It is shifted 2 bits to the right to produce
**00 0001
While shifting, the low-order (right) bits are discarded. The asterisks are replaced using one of the following strategies:
Logical shift: In this case, the high-order bits are filled with 0s, thus you get 0000 0001.
Arithmetic shift: In this case the high-order bits are filled with the original sign bits, so if the sign bit is 1, then all bits are filled with 1s; otherwise, they are filled with 0s.
For unsigned data types, logical shift is used, whereas for signed data types arithmetic shift is used.
In these examples, the char data type which is signed is used. In number 4, the sign bit is 0, so you will get the bit pattern 0000 0001 (decimal 1).
Since C has various types of operators, it also sets precedence rules so that the value of expressions that involve multiple operators should be deterministic.
Program
The precedence of operators is given in Table 3.3.
Operators |
Order of evaluation |
Remarks |
---|---|---|
[] ( ) -> |
Left to right |
Array subscript, function call |
− + sizeof( ) ! ++ −− |
||
& * ~ (cast) |
Right to left |
Unary |
* / % |
Left to right |
Binary Multiplicative |
+ - |
Left to right |
Binary Additive |
>> << |
Left to right |
Shift operators |
< <= > >= |
Left to right |
Relational operators |
== != |
Left to right |
Equality operators |
& |
Left to right |
Bitwise And operator |
^ |
Left to right |
Bitwise Xor operator |
| |
Left to right |
Bitwise Or operator |
&& |
Left to right |
Logical And operator |
|| |
Left to right |
Logical Or operator |
?: |
Left to right |
Conditional operator |
= += -= *= /= %= |
||
&= -= |= <<= >>= |
Right to left |
Assignment |
, |
Right to left |
Comma |
Point to Remember
The operators are evaluated according to the precedence as shown in Table 3.3.
Part I - C Language
Part II - Data Structures
Part III - Advanced Problems in Data Structures