Users Online

· Guests Online: 3

· Members Online: 0

· Total Members: 185
· Newest Member: meenachowdary055

Forum Threads

Newest Threads
No Threads created
Hottest Threads
No Threads created

Latest Articles

FAQ: C Operators and Expressions

FAQ (Frequently Asked Questions) >C Operators and Expressions
01 What is a C Expression02 What is the Difference Between a C Expression and C Statement03 Explain Various Operators in C Language04 Explain Operator Precedence and Associativity in C Programming
05 Explain Assignment Operators in C with Examples06 Explain Arithmetic Operators in C with Examples07 Explain Logical and Arithmetic Shifts in C Language with Examples08 Explain Bitwise Operators in C with Examples
09 Explain Relational Operators in C with Examples10 Explain Logical Operators in C with Examples11 Explain Increment and Decrement Operators in C with Examples12 Explain Conditional Operator in C with Examples
13 Explain Comma Operator in C with Examples14 What are Boolean Values and Whether C have an Explicit Boolean Type15 Explain sizeof Operator and its Return Value in C Language with Examples16 What is Cast Operator in C Programming
17 Explain Unary Operators in C Programming with Examples18 Explain L and R Values in C Language with Examples19 How can One Determine Whether a Right Shift of a Signed Value is Performed as an Arithmetic or a Logical Shift
01 What is a C Expression
This C Tutorial Explains C Expression.
A C expression is any combination of operators and operands. For example:

50; /* an integer constant */
543.0009; /* a real constant */
x + y; /* sum y to x */
hall >= room; /* a relational exp */
value = a * b / (c * d + a) /* an arithmetic exp */
An operator is what something that performs some predefined action on operand/ operands and an operand is some variable, sub-expression or some value. For example:

x + y;
/* plus '+' is a binary operator operates on two operands x and y and */
/* computes their sum */
Every C expression has a Numeric value. There are certain Rules regarding the evaluation of expressions. The Operator Precedence & its Associativity determine in which order & which operators to be evaluated first, next and so on in a given expression. For example:


x = 20;
/* assignment operator '=' assigns value to right of this to the */
/* variable left of this. result of exp x = 20; is 20 */

y = 20;
z = x + y; /* z gets value 40 */
x + y; /* this expression results 40 */
x > y; /* relational expression results 0 here */
Relational Expressions, Logical Expressions have values either True or False that is 1 or 0. C99 standard provides a new type _Bool which allows only two values 0 & 1 for false & true.

A C program comprises of Statements each of which, mostly, in turn comprises of expressions. For example:

#include <stdio.h>
#define R2Y 1.64 /* Rupee to Yen */
#define Y2R 0.6093 /* Yen to Rupee */

int main(void)
{
int choice;
float yens, rupees;

printf("user, wanna to convert Yen to Rupee, enter 1 ornif you "
"wanna to convert Rupee to Yen, enter 2nor enter q to "
"quitn");

while (scanf("%d", &choice) == 1) {
if (choice == 1) {
printf("user, enter what many YENs u wanna to convert to "
"Rupees...n");
scanf("%f", ¥s);
printf("%.2f YENs equal %.6f Rupees!nn", yens,
yens * Y2R);
}
else if (choice == 2) {
printf("user, enter what many RUPEEs u wanna to convert to "
"YENs...n");
scanf("%f", &rupees);
printf("%.2f RUPEEs equal %.6f YENs!nn",
rupees, rupees * R2Y);
}
printf("user, wanna to convert Yen to Rupee, enter 1 or nif "
"you wanna to convert Rupee to Yen, enter 2nor enter q "
"to quitn");
}
printf("Thank You!n");
return 0;
}
In the above program, we used return value of scanf() fun to terminate the loop. When we enter q to quit, scanf() failed to read & returns 0 and therefore loop terminates.


A C expression may also contain sub expression. For example:

x + y * (a = b / c); /* (a = b / c) is a sub-exp */

/* In the above exp., sub-exp is evaluated first because parentheses have */
/* higher precedence. */
/* The result of sub-exp is value of the variable to the left side of the */
/* assignment operator.*/
/* result is then multiplied to the value of y. Then the product is added */
/* to x */


Top
02 What is the Difference Between a C Expression and C Statement
Question: Differentiate between a C Expression and a C Statement.
Answer: Every C program comprises of Statements. Program executes statement by statement. Each statement generally, in turn, comprises of some expression. And an expression may further comprise of sub-expressions. For example:

/* diff_statements.c */

#include <stdio.h>
#define SIZE 10 /* SIZE symbolic constant */

int main(void)
{
int index, sum; /* declaration statement */
int boys[SIZE]; /* array declaration */

printf("user enter no of boys in 10 classes...n");
/* function statement */

for (index = 0; index < SIZE; index++)
scanf("%d", &boys[index]);

/* for statement with single statement */

/* IT'S A GOOD PRACTICE TO REVIEW IF U ENTERED CORRECT VALUES */

printf("No. of boys you entered for 10 classes are as:n");
for (index = 0; index < SIZE; index++)
printf("%dt", boys[index]);
printf("n");

printf("Summing up & Displaying boys in all classes...n");

/* for statement with block of statements */
for (index = 0; index < SIZE; index++) {
sum += boys[index];
; /* Null Statement; this does nothing here */
}

printf("Total boys in %d classes is %dn", SIZE, sum);
return 0;
}
Every C statement ends with a semicolon ‘;’. While expressions don’t. For example:



x + y; /* x + y is an exp but x + y; is a statement. */
5 + 7; /* similarly as above */

while (5 < 10) {
/* 5 < 10 is a relational exp, not a statement. */
/* used as a while test condition */

/* other statements in while loop */
}

result = (float) (x * y) / (u + v);
okey = (x * y) / (u + w) * (z = a + b + c + d);

/* (z = a + b + c + d) is a sub-expression in the above */
/* expression. */
Remember, if we remove the semicolon ‘;’ from a statement, It’ll not always be some expression. For example:

int man; /* declaration statement */
int man /* removed the semicolon */

/* But man isn't an expression because exp don't have types */
/* associated with them. */
Keep in mind that all Loops, Branching or Selection expressions are single statements. Each of this begins from its Keyword continues till first semicolon is found or until closing brace of the following compound/block statement. For example:



for (index = 0; index < SIZE; index++)
printf("read in next value.n"); /* for ends here */

for (index = 0; index < SIZE; index++) {
printf("read in next valuen");
scanf("&d", &boys[index]);
} /* for statement with compound statement */

if (celcius == farenheit)
printf("display the temperature.");
/* if ends with a semicolon */

if (celcius == farenheit) {
printf("fine!n");
printf("let's check some other temperaturen");
} /* if ends with closing brace of compound statement */

Because they owe Special Structures, Loops & Branching or Selection statements are also referred to as Structured Statements.
Top
03 Explain Various Operators in C Language
This C Tutorial Explains Operator & Various Types of Operators in C Language.
An Operator is something that performs some fixed, predefined action on its operands. For example:

15 + 34; /* '+' operator adds 34 to 15 */
x * y; /* '*' multiplication operator here */
-x; /* '-' minus operator changes the sign of its operand */
++y; /* increment operator */
C offers huge set of operators comparative to other programming languages especially to meet every possible programming need. There are some 40 different types of operators in C. Further, these operators depending upon their actions on the number of operands at a time are categorized as Unary Operators which have one operand, Binary Operators which have two operands and Ternary Operators which takes three operands. For example:

/* diff_operators.c: Program displays some common c operators */

#include <stdio.h>

int main(void)
{
int num1, num2;
int sum;

num1 = num2 = 10; /* num1 & num2 both r 10 */

/* '=' assignment operator assigns value of exp/variable at its right */
/* to var at its left. '=' operator associates from right to left */

sum = num1 + num2;

/* Plus '+' is a binary operator. It adds value of num2 to num1. */
* Result is assigned to sum by the assignment operator. */

-num1;

/* Minus '-' is here a Unary Operator. */
/* It changes sign of its operand. num1 is now -10. */

--num1;

/* '--' is a unary operator called decrement operator. */
/* comes in two versions: prefix & postfix. */
/* it reduces its operand value by 1. num1 now became -11. */

return 0;
}
Various C Operators & their Meaning:

Arithmetic Operators

+ adds the value at its right to the value at its left.
+, as a unary operator, produces a value equal in magnitude (and of the same sign) to the operand to the right.

– subtracts the value at its right from the value at its left.
–, as a unary operator, produces a value equal in magnitude (but opposite in sign) to the operand to the right.

* multiplies the value at its right by the value at its left.
/ divides the value at its left by the value at its right. The answer is truncated if both operands are integers.
% yields the remainder when the value at its left is divided by the value to its right (integers only).

++ adds 1 to the value of the variable to its right (prefix mode) or adds 1 to the value of the variable to its left (postfix mode).

— is like ++, but subtracts 1.

Relational Operators

Each of the following operators compares the value at its left to the value at its right:


< Less than
<= Less than or equal to
== Equal to
>= Greater than or equal to
> Greater than
!= Unequal to

Assignment Operators

C has one basic assignment operator and several combination/arithmetic assignment operators. The = operator is the basic form.

= assigns the value at its right to the lvalue on its left. lvalue is modifiable value. lvalue or modifiable lvalue refers to some location in the memory into which to hold some value.

Each of the following assignment operators updates the lvalue at its left by the value at its right, using the indicated operation (we use R–H for right-hand and L–H for left-hand):

+= adds the R–H quantity to the L–H variable and places the result in the L–H variable.
-= subtracts the R–H quantity from the L–H variable and places the result in the L–H variable.

*= multiplies the L–H variable by the R–H quantity and places the result in the L–H variable.
/= divides the L–H variable by the R–H quantity and places the result in the L–H variable.
%= gives the remainder from dividing the L–H quantity by the R–H quantity and places the result in the L–H variable.

&= assigns bitwise & of L–H and R–H to the L–H quantity/l-H variable.
|= assigns bitwise | of L–H and R–H to the L–H quantity/L–H variable.
^= assigns bitwise ^ of L–H and R–H to the L–H quantity/L–H variable.

>>= assigns L–H >> R–H to the L–H quantity and places the result in the L–H variable.
<<= assigns L–H << R–H to the L–H quantity and places the result in the L–H variable.

Logical Operators

There are three Logical Operators in C. They normally take relational expressions as operands. The ! operator takes one operand. The rest take two: one to the left, and one to the right.

&& AND
|| OR
! NOT

The Conditional Operator/Ternary Operator

? : takes three operands, each of which is an expression. They are arranged this way:

expression1 ? expression2 : expression3


The value of the whole expression equals the value of expression2 if expression1 is true, and equals the value of expression3 otherwise.

Pointer-Related Operators

& is the address operator. When followed by a variable name, & gives the address of that variable.
* is the indirection or dereferencing operator. When followed by a pointer, * gives the value stored at the pointed-to address.

Sign Operators

– is the minus sign and reverses the sign of the operand.
+ is the plus sign and leaves the sign unchanged.

All the following bitwise operators, except ~, are binary operators:

Bitwise Operators

~ is the unary operator and produces a value with each bit of the operand inverted.
& is AND and produces a value in which each bit is set to 1 only if both corresponding bits in the two operands are 1.
| is OR and produces a value in which each bit is set to 1 if either, or both, corresponding bits of the two operands are 1.
^ is EXCLUSIVE OR and produces a value in which each bit is set to 1 only if one or the other (but not both) of the corresponding bits of the two operands is 1.
<< is left-shift and produces a value obtained by shifting the bits of the left-hand operand to the left by the number of places given by the right-hand operand. Vacated slots are filled with zeros. >> is right-shift and produces a value obtained by shifting the bits of the left-hand operand to the right by the number of places given by the right-hand operand. For unsigned integers, the vacated slots are filled with zeros. The behaviour for signed values is implementation dependent.

