ASSIGNMENT
STATEMENTS AND OPERATORS
Operators:
Depending on the function performed, the operators can be classified as:
- Arithmetic
- Increment and Decrement
- Modulo Division
- Relational
- Logical
- Bitwise
- Conditional
- Assignment
In addition to this classification, operators can also be designated as 'unary',
'binary' or 'ternary' depending on whether they operate on one, two, or three
operands respectively.
Arithmetic operators:
The binary arithmetic operators are +, -, *, / and the modulus operator %. The
expression :
x
% y
produces
the remainder when x is divided by y, and thus is zero when y divides x exactly.
What is an operator? It is a symbol, which
represents a particular operation that can be performed on some data. The data
itself (which can be either a variable or a constant) is called the 'operand'.
The operator thus operates on an operand. It's much simple to imagine these
through an example. In the expression :
4 + 2 - 3
The symbols + and - are operators and the constants
4,2 and 3 are operands. All these operators are
'binary' operators since they operate on two operands at a time. Each of these
operators can work with ints, floats, or chars.
Increment and Decrement Operators:
C offers two special operators + + and - - called increment and decrement
operators, respectively. These are 'unary' operators since they operate on only
one operand.The operand has to be a variable and not a constant. Thus, the
expression 'a++' is valid whereas '6++' is invalid. The use of these operators
results in incrementing or decrementing the value of the variable by 1.
So the expression a++ increments the value in a by 1, and
the expression a-- decrements it by 1. These operators can be used either
before or after their operand (i.e. in either prefix or postfix position), so we
can have a++ (postfix) as well as ++a (prefix), and a-- as well as --a. Prefix
and postfix operators have the same effect if they are used in an isolated C
statement. For example, the effect of the following two statements would be the
same.
a++;
++a;
However, prefix and postfix operators have different
effects when used in association with some other operator in a C statement. For
example, if we assume the value of the variable a to be 5, then execution of the
statement :
b = ++a;
will first increase the
value of a to 6 and then assign that new value to b. The effect is exactly the
same as that of the following two statements :
a = a+1;
b = a;
On the other hand, execution of
the statement :
b = a++;
will
first set the value of b to 5 and then increase the value of a to 6.
The effect now is the same as that of the following
two statements :
b = a; a = a+1;
The decrement operators are used
in a similar way, except, of course, the value of a and
b are decreased.
First the prefix decrement :
b = --a;
which is the same as : a =a-1; b =a;
Now the postfix decrement: b = a--;
which is the same as : b =a; a =a-1;
Note that the increment and decrement operators can not only be used in
association with an assignment (=) operator, but also with any other operator
and even with printf( ). This is shown in the following program.
main(
) {
int a=10, b=10;
printf("%d", a++);
printf("%d", ++b);
}
Modulo Division Operator:
C provides one more binary arithmetic operator '%' called Modulo Division
operator. This operator is a supplement to the division operator. We use it for
division. But unlike division where we get the quotient on dividing, here we get
the remainder. For example, what is the result of the expression 5/3? The result
is 1 since it is the remainder after division.
#include<stdio.h>
main( ) {
printf("%d", 4 % 3);
printf("%d", 4 % -3);
printf("%d", -4 % 3);
printf("%d", -4 % -3);
}
The output of the first two
printf( ) statements is 1 whereas that of the next two printf()
statements is -1. This is because the sign of the output is always the same as
the sign of the numerator irrespective of the sign of the denominator.
Relational Operators:
These operators are used to compare two operands to see whether they are equal
to each other, unequal, or whether one is greater than the other. The operands
can be variables, constants or expressions that ultimately get evaluated to a
numerical value. Since characters are also represented internally as integers,
elements to be compared can be characters as well. C has six relational
operators:
|
Operator |
Meaning |
|
< |
less than |
|
> |
greater than |
|
<= |
less than or equal to |
|
>= |
greater than or equal to |
|
== |
equal to |
|
!= |
not equal to |
Each relational operator needs two operands for
comparison of their values. Hence these operators come under the category of
'binary operators'. Consider the following program.
#include<stdio.h>
main( ) {
int a=10, b=20, c=30, d, e;
d = a>b;
e = b<=c;
printf("%d %d",d,e);
}
Logical Operators:
As we saw in the last section, an expression evaluates to either true (non-zero
value) or false (zero). In a number of situations it may become necessary to
combine the results of evaluation of such expressions. For this purpose, C
provides three operators &&,|| and !, standing for
logical and, logical or, and logical not.
The && operator is usually used in situations where a set of statements are to
be executed if two expressions are true. In such cases the two expressions can
be connected as shown below:
(expression
1) && (expression 2)
If it is enough for either of them to be true then
logical or could be made use of:
(expression
1) || (expression 2)
The compound expressions formed by using relational and
logical operators again evaluate to either true or false.
The not (!) operator reverses the value of the expression it operates on. It
makes a true expression false and a false expression true. Here is an example of
the not operator applied to a relational expression.
!(y<10)
This means "not y less than 10". We
could express the same condition as :
(y>=10)
The not operator is often used to
reverse the logical value of a single variable, as in the
expression :
if(!flag)
This is another way of
saying :
if(flag
== 0)
Bitwise Operators:
The smallest element in memory on which we are able to operate as yet is a byte.
C provides six operators for bit manipulation. These may only be applied to
integral operands, i.e., char, short, int and long, whether signed or unsigned.
&
bitwise AND
| bitwise inclusive OR
^ bitwise exclusive OR
<< left shift
>> right shift
~ one's complement (unary)
The bitwise AND operator & is often
used to mask off some set of bits.
For example :
n
= n & 0177;
sets to zero all but the
low-order 7 bits of n.
The bitwise OR operator | is used to turn bits on:
x
= x | set_on;
sets to one in x the bits
that are set to one in set_on.
The bit-wise exclusive OR operator ^ sets a one in each bit position where its
operands have different bits, and zero where they are the same.
One must distinguish the bit-wise operators & and |
from the logical operators && and ||, which imply left-to-right evaluation of a
truth-value.
For example,
if
x is 1 and y is 2,
then x & y is zero while x && y is one.
The shift operators << and >> perform left and right
shifts of their left operand by the number of bit positions given by the right
operand, which must be positive. Thus x<<2 shifts the value of x left by two
positions, filling vacated bits with zero. This is equivalent to multiplication
by 4. Right shifting an unsigned quantity always fills vacated bits with zero.
Right shifting a signed quantity will fill with sign bits ("arithmetic shift")
on some machines and with 0 - bits ("logical shift") on others.
The unary operator ~ yields the one's complement of an
integer, that is, it converts each 1-bit into a 0-bit and vice versa. For
example:
x
= x & -077
sets the last six bits of x
to zero. Note that x & -077 is independent of word length, and is thus
preferable to, say, x & 0177700, which assumes that x is a 16-bit quantity. The
portable form involves no extra cost, since ~077 is a
constant expression that can be evaluated at compile time.
2.8 Conditional Operators:
The conditional operators '?' and ':' are sometimes called ternary operators
since they take three operands. Their general form is :
expression1 ?
expression2 : expression3
What this form says is : "if
expression1 is true (that is, if its value is non zero), then the value returned
will be expression2, otherwise the value returned will be expression3". Here are
a few practical examples of conditional operators.
int
x,y;
scanf("%d", &x);
y = (x > 5 ? 3 : 4);
This statement will store 3 in y if x is greater than
5, otherwise it will store 4 in y.
The Comma Operator:
The comma operator (,) permits two different expressions to appear in situations
where only one expression would ordinarily be used. The comma operator separates
the expressions. The following program illustrates the use of comma operator.
#include<stdio.h>
main(){
int a,b,c;
c= (a=10, b=20, a+b);
printf("%d", c);
}
Here, firstly value 10 is assigned to a, followed by 20
assigned to b and then the result of a + b is assigned to c.
Sizeof Operator:
The sizeof operator returns the number of bytes the operand occupies in memory.
The operand may be a variable, a constant or a data type qualifier. Consider the
following program.
#include <stdio.h>
main(){
int sum;
printf("%d", sizeof(float));
printf("%d", sizeof (sum));
printf("%d", sizeof (234L));
printf("%d", sizeof ('A'));
}
Here the first printf( )
would print out 4 since a float is always 4 bytes long. With this reasoning, the
next three printf( ) statements would output 2, 4 and
2.
Precedence of Operators:
While executing an arithmetic statement which has two or more operators, we may
have some problems about how exactly it gets executed. For example, does the
expression 2*x-3*y correspond to (2x)-(3y) or to 2(x-3y)? Similarly, does A/B*C
correspond to A/(B*C) or to (A/B)*C? The order or
priority in which the operations are performed in an expression is called
precedence of operators.
PRECEDENCE AND
ASSOCIATIVITY OF OPERATORS
|
OPERATORS |
ASSOCIATIVITY |
|
( ) [ ] - > . |
Left to right |
|
! ~ ++ -- + - * & (type) sizeof |
Right to left |
|
* / % |
Left to right |
|
+ - |
Left to right |
|
<< >> |
Left to right |
|
< <= > >= |
Left to right |
|
== != |
Left to right |
|
& |
Left to right |
|
^ |
Left to right |
|
| |
Left to right |
|
&& |
Left to right |
|
|| |
Left to right |
|
?: |
Right to left |
|
= += -= *= /= %= &= ^= |= <<=
>>= |
Right to left |
|
, |
Left to right |
Unary +, - and * have higher precedence than the binary
forms.
In case of a tie between operators of same priority
preference is given to the operator, which occurs first. For example:
Z
= a *b + c /d;
Here, a * b will be performed before c / d even though
* and / have the same priority. This is because * occurs prior to the /
operator.
Within a pair of parentheses, the same hierarchy as mentioned in the above table
is operative.
Also, if there are more than one set of parentheses, the operations within the
innermost parentheses will be performed first, followed by the operations within
the second innermost pair and so on.
Expression:
An expression is a combination of variables, constants and operators arranged as
per the syntax (grammar) of the language. C can handle any complex expression
with ease. If an expression contains an operation between an int and a float,
the int would be automatically promoted to a float before carrying out the
operation.
Type Casting:
Sometimes we are needed to force the compiler to explicitly convert the value of
an expression to a particular data type. This would be clear from the following
example:
#include<stdio.h>
main( ) {
float a ;
int x = 6, y = 4 ;
a= x/y;
printf ( "Value of a = %f",a ) ;
}
And here is the output...
Value of a = 1.000000
The answer turns out to be 1.000000 and not 1.5. This
is because, 6 and 4 are both integers and hence 6/ 4 yields
an integer, 1. This 1 when stored in a is converted
to 1.000000. But what if we don't want the quotient to be
truncated. One solution is to make either x or y as float. Let us say
that some other requirement of the program does not permit us to do this. In
such a case what do we do? Use typecasting. The following program illustrates
this.
#include<stdio.h>
main() {
float a ;
int x = 6, y = 4 ;
a = (float) x / y ;
printf("Value of a = %f", a) ;
}
And here
is the output...
Value of a = 1.500000
This program uses 'typecasting'. This consists of
putting a pair of parentheses around the name of the data type. In this program
we said,
a=(float)x/y;
The expression ( float )
causes the variable x to be converted from type int to type float before being
used in the division operation.
Assignment statements are written using the assignment
operator =. These statements are used to assign a value to a variable. The
general form of an assignment statement is:
variable
= expression;
The expression as we said in the earlier section
comprises of operands linked together by various operators.
For example:
a
= q*4/d-12/12+12/3*16/d;
x = ( a != 10 ) && ( b == 50) ;
i = 400 * 400 /400 ;
y = !x && !(!z);
z =(c>1?d>1||e>1?100:200:300);
a = ++x && ++y || --z ;
d = a & b | c;
All that it means is :
Evaluate the expression on right hand side and assign its value to the variable
on left hand side.
Consider the following :
a+=1
;
+= is a compound assignment operator. It first adds 1
to the current value of a and then assigns this new
value to a. There are several other compound assignment operators available in
C. These are:
+=, -=, *=, 1=, %=, <=, >=, |=, &= and ^=
C allows only one variable on left hand side of '='.
That is the expression z = k * 1 is legal, whereas k * 1 = z is illegal.
Arithmetic operations can be performed on chars, ints, floats and doubles. Thus
the statements,
char
x, y;
int z;
x = 'a';
y = 'b';
z = x + y;
are perfectly valid, since
the addition is performed on the ASCII values of the characters and not the
characters themselves. The ASCII values of 'a' and 'b' are 97 and 98.
A few tips for writing statements are :
No operator is assumed to be present. It must be written explicitly. In the
following example, the multiplication operator after b must be explicitly
written.
b
= c.d.b(xy) /* usual arithmetic statement */
b = c* d * b * (x * y) /* C statement */
Unlike other high level languages, there is no operator
for performing Exponentiation operation.
Thus the following statements are invalid.
a=3 * * 2;
b=3 ^ 2.;
While storing the value the expression always takes the
type of the variable into which its value is being stored.
There are several ways in which a variable can be
initialized. This is done using the assignment operator.The simplest ways to
initialize a variable, say i, to a value 10 would be :
int
i;
i = 10;
(or)
We can combine the two statements by declaring and
initializing at the same place.
For example,
int i =10;
Consider the following :
int
i ;
float b ;
i=3.5 ;
b=30;
Here in the first assignment statement though the
expression's value is a float (3.5) it cannot be stored in i since it is an int.
In such a case the float is demoted to an int and then its value is stored.
Hence what gets stored in i is 3. Exactly opposite
happens in the next statement.
HOME
<<PREVIOUS
NEXT>> |