C      PROGRAMMING

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>>

Want Easy lessons and exercises!! Then search here:

Google
Web www.poombatta.com



© poombatta.com