Miscellaneous Operators

sizeof yields the size, in units the size of a char value, of the operand to its right. Typically, a char value is 1 byte in size. The operand can be a type-specifier in parentheses, as in sizeof (float), or it can be the name of a particular variable, array, or so on, as in sizeof boys. A sizeof expression returns value of type size_t.

(type) is the cast operator and converts the value that follows it to the type specified by the enclosed keyword(s). For example, (float) 9 converts the integer 9 to the floating-point number 9.0.

, is the comma operator; it links two or more expressions into one and guarantees that the leftmost expression is evaluated first. The value of the whole expression is the value of the right-most expression. This operator is typically used to include more information in a for loop, while loop control expression.
Top
04 Explain Operator Precedence and Associativity in C Programming
This C Tutorial Explains Operator Precedence and its Associativity in C Programming.
A meaningful Expression in C is a combination of Operators and Operands. An operator performs a fixed, predefined action on its two operands if it’s a Binary Operator or operates on its single operand if it’s a Unary Operator. Most of the operators in C are Binary Operators. For example:

int x, y;
int sum;
50L; /* such exp. is doing nothing, so of no use */

printf("Read in two integer numbers for their sum...n");
scanf("%d %d", &x, &y);

sum = x + y;

/*
* Plus '+' adds y to x
* Assignment operator '=' then assigns result to sum
*/

/*
* Notice in the above exp. sum = x + y; there are two operators
* '=' and '+'. How do we decide which of two operators to be
* evaluated first? There are Certain Rules C language determines
* for the correct evaluation of expressions so programs are
* portable across different platforms.
*/
Rules of operator precedence help determine how terms are grouped when expressions are evaluated. When two operators share an operand, the one of higher precedence is applied first. If the operators have equal precedence, the associativity (left-right or right-left) determines which operator is applied first. Besides, Rules of Type Conversions, when an expression comprises of several different types of values/variables, must also be accounted for the correct evaluation of the expression.

Rules of Type Conversions

Statements and expressions should normally use variables and constants of just one type. If, however, we mix types, C doesn’t stop us from doing so. Instead, it uses a set of rules to make type conversions automatically. This can be a convenience, but it can also be a danger, especially if you are mixing types inadvertently.

The basic rules are

When appearing in an expression, char and short, both signed and unsigned, are automatically converted to int or, if necessary, to unsigned int. (If short is the same size as int, unsigned short is larger than int; in that case, unsigned short is converted to unsigned int.) Because this involves conversion to higher types, these are called Promotions.

In any operation involving two types, both values are converted to the higher ranking of the two types.

The ranking of types, from highest to lowest, is:

long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int, and int.

One possible exception is when long and int are the same size, in which case unsigned int outranks long. The short and char types don’t appear in this list because they would have been already promoted to int or perhaps unsigned int.

In an assignment statement, the final result of the calculations is converted to the type of the variable being assigned a value. This process can result in promotion, as described in rule 1, or demotion, in which a value is converted to a lower-ranking type.

When passed as function arguments, char and short are converted to int, and float is converted to double. This automatic promotion can be overridden by function prototyping.

Promotion is usually a smooth, uneventful process, but demotion can lead to real trouble. The reason is simple: The lower-ranking type may not be big enough to hold the complete number. An 8-bit char variable can hold the integer 100 but not the integer 1000000. When floating types are demoted to integer types, they are truncated, or rounded toward zero. That means 23.01 and 23.99 both are truncated to 23 and that -23.6 is truncated to -23 which causes Loss of Information. For example:

/* convert.c -- automatic type conversions */

#include <stdio.h>

int main(void)
{
char ch;
int i;
float fl;

fl = i = ch = 'C';

/*
* character ch is promoted to signed integer when assigned to integer i
* integer i then promoted to float when assigned to type float value fl
*/

printf("ch = %c, i = %d, fl = %2.2fn", ch, i, fl);

ch = ch + 1;
/*
* ch is character & 1 is signed integer therefore, character ch is
* promoted to signed integer first, computes sum then while assigning
* sum, this is demoted to character because value to the left of
* assignment is of type char
*/

i = fl + 2 * ch;
/*
* firstly multiplication is performed because of higher precedence so
* ch is promoted to integer then result of multiplication is promoted
* to float to be summed to value fl of type float final result is
* demoted to integer to be assigned to variable i of type int
*/

fl = 2.0 * ch + i;

printf("ch = %c, i = %d, fl = %2.2fn", ch, i, fl);

ch = 5212205.17;
/* 8-bit char can't occupy such big value */

printf("Now ch = %cn", ch); /* some unexpected result */
return 0;
}
Table of C Operators with their Precedence & Associativity




Top
05 Explain Assignment Operators in C with Examples
This C Tutorial Explains Different Assignment Operators in C with Examples.
The basic assignment operator in C Programming Language is ‘=’, which we know as “equal to” in Mathematics. However, in C this is not to be confused with “equal to” but this performs different operation on its operands. This operator assigns value of expression/variable/constant at its right to the variable at its left. Every expression in C evaluates to some value. For example: Valid assignment statements.

result = (x * y) / (u + v);
value = x + y;
more = ++yes;
int const TRUE = 1;
int const FALSE = 0;

/*
* In C, variable names should be in lower case. However, Constants
* are named in Capitals. Above, TRUE and FALSE are constants.
*/
The right side value of the assignment is called rvalue and left side of the assignment is called lvalue or modifiable lvalue. lvalue refers to memory location or region of actual data storage or data object to hold value into while rvalue refers to value of some expression or variable or constant which is to be assigned to lvalue. Not all data objects can have their values changed therefore data objects that can change values are called modifiable lvalues. lvalue can not be a constant. For example:

56 = x + y + z;
/*
* since lvalue must be a location to hold value into it. 56 is not a
* location, instead this is a value. Not a valid assignment statement
*/
Another example:

/* assignment.c -- program displays use of assignment operator */
#include <stdio.h>
int main(void)
{
int one, two, three;
one = two = three = 68;

/* one, two and three, each assigned 68 */
/* associativity of assignment operator is from right to left */

printf(" one two three");
printf("First round score %4d %8d %8dn", one, two, three);

return 0;
}
Operator Precedence
Consider the following line of code:

result = 19.0 + 20.0 * n / SCALE;
This statement has an addition, a multiplication, and a division operation. Which operation takes place first? Is 20.0 added to 19.0, the result of 39.0 then multiplied by n, and that result then divided by SCALE? Is 20.0 multiplied by n, the result added to 19.0, and that answer then divided by SCALE? Is it some other order? Let’s take n to be 6.0 and SCALE to be 2.0. If you work through the statement using these values, you will find that the first approach yields a value of 117.0. The second approach yields 69.5. A C program must have some other order in mind, because it would give a value of 79.0 for result.


Clearly, the order of executing the various operations can make a difference, so C needs unambiguous rules for choosing what to do first. C does this by setting up an operator precedence order. Each operator is assigned a precedence level. As in ordinary arithmetic, multiplication and division have a higher precedence than addition and subtraction, so they are performed first. What if two operators have the same precedence? If they share an operand, they are executed according to the order in which they occur in the statement. For most operators, the order is from left to right. (The = operator was an exception to this.) Therefore, in the statement

result = 19.0 + 20.0 * n / SCALE;
The order of operations is as follows:

20.0 * n

The first * or / in the expression (assuming n is 6 so that 20.0 * n is 120.0)

120.0 / SCALE

Then the second * or / in the expression

19.0 + 60

Finally (because SCALE is 2.0), the first + or – in the expression, to yield 79.0

Operators in Order of Decreasing Precedence

Operators Associativity

() Left to right
+ - (unary) Right to left
* / Left to right
+ - (binary) Left to right
= Right to left
More Assignment Operators: +=, -=, *=, /=, %=

C has several assignment operators. The most basic one, of course, is =, which simply assigns the value of the expression at its right to the variable at its left. The other assignment operators update variables. Each is used with a variable name to its left and an expression to its right. The variable is assigned a new value equal to its old value adjusted by the value of the expression at the right. The exact adjustment depends on the operator. For example,

scores += 20; is the same as scores = scores + 20;
dimes -= 2; is the same as dimes = dimes - 2;
bunnies *= 2; is the same as bunnies = bunnies * 2;
time /= 2.73; is the same as time = time / 2.73;
reduce %= 3; is the same as reduce = reduce % 3;
Well! The preceding list uses simple numbers on the right, but these operators also work with more elaborate expressions, such as the following:

x *= 3 * y + 12;
x = x * (3 * y + 12); /* both statements are same */
The assignment operators we’ve just discussed have the same low priority that = does—that is, less than that of + or *. This low priority is reflected in the last example in which 12 is added to 3 * y before the result is multiplied by x.

You are not required to use these forms. They are, however, more compact, and they may produce more efficient machine code than the longer form. The combination assignment operators are particularly useful when you are trying to squeeze something complex into a for loop specification.
Top
06 Explain Arithmetic Operators in C with Examples
This C Tutorial Explains Various Arithmetic Operators in C Language with examples.
We have following arithmetic operators:

+ (addition), – (subtraction), * (multiplication), / (division) and % (modulus/remainder)

All Arithmetic Operators are binary operators i.e. each operates on two operands. We take one by one to understand them.

Addition Operator: +

The addition operator causes the two values flanking on either side of it to be added together. For example:

printf("%d", 5 + 20);

/* printf() statement causes 25 to be printed & not the exp. 5 + 20 */
The operands to be added can be variables, constants or other expressions or sub-expression as well. For Example:

income = salary + bribes;

/*
* statement causes the computer to look up the values of the two
* variables on the right, add them up, and then assign this total
* to the variable income.
*/
Subtraction Operator: –

The subtraction operator causes the number after the – sign to be subtracted from the number before the sign. For Example:

takehome = 200.00 – 100.00;

/* The statement assigns the value 100.00 to takehome. */
Sign Operators: – and +

The minus sign can also be used to indicate or to change the algebraic sign of a value. For instance:

rocky = –12; /* assigns -12 to rocky */
smokey = –rocky; /* gives smokey the value 12 */
When the minus sign is used in this way, it is called a unary operator, meaning that it takes just one operand. The C90 standard adds a unary + operator to C. It doesn’t alter the value or sign of its operand; it just enables us to use statements, for example, like,

count = +12;

advertisements

without getting a compiler complaint.

Multiplication Operator: *

Multiplication is indicated by the * symbol. For example:

cm = 2.54 * inch;
/* statement multiplies variable inch by 2.54 & assigns product to cm */
Well! If you want a table of squares? C doesn’t have a squaring function, but, we can use multiplication to calculate squares. For example:

/* squares.c -- produces a table of first 25 squares */
#include <stdio.h>
int main(void)
{
int num = 1;

while (num <= 25) {
printf("%4d %6d\n", num, num * num);
num = num + 1;
}
return 0;
}
Division Operator: /

C uses the / symbol to represent division. The value to the left of the / is divided by the value to the right. For example,

val = 15 / 3;

/* statement gives variable val the value of 5 */
Division works differently for integer types than it does for floating types. Floating-type division gives a floating-point answer, but integer division yields an integer answer. An integer can’t have a fractional part, which makes dividing 10 by 3 awkward, because the answer does have a fractional part. In C, any fraction resulting from integer division is discarded. This process is called truncation.

We consider an example to see how truncation works and how integer division differs from floating-point division. For example,

/* division.c -- integer, floating-pt and mix divisions */
#include <stdio.h>

int main(void)
{
printf("integer division: 10 / 4 is %d \n", 10 / 4);
printf("integer division: 12 / 3 is %d \n", 12 / 3);
printf("integer division: 9 / 4 is %d \n", 9 / 4);
printf("floating division: 9. / 4. is %1.2f \n", 9. / 4.);
printf("mixed division: 9. / 4 is %1.2f \n", 9. / 4);

return 0;

/*
* Last printf() call includes a case of "mixed types" by having a
* floating-point value divided by an integer. Normally we should
* avoid mixing types.
*/
}
Sample Run of the above program:

integer division: 10 / 4 is 2
integer division: 12 / 3 is 4
integer division: 9 / 4 is 2
floating division: 9. / 4. is 2.25
mixed division: 9. / 4 is 2.25

Notice how integer division does not round to the nearest integer, but always truncates (that is, discards the entire fractional part). When we mixed integers with floating point, the answer came out the same as floating point. Actually, the computer is not really capable of dividing a floating-point type by an integer type, so the compiler converts both operands to a single type. In this case, the integer is converted to floating point before division.

Now, let’s see how integer division with negative numbers work. One could take the view that the rounding procedure consists of finding the largest integer smaller than or equal to the floating-point number. Certainly, 3 fits that description when compared to 3.9. But what about –3.9? The largest integer method would suggest rounding to –4 because –4 is less than –3.8. But another way of looking at the rounding process is that it just dumps the fractional part; that interpretation, called truncating toward zero, suggests converting –3.9 to –3. C99 standard says just truncate the fractional part.


Now, what happens when we combine more than one operation into one statement? Then we check for operator precedence.

Operator Precedence

Consider the following line of code:

result = 19.0 + 60.0 * n / SCALE;
This statement has an addition, a multiplication, and a division operation. Which operation takes place first? Is 19.0 added to 60.0, the result of 79.0 then multiplied by n, and that result then divided by SCALE? Is 60.0 multiplied by n, the result added to 19.0, and that answer then divided by SCALE? Is it some other order? Let’s take n to be 6.0 and SCALE to be 2.0. If you work through the statement using these values, you will find that the first approach yields a value of 237. The second approach yields 189.5. A C program must have some other order in mind, because it would give a value of 199.0 for result.

Clearly, the order of executing the various operations can make a difference, so C needs unambiguous rules for choosing what to do first. C does this by setting up an operator pecking order. Each operator is assigned a precedence level. As in ordinary arithmetic, multiplication and division have a higher precedence than addition and subtraction, so they are performed first. What if two operators have the same precedence? If they share an operand, they are executed according to the order in which they occur in the statement. For most operators, the order is from left to right. (The = operator operates from right to left) Therefore, in the statement

result = 19.0 + 60.0 * n / SCALE;
The order of operations is as follows:

60.0 * n

The first * or / in the expression (assuming n is 6 so that 60.0 * n is 360.0)

360.0 / SCALE

Then the second * or / in the expression

19.0 + 180

Finally (because SCALE is 2.0), the first + or – in the expression, to yield 199.0
Top
07 Explain Logical and Arithmetic Shifts in C Language with Examples
This C Tutorial Explains Logical and Arithmetic Shifts in C Language with Examples.
A single Bit is the basic unit of Storage, stores either 1 or 0. Therefore as bits move left or right in a value of specific type viz. integer, char etc. their values change. Moving bits in a value in C Language is performed using Left or Right Shift Operators. Because these operators operate on individual bits, these are called Bitwise operators. These operators work on individual bits of values of variables of Integer Data Type in their signed or unsigned form. Characters are internally integers and these operators, therefore, work with them.

Left shift operator is represented by “<<" symbol and right shift by ">>” symbol. These operators are Binary operators, require two operands on either side and both must be integers. The syntax for left and right shift is as follows:

variable-name right/left-shift-operator no-of-bits-by-which-to-shift;

val >> 5; /* shift the value in val to the right by 5 bits */
num << 5; /* shift the value in num to the left by 5 bits */
Shifting is called to be Logical when performed on unsigned integers in either direction, either right or left. In Logical Shift, during shifting either side, empty slots are padded with Zeros. For example:

/*
* rlshift.c -- program uses left and right shift operators with unsigned
* integers
*/
#include <stdio.h>
int main(void)
{
unsigned int b = 16, result;

printf("value of exp. result = b >> 3 is %d\n", result = b >> 3);
printf("value of b after right shift by 3 bits, is %d\n", b);
printf("value of exp. result = b << 3 is %d\n", result = b << 3);
printf("value of b after left shift by 3 bits, is %d\n", b);

/* note that value of b remains same after left or right shift */
/* only result changes */

return 0;
}

Shifting a value to the right by n bits has the effect of dividing the value by the power of 2 raised to n and shifting the value to left by n bits has the effect of multiplying value by power of 2 raised to n. For example:

/*
* rlshift_effect.c -- program displays result of left or right shift of
* values of unsigned integers
*/
#include <stdio.h>
int main(void)
{
unsigned int b = 16;

printf("value of exp. b >>= 3 is %d\n", b >>= 3);
printf("value of b after right shift by 3 bits, is %d\n", b);
printf("value of exp. b <<= 3 is %d\n", b <<= 3);
printf("value of b after left shift by 3 bits, is %d\n", b);

/*
* note that value of b after right shift by 3 bits is as
* dividing it by 2 raised to 3
* and shifting it to left by 3 bits has effect of it is being
* multiplied by 2 raised to 3
*/

return 0;
}
Now, we consider what happens when the value in the variable is shifted either side but by Negative Number or what happens when shift counts are larger than number of bits in the operand. For example:

boys >> -6;
boys << -6;
boys >> 35;
The standard states that the behaviour of such Shifts is implementation specific. We should avoid using such types of shifts because their effects are unpredictable and non-portable.

Arithmetic Shifts

So far, we considered shifting of unsigned integer numbers right or left by given bits, and filled in thus produced empty spaces with zeroes. When Arithmetic right shift is performed on negative number, then sign bit is copied to the empty slots created in shifting. For example:


/* rshift_negtive_val.c -- program performs right shift on -ve integers */
#include <stdio.h>
int main(void)
{
int hall = -16;

printf("value of exp. hall >>= 3 is %d\n", hall >>= 3);
printf("value of hall, -ve value, after right shift by 3 bits, "
"is %d\n", hall);

/*
* negative numbers are stored in computer in 2's complement form result
* of right shift of a -ve number is -ve because sign bit 1 is copied
* into empty slots
*/

return 0;
}
Arithmetic and Logical left shifts are Identical. Only the right shifts differ, and then only for negative values. Therefore, programs that do right shifts on signed values are inherently non-portable.

Uses of Shift Operators:
For example:

/* count_one_bit.c: Program counts 1 bits in a given unsigned integer */

#include <stdio.h>
void count1bits(int);

int main(void)
{
int num;

printf("enter some unsigned integer number\n");
scanf("%d", &num);

count1bits(num); /* call to fun. */
return 0;
}
void count1bits(int num1)
{
int ones = 0;

while (num1 != 0) {
if (num1 % 2 != 0)
ones++;
num1 >>= 1;
}
printf("the number of Ones in the Value is %d\n", ones);
}
Top
08 Explain Bitwise Operators in C with Examples
This C Tutorial Explains Bitwise Operators in C and How they Operate on their Operands.

C’s Bitwise Operators:

C offers Bitwise logical operators and shift operators. In the following examples, we write out values in binary notation so that we can see what happens to the bits when they are shifted either right or left. In an actual program, we would use integer variables or constants written in the usual forms. For example, instead of 00011001(in Binary), we would use 25 or 031(in Octal) or 0x19(in Hexadecimal). For our examples, we will use 8-bit numbers, with the bits numbered 7 through 0, left to right.

Bitwise Logical Operators

The four bitwise logical operators work on integer-type data, including char. Characters are internally Integers which occupy One Byte of Storage. They are called bitwise because they operate on each bit independently of the bit to the left or right. Don’t confuse them with the regular logical operators (&&, ||, and !), which operate on values as a whole.

One’s Complement, or Bitwise Negation: ~

The unary operator ~ toggles each 1 to a 0 and each 0 to a 1. For example:

~(10011010) /* some expression */
(01100101) /* resulting value */
Suppose that val is an unsigned char assigned the value 10. In binary, 10 is 00001010. Then ~val has the value 11110101, or 245. Note that the operator does not change the value of val, just as 5 * val does not change the value of val; val is still 10, but it does create a new value that can be used or assigned elsewhere. For example:

newval = ~val; /* value in val is unchanged */
printf("%d", val); /* unchanged val */
printf("%d", ~val); /* got the new value printed but val is unchanged */
Now, If we want to change the value of val to ~val, use simple assignment as:

val = ~val; /* value in val is now updated to ~val */

Bitwise AND: &

The binary operator & produces a new value by making a bit-by-bit comparison between two operands. For each bit position, the resulting bit is 1 only if both corresponding bits in the operands are 1. (In terms of true/false, the result is true only if each of the two bit operands is true.) Therefore, expression

(10010011) & (00111101) /* some exp. */
(00010001) /* resulting value. */
/* Reason is that only bits 4 and 0 are 1 in both operands. */
C also has a combined bitwise AND-assignment operator: &=. The statement

val &= 0377;
val = val & 0377; /* both statements are equivalent */

Bitwise OR: |

The binary operator | produces a new value by making a bit-by-bit comparison between two operands. For each bit position, the resulting bit is 1 if either of the corresponding bits in the operands is 1. (In terms of true/false, the result is true if one or the other bit operands are true or if both are true.) Therefore, expression

(10010011) | (00111101) /* some exp. */
(10111111) /* resulting value */
/* because 6th bit in two operands is 0 */
C also has a combined bitwise OR-assignment operator: |=. The statements

val |= 0377; /* in compact form */
val = val | 0377; /* two statements are equivalent */

Bitwise EXCLUSIVE OR: ^

The binary operator ^ makes a bit-by-bit comparison between two operands. For each bit position, the resulting bit is 1 if one or the other (but not both) of the corresponding bits in the operands is 1. (In terms of true/false, the result is true if one or the other bit operands—but not both— is true.) Therefore, expression

(10010011) ^ (00111101) /* some exp. */
(10101110) /* resulting value. */
/* Note that because bit position 0 has the value 1 in both operands, */
/* the resulting 0 bit has value 0. */

C also has a combined bitwise EXCLUSIVE OR-assignment operator: ^=. The statement
val ^= 0377;
val = val ^ 0377; /* both are equivalent statements */

Usage: Masks

The bitwise AND operator is often used with a mask. A mask is a bit pattern with some bits set to on (1) and some bits to off (0). To see why a mask is called a mask, let’s see what happens when a quantity is combined with a mask by using &. For example, suppose you define the symbolic constant MASK as 2 (that is, binary 00000010), with only bit number 1 being nonzero. Then the statement

flags = flags & MASK; /* flags is some variable of type int */
flags &= MASK; /* same statement in compact form */
would cause all the bits of flags (except bit 1) to be set to 0 because any bit combined with 0 using the & operator yields 0. Bit number 1 will be left unchanged. (If the bit is 1, 1 & 1 is 1; if the bit is 0, 0 & 1 is 0.) This process is called “using a mask” because the zeros in the mask hide the corresponding bits in flags.

One common C usage is this statement:

ch &= 0xff; /* 0xff acts here as a MASK*/
The value 0xff, recall, is 11111111 in binary. This mask leaves the final 8 bits of ch alone and sets the rest to 0. Regardless of whether the original ch is 8 bits, 16 bits, or more, the final value is trimmed to something that fits into a single byte. In this case, the mask is 8 bits wide.

Usage: Turning Bits On

Sometimes we might need to turn on particular bits in a value while leaving the remaining bits unchanged. For instance, an IBM PC controls hardware through values sent to ports. To turn on, say, the speaker, we might have to turn on the 1 position bit while leaving the others unchanged. We can do this with the bitwise OR operator.For example, consider the MASK, which has bit 1 set to 1 and others 0s. The statement

flags = flags | MASK;
flags |= MASK; /* in compact form */
sets bit number 1 in flags to 1 and leaves all the other bits unchanged. This follows because any bit combined with 0 by using the | operator is itself, and any bit combined with 1 by using the | operator is 1.

Usage: Turning Bits Off

Just as it’s useful to be able to turn on particular bits, for specific purposes, without disturbing the other bits, it’s useful to be able to turn them off. Suppose you want to turn off bit 1 in the variable flags. Once again, MASK has only the 1 bit turned on. We can do this as:

flags = flags & ~MASK;
flags &= ~MASK;
Because MASK is all 0s except for bit 1, ~MASK is all 1s except for bit 1. A 1 combined with any bit using & is that bit, so the statement leaves all the bits other than bit 1 unchanged. Also, a 0 combined with any bit using & is 0, so bit 1 is set to 0 regardless of its original value.

Another Usage: Toggling Bits

Toggling a bit means turning it off if it is on, and turning it on if it is off. We can use the bitwise EXCLUSIVE OR operator to toggle a bit. The idea is that if b is a bit setting (1 or 0), then 1 ^ b is 0 if b is 1 and is 1 if b is 0. Also 0 ^ b is b, regardless of its value. Therefore, if we combine a value with a mask by using ^, values corresponding to 1s in the mask are toggled, and values corresponding to 0s in the mask are unaltered. To toggle bit 1 in flag, we can do either of the following:

flag = flag ^ MASK;
flag ^= MASK; /* in compact form */

Usage: Checking the Value of a Bit

We have seen how to change the values of bits. Suppose, instead, that we want to check the value of a bit. For example, does flag have bit 1 set to 1?

Even if bit 1 in flag is set to 1, the other bit setting in flag can make the comparison untrue. Instead, we must first mask the other bits in flag so that we compare only bit 1 of flag with MASK, for example:

if ((flag & MASK) == MASK)
puts("Wow! flag has bit 1 set to 1!");
In the above example, bitwise operators have lower precedence than ==, so the parentheses around flag & MASK are needed.


To avoid information peeking around the edges, a bit mask should be at least as wide as the value it’s masking.

Bitwise Shift Operators

Now let’s look at C’s shift operators. The bitwise shift operators shift bits to the left or right. Again, we will write binary numbers explicitly to show the mechanics.

Left Shift: <<

The left shift operator (<<) shifts the bits of the value of the left operand to the left by the number of places given by the right operand. The vacated positions are filled with 0s, and bits moved past the end of the left operand are lost. In the following example, then, each bit is moved two places to the left:

(10001010) << 2 /* some expression */
(00101000) /* resulting value */
This operation produces a new bit value, but it doesn’t change its operands. For example, suppose john is 1. Then
john << 2 is 4, but john is still 1. We can use the left-shift assignment operator (<<=) to actually change a variable's value. This operator shifts the bit in the variable to its left by the number of places given by the right-hand value. For example:

int john = 1;
int akram;

akram = john << 2; /* assigns 4 to akram */
john <<= 2; /* changes john to 4 */
Right Shift: >>

The right shift operator (>>) shifts the bits of the value of the left operand to the right by the number of places given by the right operand. Bits moved past the right end of the left operand are lost. For unsigned types, the places vacated at the left end are replaced by 0s. For signed types, the result is machine dependent. The vacated places may be filled with 0s, or they may be filled with copies of the sign (leftmost) bit. For example:

(10001010) >> 2 /* some expression, signed value */
(00100010) /* resulting value, some systems */
(10001010) >> 2 /* some expression, signed value */
(11100010) /* resulting value, other systems */
For an unsigned value, we have the following:

(10001010) >> 2 /* expression, unsigned value */
(00100010) /* resulting value, all system */
Each bit is moved two places to the right, and the vacated places are filled with 0s.

The right-shift assignment operator (>>=) shifts the bits in the left-hand variable to the right by the indicated number of places, as shown here:

int sweet = 16;
int bitter;

bitter = sweet >> 3; /* bitter now has value 2, sweet still 16 */
sweet >>=3; /* sweet changed to 2 */

Usage: Bitwise Shift Operators

The bitwise shift operators can provide swift, efficient (depending on the hardware) multiplication and division by powers of 2:

number << n; /* Multiplies number by 2 to the nth power */
number >> n; /*
* Divides number by 2 to the nth power if number is not
* negative
*/
These shift operations are analogous to the decimal system procedure of shifting the decimal point to multiply or divide by 10.

The shift operators can also be used to extract groups of bits from larger units. Suppose, for example, we use an unsigned long value to represent color values, with the low-order byte holding the red intensity, the next byte holding the green intensity, and the third byte holding the blue intensity. Supposed we then wanted to store the intensity of each color in its own unsigned char variable. Then we could do something like this:

#define BYTE_MASK 0xff

unsigned long color = 0x002a162f;
unsigned char blue, green, red;

red = color & BYTE_MASK;
green = (color >> 8) & BYTE_MASK;
blue = (color >> 16) & BYTE_MASK;
The code uses the right-shift operator to move the 8-bit color value to the low-order byte, and then uses the mask technique to assign the low-order byte to the desired variable.
Top
09 Explain Relational Operators in C with Examples
This C Tutorial explains Relational Operators in C with Examples.
While loops, for loops often rely on test expressions that make comparisons. Such expressions are termed relational expressions, and the operators that appear in them are called relational operators. We give below a complete list of C relational operators.

Relational Operators

Operator Meaning
< Is less than
<= Is less than or equal to
== Is equal to
>= Is greater than or equal to
> Is greater than
!= Is not equal to
The relational operators are used to form the relational expressions used in while statements and in other C statements. These statements check to see whether the expression is true or false. Below given are three unrelated statements containing examples of relational expressions. Let’s try to understand them.

while (number < 5) {
printf("Your number is smaller than 5.n");
scanf("%d", &number); /* read-in another number */
}

while (ch != '$') { /* while ch not equals char $ */
count++;
scanf("%c", &ch);
}

while (scanf("%f", &num) == 1)
sum += num;
Note in the second example that the relational expressions can be used with characters, too. The machine character code (which we have been assuming is ASCII) is used for the comparison. However, we can’t use the relational operators to compare strings. For comparing strings, we have several string comparing functions defined in the string.h header file.

The relational operators can be used with floating-point numbers, too. Beware, though, We should limit to using only < and > in floating-point comparisons. The reason is that round-off errors can prevent two numbers from being equal, even though logically they should be. For example, certainly the product of 3 and 1/3 is 1.0. If we express 1/3 as a six-place decimal fraction, however, the product is .999999, which is not quite equal to 1. The fabs() function, declared in the math.h header file, can be handy for floating-point tests. This function returns the absolute value of a floating-point value—that is, the value without the algebraic sign. For example:

/* cmpflt.c -- floating-point comparisons using fabs() function */

#include <math.h>
#include <stdio.h>

int main(void)
{
const double ANSWER = 3.14159;
double response;

printf("What is the value of pi?n");
scanf("%lf", &response);

while (fabs(response - ANSWER) > 0.0001) {
printf("Try again!n");
scanf("%lf", &response);
}
printf("Close enough!n");
return 0;
}
In the above program, loop continues to elicit a response until the user gets within 0.0001 of the correct value.

Recall that an expression in C always has a value. This is true even for relational expressions. Consider the program

/* true_false.c -- true and false values in C */
#include <stdio.h>
int main(void)
{
int true, false;

true = (10 > 5); /* value of a true relationship */
false = (10 == 5); /* value of a false relationship */

printf("true = %d; false = %d n", true, false);
return 0;
}
When we run the above program, we found values for true is 1 and for false is 0. Are there other values in C considered to be true than just 1? Let’s experiment:

/* truth.c -- what values are true? */
#include <stdio.h>
int main(void)
{
int n = 5;

while (n)
printf("%2d is truen", n--);
printf("%2d is falsen", n);

n = -5;
while (n)
printf("%2d is truen", n++);
printf("%2d is falsen", n);

return 0;
}
The first loop executes when n is 5, 4, 3, 2, and 1, but terminates when n is 0. Similarly, the second loop executes when n is -5, -4, -3, -2, and -1, but terminates when n is 0. More generally, all non-zero values are regarded as true, and only 0 is recognized as false.

Alternatively, we can say that a while loop executes as long as its test condition evaluates to non-zero. This puts test conditions on a numeric basis instead of a true/false basis. Keep in mind that relational expressions evaluate to 1 if true and to 0 if false, so such expressions really are numeric.

Aha! For C, a true expression has the value 1 or any non-zero value, and a false expression has the value 0. Indeed, some C programs use the following construction for loops that are meant to run forever because 1 always is true:


while (1) {
....
.... /* statements */
}
Troubles with Truth when Using of = operator for == operator

For example:

/* trouble.c -- misuse of = will cause infinite loop */
#include <stdio.h>
int main(void)
{
long num;
long sum = 0L;
int status;

printf("Please enter an integer to be summed ");
printf("(q to quit): ");
status = scanf("%ld", &num);

while (status = 1) {
sum = sum + num;
printf("Please enter next integer (q to quit): ");
status = scanf("%ld", &num);
}

printf("Those integers sum to %ld.n", sum);
return 0;
}
Above program produces output like the following:

Please enter an integer to be summed (q to quit): 50
Please enter next integer (q to quit): 100
Please enter next integer (q to quit): 2000
Please enter next integer (q to quit): q
Please enter next integer (q to quit):
Please enter next integer (q to quit):
Please enter next integer (q to quit):
Please enter next integer (q to quit):

… and so on until you kill the program.

This troublesome example made a change in the while test condition, replacing status == 1 with status = 1. The second statement is an assignment statement, so it gives status the value 1. Furthermore, the value of an assignment statement is the value of the left side, so status = 1 has the same numerical value of 1. So for all practical purposes, the while loop is the same as using while (1); that is, it is a loop that never quits. You enter q, and status is set to 0, but the loop test resets status to 1 and starts another cycle.

You might wonder why, because the program keeps looping, the user doesn’t get a chance to type in any more input after entering q. When scanf() fails to read the specified form of input, it leaves the nonconforming input in place to be read the next time. When scanf() tries to read the q as an integer and fails, it leaves the q there. During the next loop cycle, scanf() attempts to read where it left off the last time—at the q. Once again, scanf() fails to read the q as an integer, so not only does this example set up an infinite loop, it also creates a loop of infinite failure, a daunting concept.

Don’t use = for ==. The assignment operator assigns a value to the left variable. The relational equality operator, however, checks to see whether the left and right sides are already equal. It doesn’t change the value of the left-hand variable, if one is present. Here’s an example:

canoes = 5; /* *Assigns the value 5 to canoes */
canoes == 5 /* Checks to see whether canoes has the value 5 */
Precedence of Relational Operators

The precedence of the relational operators is less than that of the arithmetic operators, including + and -, and greater than that of assignment operators. This means, for example, that

x > y + 2 means the same as x > (y + 2)

It also means that x = y > 2 means x = (y > 2)

In other words, x is assigned 1 if y is greater than 2 and is 0 otherwise; x is not assigned the value of y.

The relational operators have a greater precedence than the assignment operator. Therefore,

x_bigger = x > y; means x_bigger = (x > y);

The relational operators are themselves organized into two different precedence levels.

Higher precedence group

< <= > >=

Lower precedence group

== !=


Like most other operators, the relational operators associate from left to right. Therefore,

ex != wye == zee is the same as (ex != wye) == zee

First, C checks to see whether ex and wye are unequal. Then, the resulting value of 1 or 0 (true or false) is compared to the value of zee. We don’t anticipate using this sort of construction.



Top
10 Explain Logical Operators in C with Examples
This C Tutorial Explains Different Logical Operators in C with Examples.
We know that if, while and for statements often use relational expressions as tests or test conditions. Sometimes we find it useful to combine two or more relational expressions. For example, suppose we want a program that counts how many times the characters other than single or double quotes appear in an input sentence. We can use logical operators to meet this need, and can use the period character (.) to identify the end of a sentence.

/* charcount.c -- use the logical AND operator */

#include <stdio.h>
#define PERIOD '.'
int main(void)
{
int ch;
int charcount = 0;

/* getchar() returns integer that's why I chose ch to be an integer */

while ((ch = getchar()) != PERIOD) {
if (ch != '"' && ch != '\'')
charcount++;
}

printf("There are %d non-quote characters.\n", charcount);
return 0;
}
Following we have a sample run:

“Children, don’t you know how to behave with elder people”, asked the father.

There are 73 non-quote characters.

The action begins as the program reads a character and checks to see whether it is a period, because the period identifies the end of a sentence. Next comes something new and interesting, a statement using the logical AND operator, &&. We can translate the if statement as, “If the character is not a double quote AND if it is not a single quote, increase charcount by 1.”

Both conditions must be true if the whole expression is to be true. The logical operators have a lower precedence than the relational operators, so it is not necessary to use additional parentheses to group the sub-expressions. C has three logical operators.

Operator Meaning
&& and
|| or
! not
Suppose exp1 and exp2 are two simple relational expressions, such as:

exp1: okey > bye
exp2: money == loan

Then we can state the following:

exp1 && exp2 is true only if both exp1 and exp2 are true.
exp1 || exp2 is true if either exp1 or exp2 is true or if both are true.
!exp1 is true if exp1 is false, and it’s false if exp1 is true.

Apart from this, Logical Operators AND and OR exert order of evaluation of the expression in which they appear. That is, in an exp. with AND operator, if operand on the left of the AND operator is FALSE, then operand on the right is not evaluated at all and result of the entire exp. is FALSE. Well! Now in an exp. with OR operator, if operand on the left of the OR operator is TRUE, then operand on the right is not evaluated at all and result of the entire exp. is TRUE. Some clear examples:

10 > 8 && 3 > 7; /* FALSE */
3 > 7 && 10 > 8; /* FALSE */

/*
* because 3 > 7 is false. sub-exp. 10 > 8 however, is
* TRUE but not evaluated at all.
*/

3 > 7 || 10 > 8; /* TRUE */
10 > 8 || 3 > 7; /* TRUE */

/* sub-exp. 3 > 7, which is FALSE, is not evaluated at all */

!(3 > 7) /* TRUE because 3 is not greater than 7 */

Precedence

The ! operator has a very high precedence — higher than multiplication, the same as the increment operators, and just below that of parentheses. The && operator has higher precedence than ||, and both rank below the relational operators and above assignment in precedence. Therefore, the expression

a > b && b > c || b > d

would be interpreted as

((a > b) && (b > c)) || (b > d)

/* parentheses used are however not necessary */

That is, b is between a and c, or b is greater than d.

Order of Evaluation

Aside from those cases in which two operators share an operand, C ordinarily does not guarantee which parts of a complex expression are evaluated first. For example, in the following statement, the expression 5 + 3 might be evaluated before 9 + 6, or it might be evaluated afterwards:

something = (5 + 3) * (9 + 6);


This ambiguity was left in the language so that compiler designers could make the most efficient choice for a particular system. One exception to this rule is the treatment of logical operators. C guarantees that logical expressions are evaluated from left to right in a way that program doesn’t move to the next operand until preceding operand is evaluated fully. Furthermore, it guarantees that as soon as an element is found that invalidates the expression as a whole, the evaluation stops. These guarantees make it possible to use constructions such as the following:

while ((c = getchar()) != ‘ ‘ && c != ‘\n’)

This construction sets up a loop that reads characters up to the first space or newline character. The first sub-expression gives a value to c, which then is used in the second sub-expression. Without the order guarantee, the computer might try to test the second expression before finding out what value c has.

Let’s see another example:

if (number != 0 && 12 / number == 2)
printf("The number is 5 or 6.\n");
/*
* If number has the value 0, the first sub-expression is false,
* and the relational expression is not evaluated any further.
* This spares the computer the trauma of trying to divide by zero.
*/

Consider one more example:

while ( x++ < 10 && x + y < 20)
/*
* The fact that the && operator is a sequence point meaning that
* program doesn't switch to next exp. until solves out the preceding
* one. guarantees that x is incremented before the expression on the
* right is evaluated.
*/

Ranges

We can use the && operator to test for ranges. For example, to test for score being in the range 90 to 100, we can do this as:

if (range >= 90 && range <= 100)
printf("Good show!\n");

/*
* It's important to avoid imitating common mathematical
* notation, as in the following:
*/

if (90 <= range <= 100) /* NO! Don't do it! */
printf("Good show!\n");
/*
* The problem is that the code is a semantic error, not a syntax error,
* so the compiler will not catch it. Because the order of evaluation
* for the <= operator is left-to-right, the test expression is
* interpreted as follows:
*/
(90 <= range) <= 100
/*
* The sub-expression 90 <= range either has the value 1 (for
* true) or 0 (for false).
* Either value is less than 100, so the whole expression is
* always true, regardless of the value of range. So use && for
* testing for ranges.
*/
Top
11 Explain Increment and Decrement Operators in C with Examples
This C Tutorial explains Increment and Decrement Operators in C.
Well! ++ and — are two Increment and decrement operators respectively in C. Each operator has two forms and these are prefix and postfix forms. In prefix form, operand comes after the operator while in postfix form operand comes before the operator. For example:

++man; /* prefix form */
cats++; /* postfix form */

--days;
nights--;
Notice, there must not be any space between the operand and the operator. Also, ++ and — are Unary operators that is each takes just one operand! Being Unary operators they have very high precedence and are put above the arithmetic operators in the precedence table.

How they Work: ++ and — operators work the same except ++ increments its operand while — decrements its operand. ++ operator in either form increments its operand by value of 1. For example:

++man; /* prefix form; increments man by 1 */
cats++; /* postfix form; increments cats by 1 */

--days; /* decrements days by 1*/
nights--; /* decrements nights by 1*/
One more example:

/* plus_one.c -- incrementing: prefix and postfix */
#include <stdio.h>
int main(void)
{
int num1 = 0, num2 = 0;

while (num1 < 5) {
num1++;
++num2;

printf("num1 %d, num2 = %d \n", num1, num2)
}
return 0;
}
Running plus_one.c produces this output:

num1 = 1, num2 = 1
num1 = 2, num2 = 2
num1 = 3, num2 = 3
num1 = 4, num2 = 4
num1 = 5, num2 = 5
The program counted to five twice and simultaneously. We could get the same results by replacing the two increment statements with this:

num1 = num1 + 1;
num2 = num2 + 1;

Another example:

shoe = 3.0;

while (shoe < 18.5) {
foot = SCALE * size + ADJUST;
printf("%10.1f %20.2f inches\n", shoe, foot);
++shoe;
}


However, we still haven’t taken full advantage of the increment operator. We can shorten the fragment this way:

shoe = 2.0;

while (shoe++ < 18.5) {
foot = SCALE * size + ADJUST;
printf("%10.1f %20.2f inches\n", shoe, foot);
}
Second, what’s so good about this approach? It is more compact. More important, it gathers in one place the two processes that control the loop. The primary process is the test: Do you continue or not? In this case, the test is checking to see whether the shoe size is less than 18.5. The secondary process changes an element of the test; in this case, the shoe size is increased.

Suppose you forgot to change the shoe size. Then shoe would always be less than 18.5, and the loop would never end. The computer would churn out line after identical line, caught in a dreaded infinite loop. Eventually, you would lose interest in the output and have to kill the program somehow. Having the loop test and the loop change at one place, instead of at separate locations, helps you to remember to update the loop.

A disadvantage is that combining two operations in a single expression can make the code harder to follow and can make it easier to make counting errors.

Another advantage of the increment operator is that it usually produces slightly more efficient machine language code because it is similar to actual machine language instructions.

But there is difference between prefix and postfix increments when an expression contains two or more different terms then they evaluate differently. For example:

y = a + ++man; /* prefix form; increments man by 1 */
y = a + cats++; /* postfix form; increments cats by 1 */

/*
* in the first exp. man is incremented by 1 before it is used in
* the exp. while in the second the value of cats is incremented
* after it is used in the exp.
*/
How does this happen? Actually, in any exp. with two or more terms, copy of operand, with which ++ operator is associated, is used. In prefix form, operand is first incremented then copy of operand is used in the exp. In postfix form copy of original value of the operand is created and used in the exp. then operand is incremented. For example:

b = ++i; /* different result for b if i++ is used */
++i; /* line 1 */
b = i; /* same result for b as if i++ used in line 1 */
Precedence of ++ and — operators

The increment and decrement operators have a very high precedence of association; only parentheses are higher. Therefore, x * y++ means (x) * (y++), not (x * y)++, which is fortunate because the latter is invalid. The increment and decrement operators affect a variable (or, more generally, a modifiable lvalue), and the combination x * y is not itself a variable, although its parts are.

Don’t confuse precedence of these two operators with the order of evaluation. Suppose you have the following:

y = 2;
n = 3;

nextnum = (y + n++) * 6;
What value does nextnum get? Substituting in values yields

nextnum = (2 + 3) * 6 = 5 * 6 = 30
Only after n is used is it increased to 4. Precedence tells us that the ++ is attached only to the n, not to y + n. It also tells us when the value of n is used for evaluating the expression, but the nature of the increment operator determines when the value of n is changed.

When n++ is part of an expression, you can think of it as meaning “use n; then increment it.” On the other hand, ++n means “increment n; then use it.”

Another possible source of trouble is a statement like this one:

ans = num / 2 + 5 * (1 + num++);
Again, the problem is that the compiler may not do things in the same order you have in mind. You would think that it would find num/2 first and then move on, but it might do the last term first, increase num, and use the new value in num/2. There is no guarantee.

Yet another troublesome case is this:

n = 3;
y = n++ + n++;
Certainly, n winds up larger by 2 after the statement is executed, but the value for y is ambiguous. A compiler can use the old value of n twice in evaluating y and then increment n twice. This gives y the value 6 and n the value 5, or it can use the old value once, increment n once, use that value for the second n in the expression, and then increment n a second time. This gives y the value 7 and n the value 5. Either choice is allowable. More exactly, the result is undefined, which means the C standard fails to define what the result should be.

Remember how we can easily avoid these problems:
1. Don’t use increment or decrement operators on a variable that is part of more than one argument of a function.
2. Don’t use increment or decrement operators on a variable that appears more than once in an expression.
Top
12 Explain Conditional Operator in C with Examples
Explain Conditional Operator in C with Examples

This C Tutorial explains Conditional Operator in C with examples.
Conditional operator is Ternary Operator that is it takes 3 operands. The general syntax of this operator is as:

expression1 ? expression2 : expression3;
Besides Operator Precedence and Associativity, It, like the logical operators, does exert some control on the order of evaluation of the entire expression. For example:

(number >= 1000) ? a + b + c : d + e + f;
Here in the above example, if (number >= 1000) is TRUE then result of whole expression is expression2 which is (a + b + c) and expression3 (d + e + f) is not evaluated at all. But if (number >= 1000) evaluates to FALSE then result of the entire expression is expression3 which is (d + e + f) and expression2 isn’t evaluated at all.



Basically, conditional operator is same as if-else construct. We can rewrite the above conditional expression as:

if (expression1)
expression2;
else
expression3;
Advantages of conditional operator over if-else construct:

Then what is the difference between conditional expression and if-else statement. Firstly, conditional expression is little bit more compact than if-else construct. For example:

/* b written twice using if-else */
if (ch == 'A')
b = 5;
else
b = ch + 5;

/* b written once using conditional operator */
b = (ch == 'A') ? 5 : ch + 5;

Consider another example:

/* subscript written twice using if-else */
if (a > 10)
b[a + c / 5 * 10 - 2] = 100;
else
b[a + c / 5 * 10 - 2] = 1000;

/* subscript written once using conditional operator */
b[a + c / 5 * 10 - 2] = a > 10 ? 100 : 1000;
Notice in the above example, subscript is a complex exp. and there are chances of errors while typing it twice as in if-else. So, using the conditional statement, we can avoid such errors.
Top
13 Explain Comma Operator in C with Examples
This C Tutorial explains Comma Operator in C with examples.
Comma operator represented by ‘,’ ensures the evaluation from left to right, one by one, of two or more expressions, separated with commas, and result of entire expression is value of rightmost expression. For example:

int a = 10, b = 20, c = 30;
int x;

printf("Value of exp. "x = a + b, b + c, c + a;" is %d\n",
(x = a + b, b + c, c + a));

/* value of x is value of rightmost sub-exp. c + a */
But what happens if we mistakenly write the above example this way:

int a = 10, b = 20, c = 30;
int x;

printf("Value of exp. "x = a + b, b + c, c + a;" is %d\n",
x = a + b, b + c, c + a);
/* value of x is value of leftmost sub-exp. a + b */
Actually, in the above printf() statement, this time there are three arguments, separated with commas, following format string for one format specifier. All expressions are evaluated but value of x = a + b is printed. To avoid such problems, enclose the entire expression in pair of parenthesis.

Another example:

int x, y, z, a = 10, b = 20, c = 30;

x = a + b, y = b + c, z = c + a;

printf("In x = a + b, y = b + c, z = c + a; x is %d y is %d"
"and z is %d", x, y, z);
/* above statement is same as x = a + b; y = b + c; z = c + a; */

One more example:

/* comma1.c -- how comma operator works */
#include <stdio.h>
int main(void)
{
int x, y, z;
int a = 10, b = 20, c = 30;

printf("The value of entire expression a + b, b + c, c + a"
"is %d\n", (a + b, b + c, c + a));
printf("Value of the entire exp. a, a++, a++; is %d\n",
(a, a++, a++));

return 0;
}
Usage of Comma Operator
This operator is of great worth in multiple initializations, updating values in for and while loop statements. For example:

/*comma2.c----usage of comma operator */
#include <stdio.h>
int main(void)
{
int x, y, z;

for (x = getval(), y = x + 1; y >= 0 ; x++, y = x + 1) {
...
x = getval();
}

return 0;
}
Another example:

/*comma3.c----use with while loop test exp. */
#include <stdio.h>
int main(void)
{
int a;

a = getval();
count(a);
while (a > 0) {
...
a = getval();
count(a);
}

return 0;
}
In the above program, test exp is preceded by two statements to obtain the value of a and the same pair of statements are needed at the end of while loop. However, with comma operator, we can rewrite this loop as:


/*comma3.c----use with while loop test exp. */
#include <stdio.h>
int main(void)
{
int a;

while (a = getval(), count(a), a > 0) {
...
}

return 0;
}
Or even in more compact form as:

while (count(a = getval()), a > 0) {
...
}
With this approach, just one copy of the code is needed. Comma operator makes the source program easier to maintain. In future, if there needs some changes, only one copy of the code is to be fixed.
Top
14 What are Boolean Values and Whether C have an Explicit Boolean Type
This C Tutorial explains Boolean Values and Whether C have an Explicit Boolean Type.
C doesn’t have an explicit Boolean type so integers are used instead. Boolean values are TRUE and FALSE or ON and OFF or 1 and 0 respectively. According to rule, 1 is considered TRUE and 0 is FALSE. However, any nonzero value is considered to be TRUE and Standard doesn’t say if 1 is more TRUE than any nonzero value. For example, in the following program fragment,

int a = 10, b = 20;

if (a)
if (b)
printf("value of a + b is %d\n", a + b);

/*
* in this example a and b are integers and used in Boolean context as
* "if a is TRUE then if b is TRUE then print the value of a + b
*/
Consider another example:

int a = 10, b = 20;

if (a) /* if a is nonzero */
if (b) /* if b is nonzero */
if (a == b) /* a & b are being tested as ints not as boolean */
printf("value of a + b; is %d\n", a + b);

Beware that several nonzero values represent TRUE. In the following program two pair of statements seem to be equivalent. For example:

/*
* mix_bool_int.c -- program displays ints being tested as boolean values
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0

int main(void)
{
int flag;

printf("User, type in some intger value...\n");
scanf("%d", &flag);

if (flag == FALSE) /* if flag is zero or false */
(!flag); /* set flag to 1 */

if (flag == TRUE) /* if flag is 1 or true */
(flag); /* flag is True */

return 0;
}
But second pair of statements is not equivalent because if flag is given any arbitrary value other than 1, condition won’t hold. This is because of mixing of Integers & Boolean Values. Therefore, the solution to the problem is to avoid using mixed types. And test a given value for zero or nonzero explicitly. For example, in the following program fragment,

okey = boys_in_class() >= 10;

if (okey)
printf("Good! We set to work today!\n");
else
printf("See the class on next working day!");
In the above program fragment, the result of relational exp. “boys_in_class() >= 10” is assigned to okey which is then tested for boolean values True and False.


C99 Standard introduced _Bool Type for Boolean Values. Since boolean values 1 or 0 can be represented by just 1 Bit therefore variable of _Bool Type is 1 bit in memory. For example:

/* bool.c---program displays values of _Bool type */
#include <stdio.h>
#define TRUE 1
#define FALSE 0

_Bool new_count();

int main(void)
{
_Bool okey;
int count = 0;

while ((okey = new_count()) == TRUE) {
printf("No of Iteration Count is %d\n", ++count);
}

printf("Bye!\n");
return 0;
}

_Bool new_count()
{
_Bool new;
int a, b;

printf("user, enter two intgers...\n");
scanf("%d %d", &a, &b);

if (a == b)
return new = 1;
else
return new = 0;
}
Top
15 Explain sizeof Operator and its Return Value in C Language with Examples
This C Tutorial explains sizeof Operator in C Language and the Type of Value Returned by the operator.
The sizeof operator returns the size, in bytes, of its operand. Recall that a C byte is defined as the size used by the char type. In the past, this has most often been 8 bits, but some character sets may use larger bytes. The operand can be a specific data object either a unary expression such as the name of a variable, array, structure or it can be a type name. If it is a type, such as float, the operand must be enclosed in parentheses. For example:

/* sizeof_1.c -- uses sizeof operator */
/* uses C99 %z modifier -- try %u or %lu if you lack %zd */
#include <stdio.h>
int main(void)
{
int n = 0;
size_t intsize; /* size_t type used */

intsize = sizeof (int);
printf("n = %d, n has %zd bytes; all ints have %zd bytes.\n",
++n, sizeof ++n, intsize );
/* sizeof doesn't evaluate the exp. */
return 0;
}
Using sizeof with arrays

When sizeof is applied to the name of a static array (not allocated through malloc, calloc or realloc), the result is the size in bytes of the whole array. This is one of the few exceptions to the rule that the name of an array is converted to a pointer to the first element of the array, and is possible just because the actual array size is fixed and known at compile time, when sizeof operator is evaluated. The following program uses sizeof to determine the size of a declared array, avoiding a buffer overflow when copying characters:

/* sizeof_2.c -- use of sizeof operator with arrays */
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
char buffer[10]; /* Array of 10 chars */

/* Copy at most 9 characters from argv[1] into buffer. */
/* sizeof(char) is defined to be always 1. */

strncpy(buffer, argv[1], sizeof buffer - sizeof buffer[0]);

/* Ensure that the buffer is null-terminated */
buffer[sizeof buffer - 1] = '\0';
return 0;
}
Here, sizeof buffer is equivalent to 10 * sizeof buffer[0], or 10.

C99 adds support for flexible array members to structures. This form of array declaration is allowed as the last element in structures only, and differs from normal arrays in that no length is specified to the compiler. For a structure named flexarray containing a flexible array member named as array, for example:

/* sizeof_3.c -- use of sizeof with flexible array member to a structure */
#include <stdio.h>

struct flexarray {
char val;
int array[];
/* Flexible array member; must be last element of struct */
};

int main(int argc, char **argv)
{
printf("sizeof(struct flexarray) = %zu bytes\n",
sizeof (struct flexarray));

return 0;
}
Thus, in this case the sizeof operator returns the size of the structure, including any padding, but without any storage allowed for the flexible array. In the above example, the following output will be produced on most platforms:


sizeof (struct flexarray) = 4

C99 also allows variable length arrays where the length is specified at runtime. In such cases, the sizeof operator is evaluated in part at runtime to determine the storage occupied by the array. For example:

/* sizeof_4.c -- use of sizeof with variable length arrays */

#include <stddef.h>
#include

size_t flexsize(int n)
{
char b[n+3]; /* Variable length array */
return sizeof b; /* Execution time sizeof */
}

int main( void )
{
size_t size = flexsize(10); /* flexsize returns 13 */
return 0;
}
C says that sizeof returns a value of type size_t. This is an unsigned integer type, but not a brand-new type. Instead, like the portable types (int32_t and so on), it is defined in terms of the standard types. C has a typedef mechanism that lets you create an alias for an existing type. For example,

typedef double real;
makes real another name for double. Now we can declare a variable of type real as

real deal; /* using a typedef */
The compiler will see the word real, recall that the typedef statement made real an alias for double, and create deal as a type double variable. Similarly, the C header files system can use typedef to make size_t a synonym for unsigned int on one system or for unsigned long on another. Thus, when you use the size_t type, the compiler will substitute the standard type that works for your system.

C99 goes a step further and supplies %zd as a printf() specifier for displaying a size_t value. If your system doesn’t implement %zd, try using %u or %lu instead.


sizeof and incomplete types

sizeof can only be applied to “completely” defined types. With arrays, this means that the dimensions of the array must be present in its declaration, and that the type of the elements must be completely defined. For structs and unions, this means that there must be a member list of completely defined types. For example, consider the following two source files:

/* file1.c */
int arr[10];
struct x {int one; int two;};
/* more code */

/* file2.c */
extern int arr[];
struct x;
/* more code */
Both files are perfectly legal C, and code in file1.c can apply sizeof to arr and struct x. However, it is illegal for code in file2.c to do this, because the definitions in file2.c are not complete. In the case of arr, the code does not specify the dimension of the array; without this information, the compiler has no way of knowing how many elements are in the array, and cannot calculate the array’s overall size. Likewise, the compiler cannot calculate the size of struct x because it does not know what members it is made up of, and therefore cannot calculate the sum of the sizes of the structure’s members (and padding). If the programmer provided the size of the array in its declaration in file2.c, or completed the definition of struct x by supplying a member list, this would allow the application of sizeof to arr or struct x in that source file.

Implementation

It is the responsibility of compilers to implement the sizeof operator correctly for each target platform. In many cases, there will be an official Application Binary Interface (ABI) document for the platform, specifying formats, padding, and alignment for the data types, to which the compiler must conform. In most cases, sizeof is a compile-time operator, which means that during compilation sizeof expressions get replaced by constant result-values. However, sizeof applied to a variable length array, introduced in C99, requires computation during program execution.
Top
16 What is Cast Operator in C Programming
This C Tutorial explains Cast Operator in C Programming with examples.
Sometimes we need to evaluate mixed-type expressions. For example:

/*autocast.c -- automatic type conversions */
#include <stdio.h>
int main(void)
{
int a = 1, b = 2;
float val = 3, z = 4, x;
char new = 'A', old = 'B', ch;

x = a * b + val * new * old;
printf("The result of the exp. "x = a * b + val * new * old is %f\n",
x = a * b + val * new * old);

ch = a * b + val * new * old;
printf("The result of the exp. "ch = a * b + val * new * old is %c\n",
ch = a * b + val * new * old);

return 0;
}
When above program is run on Linux system, the output follows as:

The result of the exp. x = a * b + val * new * old is 12872.000000
The result of the exp. ch = a * b + val * new * old is H

Exp. “x = a * b + val * new * old” which is composed of different types of values, when evaluated, each type is converted to same higher type. That is integers and characters are promoted to floats implicitly. Promotions are smooth and easy. However, demotions are not always. Mostly, there’s chance of Information Lost in demotions. In the above example, right side of the assignment in the exp. ch = a * b + val * new * old, evaluated to 12872.000000 by implicit conversions of integers and characters to floats and then final result is demoted to character type and there is information lost as result is character H. Because a char type can’t hold a value greater than 255.

To avoid such problems, exercise due care not mixing several different types. It is a good idea to have at least some knowledge of the type conversion rules.

The basic rules are

When appearing in an expression, char and short, both signed and unsigned, are automatically converted to int or, if necessary, to unsigned int. (If short is the same size as int, unsigned short is larger than int; in that case, unsigned short is converted to unsigned int.) Under K&R C, but not under current C, float is automatically converted to double. Because they are conversions to larger types, they are called promotions.

In any operation involving two types, both values are converted to the higher ranking of the two types.

The ranking of types, from highest to lowest, is long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int, and int. One possible exception is when long and int are the same size, in which case unsigned int outranks long. The short and char types don’t appear in this list because they would have been already promoted to int or perhaps unsigned int.

In an assignment statement, the final result of the calculations is converted to the type of the variable being assigned a value. This process can result in promotion, as described in rule 1, or demotion, in which a value is converted to a lower-ranking type.

When passed as function arguments, char and short are converted to int, and float is converted to double. This automatic promotion can be overridden by function prototyping.

The Cast Operator

We should usually steer clear of automatic type conversions, especially of demotions, but sometimes it is convenient to make conversions, provided you exercise care. The type conversions we’ve discussed so far are done automatically. However, it is possible for us to demand the precise type conversion that we want or else document that we know we’re making a type conversion. The method for doing this is called a cast and consists of preceding the quantity with the name of the desired type in parentheses. The parentheses and type name together constitute a cast operator. This is the general form of a cast operator:


(type) name_quantity;

The actual type desired, such as long, is substituted for the word type.

Consider the next two code lines, in which mice is an int variable. The second line contains two casts to type int.

mice = 1.6 + 1.7;
mice = (int) 1.6 + (int) 1.7;
The first example uses automatic conversion. First, 1.6 and 1.7 are added to yield 3.3. This number is then converted through truncation to the integer 3 to match the int variable. In the second example, 1.6 is converted to an integer (1) before addition, as is 1.7, so that mice is assigned the value 1+1, or 2. Neither form is intrinsically more correct than the other; you have to consider the context of the programming problem to see which makes more sense.

Normally, you shouldn’t mix types (that is why some languages don’t allow it), but there are occasions when it is useful. The C philosophy is to avoid putting barriers in your way and to give you the responsibility of not abusing that freedom.
Top
17 Explain Unary Operators in C Programming with Examples
This C Tutorial explains different Unary Operators in C Programming with examples and how they
Operate on their Operands.

There are several Unary Operators in C. Unary operators take just one operand. We have following

Unary Operators in C.

! (logical negation),
~ (one’s complement or bitwise negation),
– (unary minus),
+ (unary plus),
& (addressof),
* (dereferencing),
++ (pre-increment),
— (pre-decrement),
sizeof operator,
(type) or cast operator

All Unary Operators have associativity from Right to Left. We consider each, one by one.

One’s Complement or Bitwise Negation: ~

Ones Complement is a Bitwise Unary Operator operates on individual bits, turns 0s to 1s and 1s to 0s. All other Bitwise operators are Binary Operators. For example:

/*
* itobinary.c -- program to display binary string for a given integer and
* inverts given n bits at the end
*/
#include <stdio.h>
char * itobstr(int, char *);
void show_bstr(const char *);
int invert_nbits(int num, int no_bits);

int main(void)
{
int num, no_bits;
char str[ 8 * sizeof (int) + 1 ];

puts("Enter some integer number...");
puts("Non numeric number terminates the program!");

while (scanf("%d", &num) == 1) {
itobstr(num, str);
printf("Number you entered is %d\n", num);
show_bstr(str);

printf("Enter no of bits u wanna to invert in the binary string..."
"\n");
scanf("%d", &no_bits);
num = invert_nbits(num, no_bits);
show_bstr(itobstr(num, str));
}
printf("Thank you!\n");
return 0;
}

char *itobstr(int n, char * bs)
{
int i;
static int size = 8 * sizeof n;

for (i = size - 1; i >= 0; i--, n >>= 1)
bs[i] = (00000001 & n) + '0';

bs[size] = '\0';
return bs;
}

void show_bstr(const char * bs)
{
int i = 0;

while (bs[i]) {
printf("%c", bs[i]);
if (++i % 4 == 0 && bs[i])
putchar(' ');
}
putchar('\n');
}

int invert_nbits(int num, int no_bits)
{
int mask = 0;
int bitval = 1;

/* we set a given no bits of mask to 1s */
while (no_bits-- > 0 ) {
mask |= bitval;
bitval <<= 1;
}

/* now we invert n = no_bits from the end of the binary string bs */
return mask ^ num;
}
Logical Negation !

This is the only Unary Operator in the set of Logical Operators. It operates on Type integer and turns the TRUTH Value of its operand from TRUE to FALSE and Vice-Versa. For example:

/* log_negate.c -- program inverts the truth value of the given integer */
#include <stdio.h>
int main(void)
{
int num;
_Bool truth_val;

printf("Program inverts the truth value of the integer value\n\n");
printf("user, enter some integer...\nnon-integer value terminates "
"the program...\n");

while (scanf("%d", &num) == 1) {
truth_val = !num;
printf("Entered number is %d and its Inverted Truth Value is %d\n",
num, truth_val);
printf("enter another number or terminate the program by typing "
"in non integer val...\n");
}
printf("Goodbye!\n");
return 0;
}
Remember that any nonzero value in C is considered TRUE while 0 is considered FALSE. Since single bit storage is sufficient to store 1 or 0, so new type _Bool can be used to store either TRUTH Value.

Sign Operators: – and +

The minus sign can also be used to indicate or to change the algebraic sign of a value. For instance, the sequence

nancy = –12;
fancy = –nancy;
gives fancy the value 12.

When the minus sign is used in this way, it is called a unary operator, meaning that it takes just one operand.

The C90 standard adds a unary + operator to C. It doesn’t alter the value or sign of its operand; it just enables you to use statements such as

bananas = +12;
without getting a compiler complaint. Formerly, this construction was not allowed.

Finding Addresses: The & Operator

One of the most important C concepts (and perhaps the most perplexing) is the pointer, which is a variable used to store an address. We’ve already seen that scanf() uses addresses for arguments. More generally, any C function that modifies a value in the calling function without using a return value uses addresses.

The unary (addressof) & operator gives us the address where a variable is stored. If number is the name of a variable, &number is the address of the variable. We can think of the address as a location in memory. Suppose we have the following statement:

qual = 24;
Suppose that the address where qual is stored is 0B76. (PC addresses often are given as hexadecimal values.) Then the statement

printf("%d %p\n", qual, &qual);
would produce this (%p is the specifier for addresses):

24 0B76
The following program uses the ANSI C %p format for printing the addresses.

/*
* The loccheck.c -- Program uses this operator to see where variables of
* the same name but in different functions are kept.
*/
#include <stdio.h>
void mikado(int); /* declare function, function prototype */
int main(void)
{
int pooh = 2, bah = 5; /* local to main() */

printf("In main(), pooh = %d and &pooh = %p\n", pooh, &pooh);
printf("In main(), bah = %d and &bah = %p\n", bah, &bah);

mikado(pooh);
return 0;
}

void mikado(int bah) /* define function */
{
int pooh = 10; /* local to mikado() */

printf("In mikado(), pooh = %d and &pooh = %p\n", pooh, &pooh);
printf("In mikado(), bah = %d and &bah = %p\n", bah, &bah);
}

My system, Linux, produced the following output:

In main(), pooh = 2 and &pooh = 0x7fff3575608c
In main(), bah = 5 and &bah = 0x7fff35756088
In mikado(), pooh = 10 and &pooh = 0x7fff3575606c
In mikado(), bah = 2 and &bah = 0x7fff3575605c
The way that %p represents addresses varies between implementations. However, many implementations, such as one used for this example, display the address in hexadecimal form.

What does this output show? First, the two poohs have different addresses. The same is true for the two bahs. So, as promised, the computer considers them to be four separate variables. Second, the call mikado(pooh) did convey the value (2) of the actual argument (pooh of main()) to the formal argument (bah of mikado()). Note that just the value was transferred. The two variables involved (pooh of main() and bah of mikado()) retain their distinct identities.

We raise the second point because it is not true for all languages. In FORTRAN, for example, the subroutine affects the original variable in the calling routine. The subroutine variable might have a different name, but the address is the same. C doesn’t do this. Each function uses its own variables. This is preferable because it prevents the original variable from being altered mysteriously by some side effect of the called function.

Dereferencing Operator or Indirection Operator: *

Pointers? What are they? Basically, a pointer is a variable (or, more generally, a data object) whose value is a memory address. Just as a char variable has a character as a value and an int variable has an integer as a value, the pointer variable has an address as a value. The term data object refers to region of storage in the computer memory.

If we give a particular pointer variable the name ptr, we can have statements such as the following:

ptr = &danny; /* assigns danny's address to ptr */
We say that ptr “points to” danny. The difference between ptr and &danny is that ptr is a variable, and &danny is a constant. If we want, we can make ptr point elsewhere:

ptr = &kristina;
/* make ptr point to kristina instead of to danny */
Now the value of ptr is the address of kristina.

To create a pointer variable, we need to be able to declare its type. Suppose we want to declare ptr so that it can hold the address of an int. To make this declaration, we need to use a new operator. Let’s examine that operator now.

Suppose we know that ptr points to kristina, as shown here:

ptr = &kristina;
Then we can use the indirection operator * (also called the dereferencing operator) to find the value stored in kristina (don’t confuse this unary indirection operator with the binary * operator of multiplication):

val = *ptr; /* finding the value ptr points to */
The statements ptr = &kristina; and val = *ptr; taken together amount to the following statement:

val = kristina;
Using the address and indirection operators is a rather indirect way of accomplishing this result, hence the name “indirection operator.”

Increment and Decrement Operators: ++ and —

The increment operator performs a simple task; it increments (increases) the value of its operand by 1. This operator comes in two varieties. The first variety has the ++ come before the affected variable; this is the prefix mode. The second variety has the ++ after the affected variable; this is the postfix mode. The two modes differ with regard to the precise time that the incrementing takes place. The short example below shows how the increment operators work.

/* add_one.c -- incrementing: prefix and postfix */
#include <stdio.h>
int main(void)
{
int ultra = 0, super = 0;

while (super < 5) {
super++;
++ultra;
printf("super = %d, ultra = %d \n", super, ultra);
}
return 0;
}
Running add_one.c produces this output:

super = 1, ultra = 1
super = 2, ultra = 2
super = 3, ultra = 3
super = 4, ultra = 4
super = 5, ultra = 5
The program counted to five twice and simultaneously. You could get the same results by replacing the two increment statements with this:

super = super + 1;
ultra = ultra + 1;
These are simple enough statements. Why bother creating one, let alone two, abbreviations? One reason is that the compact form makes your programs neater and easier to follow. These operators give your programs an elegant gloss that cannot fail to please the eye.

Another advantage of the increment operator is that it usually produces slightly more efficient machine language code because it is similar to actual machine language instructions. However, as vendors produce better C compilers, this advantage may disappear. A smart compiler can recognize that x = x + 1 can be treated the same as ++x.

Finally, these operators have an additional feature that can be useful in certain delicate situations.

/* post_pre.c -- postfix vs prefix */
#include <stdio.h>
int main(void)
{
int a = 1, b = 1;
int aplus, plusb;

aplus = a++; /* postfix */
plusb = ++b; /* prefix */
printf("a aplus b plusb \n");
printf("%1d %5d %5d %5d\n", a, aplus, b, plusb);

return 0;
}
If you and your compiler do everything correctly, you should get this result:

a aplus b plusb

2 1 2 2

Both a and b were increased by 1, as promised. However, aplus has the value of a before a changed, but plusb has the value of b after b changed. This is the difference between the prefix form and the postfix form.

aplus = a++; /* postfix: a is changed after its value is used */
plusb = ++b; /* prefix: b is changed before its value is used */
When one of these increment operators is used by itself, as in a solitary ego++; statement, it doesn’t matter which form you use. The choice does matter, however, when the operator and its operand are part of a larger expression, as in the assignment statements we just saw. In this kind of situation, we must give some thought to the result we want.
You should pay special attention to the examples of increment operators as you read through this book. Ask yourself if you could have used the prefix and the suffix forms interchangeably or if circumstances dictated a particular choice.

Perhaps an even wiser policy is to avoid code in which it makes a difference whether we use the prefix or postfix form. For example, instead of

b = ++i; /* different result for b if i++ is used */
use

++i; /* line 1 */
b = i; /* same result for b as if i++ used in line 1 */
Decrementing: —

For each form of increment operator, there is a corresponding form of decrement operator. Instead of ++, use –:

-- count; /* prefix form of decrement operator */
count --; /* postfix form of decrement operator */
The sizeof Operator and the size_t Type

The sizeof operator returns the size, in bytes, of its operand. (Recall that a C byte is defined as the size used by the char type. In the past, this has most often been 8 bits, but some character sets may use larger bytes.) The operand can be a specific data object, such as the name of a variable, or it can be a type. If it is a type, such as float, the operand must be enclosed in parentheses. For example:

/* sizeof_1.c -- uses sizeof operator */
/* uses C99 %z modifier -- try %u or %lu if you lack %zd */

#include <stdio.h>
int main(void)
{
int n = 0;
size_t intsize; /* size_t type used */

intsize = sizeof (int);
printf("n = %d, n has %zd bytes; all ints have %zd bytes.\n",
++n, sizeof ++n, intsize );

printf("now n has become %d\n", n);

return 0;
}
C says that sizeof returns a value of type size_t. This is an unsigned integer type, but not a brand-new type. Instead, like the portable types (int32_t and so on), it is defined in terms of the standard types. C has a typedef mechanism that lets us create an alias for an existing type. For example,

typedef double real;
makes real another name for double. Now you can declare a variable of type real:

real deal; /* using a typedef */
The compiler will see the word real, recall that the typedef statement made real an alias for double, and create deal as a type double variable. Similarly, the C header files system can use typedef to make size_t a synonym for unsigned int on one system or for unsigned long on another. Thus, when you use the size_t type, the compiler will substitute the standard type that works for your system.

C99 goes a step further and supplies %zd as a printf() specifier for displaying a size_t value. If your system doesn’t implement %zd, you can try using %u or %lu instead.
Top
18 Explain L and R Values in C Language with Examples
This C Tutorial explains L and R Values in C Language and How are they Used in C Programs with Examples.
We are quite very much familiar with various types of assignment statements. For example:

hny = "Happy New Year 2014!"; /* a character string */
count += 1; /* an integer */
cats = monkeys + elephants * mice - foxes;
sum = x + y * z / (u * v) + (f = g * h - t);/* exp containing sub exp */
In all the above statements, left side represents a data object. A data object is a region of storage in computer memory where values are stored. These data objects are also called locations in the memory. Variables, arrays, structures are specific labels given to these data objects. Each location in memory has an address. For any value of either type, char, float, int etc. to be stored in computer requires some storage/location. For instance,

/* lvalue3.c -- valid lvalues */
#include <stdio.h>
int main(void)
{
int x = 10, y = 20;
float marks = 60.75, u = 33.89, v;

v = marks + u * x + y; /* v here is a valid lvalue */
printf("Value of the exp. v = marks + u * x + y is %f\n", v);
return 0;
}
Value of the exp. v = marks + u * x + y is 419.649994 results when program is run.

Some Terminology: Data Objects, Lvalues, Rvalues, and Operands

Data object is a general term for a region of data storage that can be used to hold values. The data storage used to hold a variable or an array is a data object, for instance. C uses the term lvalue to mean a name or expression that identifies a particular data object. The name of a variable, for instance, is an lvalue, so object refers to the actual data storage, but lvalue is a label used to identify, or locate, that storage.


Not all objects can have their values changed, so C uses the term modifiable lvalue to identify objects whose value can be changed. Therefore, the left side of an assignment operator should be a modifiable lvalue. Indeed, the l in lvalue comes from left because modifiable lvalues can be used on the left side of assignment operators. The term rvalue refers to quantities that can be assigned to modifiable lvalues. Rvalues can be constants, variables, or any other expression that yields a value.

Now, let’s see some examples of invalid lvalues, means left side of assignment doesn’t represent location or storage.

5 = men + women + children;
/* left side is 5 which is a value not location */

110 = 200 + 300 * 12;
/* 110 is integer literal not location */
Consider another example:

/* lvalue1.c -- lvalue error */
#include <stdio.h>
int main(void)
{
int i = 10, j = 20, k = 50;
float cm = 10.5, mm = 20.9, inch = 12;

5 = 10;
return 0;
}
When program is run, results as:
lvalue1.c: In function ‘main’:
lvalue1.c:9:4: error: lvalue required as left operand of assignment

/* lvalue2.c -- lvalue error */
#include <stdio.h>
int main(void)
{
char name = 'A';

'A' = 10; /* assigning to character A number 10 */
return 0;
}

Program results as:
lvalue2.c: In function ‘main’:
lvalue2.c:8:13: error: lvalue required as left operand of assignment

Pointer expressions as lvalues

For example:

int candy = 20; /*
/* candy a variable has a location into which val 20 is stored */

int *iptr;
/* pointer of type int; will point to some integer val */

iptr = &candy;
/* now iptr points to candy, location into which 20 is stored */

*iptr = 100; /* assigning candy value 100 through iptr */
Constants either integers, characters, floats all are values and variables of any type are values as well as locations. Pointer expressions also represent values and locations.
Top
19 How can One Determine Whether a Right Shift of a Signed Value is Performed as an Arithmetic or a Logical Shift
Question: How can One Determine Whether a Right Shift of a Signed Value is Performed on Linux Machine as an Arithmetic or a Logical Shift
Answer: Right and Left shift operators are Bitwise Binary Operators operate on Individual Bits of their Integer Operands. On Linux Machine, Logical and Arithmetic Right and Left Shifts on Unsigned Integer values are same but Arithmetic Right Shift on signed integer values are implementation dependent.

/* rshift_negval.c -- What happens on right arithmetic shift on -ve int */
#include <stdio.h>
int main(void)
{
int x = -1000, y, nbits;

printf("By what no of bits u wanna right shift on signed integer, "
"enter no of bits...\n");
puts("Non integer value terminates the program.");

while (scanf("%d", &nbits) == 1) {
y = x >> nbits;
printf("The value of x in y = x >> %d is %d and y is %d\n",
nbits, x, y);
}
printf("Program Terminated! Good Bye!\n");
return 0;
}

When the above program is run, it displays the output as follows:

By what number of bits you want to right shift on signed integer, enter number of bits…
Non integer value terminates the program.
1
The value of x in y = x >> 1 is -1000 and y is -500
2
The value of x in y = x >> 2 is -1000 and y is -250
3
The value of x in y = x >> 3 is -1000 and y is -125
4
The value of x in y = x >> 4 is -1000 and y is -63
5
The value of x in y = x >> 5 is -1000 and y is -32
6
The value of x in y = x >> 6 is -1000 and y is -16
7
The value of x in y = x >> 7 is -1000 and y is -8
8
The value of x in y = x >> 8 is -1000 and y is -4
9
The value of x in y = x >> 9 is -1000 and y is -2
10
The value of x in y = x >> 10 is -1000 and y is -1
11
The value of x in y = x >> 11 is -1000 and y is -1
12
The value of x in y = x >> 12 is -1000 and y is -1
13
The value of x in y = x >> 13 is -1000 and y is -1
14
The value of x in y = x >> 14 is -1000 and y is -1
15
The value of x in y = x >> 15 is -1000 and y is -1
16
The value of x in y = x >> 16 is -1000 and y is -1
17
The value of x in y = x >> 17 is -1000 and y is -1
18
The value of x in y = x >> 18 is -1000 and y is -1
19
The value of x in y = x >> 19 is -1000 and y is -1
20
The value of x in y = x >> 20 is -1000 and y is -1
21
The value of x in y = x >> 21 is -1000 and y is -1
22
The value of x in y = x >> 22 is -1000 and y is -1
23
The value of x in y = x >> 23 is -1000 and y is -1
24
The value of x in y = x >> 24 is -1000 and y is -1
25
The value of x in y = x >> 25 is -1000 and y is -1
26
The value of x in y = x >> 26 is -1000 and y is -1
27
The value of x in y = x >> 27 is -1000 and y is -1
28
The value of x in y = x >> 28 is -1000 and y is -1
29
The value of x in y = x >> 29 is -1000 and y is -1
30
The value of x in y = x >> 30 is -1000 and y is -1
31
The value of x in y = x >> 31 is -1000 and y is -1
32
The value of x in y = x >> 32 is -1000 and y is -1000
q
Program Terminated! Good Bye!

Therefore, when right shift on a signed value (here -1000) is performed, on Linux Machine where type int has 32 bits storage, starting from 1 bit and successively increasing by 1, till 31 bits, the result is always negative. During the successive right shifts, signed integer number reduced to half of its before until becomes -1. And thereon it doesn’t alter with successive right shifts. When shifted the signed number by 32 bits, its wrap around.
Top
Render time: 0.34 seconds
7,458,553 unique visits