Parentheses and Priority
Parentheses are classed as operators by the compiler, although their position is a bit unclear. They have a value in the sense that they assume the value of whatever expression is inside them. Parentheses are used for forcing a priority over operators. If an expression is written out in an ambiguous way, such as: a + b / 4 * 2
it is not clear what is meant by this. It could be interpreted in several ways: ((a + b) / 4) * 2
or (a + b)/ (4 * 2)
or a + (b/4) * 2
and so on. By using parentheses, any doubt about what the expression means is removed. Parentheses are said to have a higher priority than + * or / because they are evaluated as "sealed capsules" before other operators can act on them. Putting parentheses in may remove the ambiguity of expressions, but it does not alter than fact that a + b / 4 * 2
is ambiguous. What will happen in this case? The answer is that the C compiler has a convention about the way in which expressions are evaluated: it is called operator precedence. The convention is that some operators are stronger than others and that the stronger ones will always be evaluated first. Otherwise, expressions like the one above are evaluated from left to right: so an expression will be dealt with from left to right unless a strong operator overrides this rule. Use parentheses to be sure. A table of all operators and their priorities is given in the reference section.
Node:Unary Operator Precedence, Next:Special Assignment Operators ++ --, Previous:Parentheses and Priority, Up:Assignments Expressions and Operators
Unary Operator Precedence
Unary operators are operators which have only a single operand: that is, they operate on only one object. For instance: ++ -- + - &
The precedence of unary operators is from right to left so an expression like: *ptr++;
would do ++ before *.
Node:Special Assignment Operators ++ --, Next:More Special Assignments, Previous:Unary Operator Precedence, Up:Assignments Expressions and Operators
Special Assignment Operators ++ and --
C has some special operators which cut down on the amount of typing involved in a program. This is a subject in which it becomes important to think in C and not in other languages. The simplest of these perhaps are the increment and decrement operators:

++
increment: add one to
--
decrement: subtract one from
These attach to any variable of integer or floating point type. (character types too, with care.) They are used to simply add or subtract 1 from a variable. Normally, in other languages, this is accomplished by writing: variable = variable + 1;
In C this would also be quite valid, but there is a much better way of doing this: variable++; or++variable;
would do the same thing more neatly. Similarly: variable = variable - 1;
is equivalent to: variable--;
or --variable;
Notice particularly that these two operators can be placed in front or after the name of the variable. In some cases the two are identical, but in the more advanced uses of C operators, which appear later in this book, there is a subtle difference between the two.
Node:More Special Assignments, Next:Example 13, Previous:Special Assignment Operators ++ --, Up:Assignments Expressions and Operators
More Special Assignments
Here are some of the nicest operators in C. Like ++ and -- these are short ways of writing longer expressions. Consider the statement: variable = variable + 23;
In C this would be a long winded way of adding 23 to variable. It could be done more simply using the general increment operator: += variable += 23;
This performs exactly the same operation. Similarly one could write: variable1 = variable1 + variable2;
as variable1 += variable2;
and so on. There is a handful of these =
operators: one for each of the major operations which can be performed. There is, naturally, one for subtraction too: variable = variable - 42;
can be written: variable -= 42;
More surprisingly, perhaps, the multiplicative assignment: variable = variable * 2;
may be written: variable *= 2;
and so on. The main arithmetic operators all follow this pattern:
+=
add assign
-=
subtract assign
*=
multiply assign
/=
divide (double) and (int) types
%=
remainder (int) type only.
and there are more exotic kinds, used for bit operations or machine level operations, which will be ignored at this stage: >>=<<=^==&=
Node:Example 13, Next:Output 13, Previous:More Special Assignments, Up:Assignments Expressions and Operators
Example Listing/**************************************//* *//* Operators Demo # 2 *//* *//**************************************/ #include /**************************************/ main () { int i; printf ("Assignment Operators\n\n"); i = 10; /* Assignment */ printf("i = 10 : %d\n",i); i++; /* i = i + 1 */ printf ("i++ : %d\n",i); i += 5; /* i = i + 5 */ printf ("i += 5 : %d\n",i); i--; /* i = i = 1 */ printf ("i-- : %d\n",i); i -= 2; /* i = i - 2 */ printf ("i -= 2 : %d\n",i); i *= 5; /* i = i * 5 */ printf ("i *= 5 :%d\n",i); i /= 2; /* i = i / 2 */ printf ("i /= 2 : %d\n",i); i %= 3; /* i = i % 3 */ printf ("i %%= 3 : %d\n",i); }
Node:Output 13, Next:The Cast Operator, Previous:Example 13, Up:Assignments Expressions and Operators
OutputAssignment Operators i = 10 : 10i++ : 11i += 5 : 16i-- : 15i -= 2 : 13i *= 5 :65i /= 2 : 32i %= 3 : 2
Node:The Cast Operator, Next:Expressions and Types, Previous:Output 13, Up:Assignments Expressions and Operators
The Cast Operator
The cast operator is an operator which forces a particular type mould or type cast onto a value, hence the name. For instance a character type variable could be forced to fit into an integer type box by the statement: char ch; int i; i = (int) ch;
This operator was introduced earlier, See Variables. It will always produce some value, whatever the conversion: however remotely improbable it might seem. For instance it is quite possible to convert a character into a floating point number: the result will be a floating point representation of its ASCII code!
Node:Expressions and Types, Next:Summary of Operators and Precedence, Previous:The Cast Operator, Up:Assignments Expressions and Operators
Expressions and Types
There is a rule in C that all arithmetic and mathematical operations must be carried out with long variables: that is, the types doublelong float intlong int
If the programmer tries to use other types like short or float in a mathematical expression they will be cast into long types automatically by the compiler. This can cause confusion because the compiler will spot an error in the following statement: short i, j = 2; i = j * 2 + 1;
A compiler will claim that there is a type mismatch between i and the expression on the right hand side of the assignment. The compiler is perfectly correct of course, even though it appears to be wrong. The subtlety is that arithmetic cannot be done in short type variables, so that the expression is automatically converted into long type or int type. So the right hand side is int type and the left hand side is short type: hence there is indeed a type mismatch. The programmer can get around this by using the cast operator to write: short i, j = 2; i = (short) j * 2 + 1;
A similar thing would happen with float: float x, y = 2.3; x = y * 2.5;
would also be incorrect for the same reasons as above.
Comparisons and Logic
Comparisons and Logic
Six operators in C are for making logical comparisons. The relevance of these operators will quickly become clear in the next chapter, which is about decisions and comparisons. The six operators which compare values are:
==
is equal to
!=
is not equal to
>
is greater than
<
is less than
>=
is greater than or equal to
<=
is less than or equal to
These operators belong to the second group according to the scheme above but they do actually result in values so that they could be thought of as being a part of the first group of operators too. The values which they produce are called true and false. As words, "true" and "false" are not defined normally in C, but it is easy to define them as macros and they may well be defined in a library file: #define TRUE 1#define FALSE 0
Falsity is assumed to have the value zero in C and truth is represented by any non-zero value. These comparison operators are used for making decisions, but they are themselves operators and expressions can be built up with them. 1 == 1
has the value "true" (which could be anything except zero). The statement: int i; i = (1 == 2);
would be false, so i would be false. In other words, i would be zero.
Comparisons are often made in pairs or even in groups and linked together with words like OR and AND. For instance, some test might want to find out whether: (A is greater than B) AND (A is greater than C)
C does not have words for these operations but gives symbols instead. The logical operators, as they are called, are as follows:
&&
logical AND

logical OR inclusive
!
logical NOT
The statement which was written in words above could be translated as: (A > B) && (A > C)
The statement: (A is greater than B) AND (A is not greater than C)
translates to: (A > B) && !(A > C)
Shakespeare might have been disappointed to learn that, whatever the value of a variable tobe the result of thequestion = tobe !tobe
must always be true. The NOT operator always creates the logical opposite: !true is false and !false is true. On or the other of these must be true. thequestion is therefore always true. Fortunately this is not a matter of life or death!
Node:Summary of Operators and Precedence, Next:Questions 16, Previous:Expressions and Types, Up:Assignments Expressions and Operators
Summary of Operators and Precedence
The highest priority operators are listed first. Operator Operation Evaluated. () parentheses left to right [] square brackets left to right ++ increment right to left -- decrement right to left(type) cast operator right to left * the contents of right to left & the address of right to left - unary minus right to left ~ one's complement right to left ! logical NOT right to left * multiply left to right / divide left to right % remainder (MOD) left to right + add left to right - subtract left to right >> shift right left to right <<> is greater than left to right >= greater than or equal to left to right <= less than or equal to left to right < right ="="" right =" assign">>= right shift assign right to left <<= left shift assign right to left &= AND assign right to left ^= exclusive OR assign right to left = inclusive OR assign right to left
Node:Questions 16, Previous:Summary of Operators and Precedence, Up:Assignments Expressions and Operators
Questions
What is an operand?
Write a statement which prints out the remainder of 5 divided by 2.
Write a short statement which assigns the remainder of 5 divided by 2 to a variable called "rem".
Write a statement which subtracts -5 from 10.
Write in C: if 1 is not equal to 23, print out "Thank goodness for mathematics!"
Node:Decisions, Next:Loops, Previous:Assignments Expressions and Operators, Up:Top
Decisions

Testing and Branching. Making conditions.
Suppose that a fictional traveller, some character in a book like this one, came to the end of a straight, unfinished road and waited there for the author to decide where the road would lead. The author might decide a number of things about this road and its traveller:
The road will carry on in a straight line. If the traveller is thirsty he will stop for a drink before continuing.
The road will fork and the traveller will have to decide whether to take the left branch or the right branch.
The road might have a crossroads or a meeting point where many roads come together. Again the traveller has to decide which way to go.
We are often faced with this dilemma: a situation in which a decision has to be made. Up to now the simple example programs in this book have not had any choice about the way in which they progressed. They have all followed narrow paths without any choice about which way they were going. This is a very limited way of expressing ideas though: the ability to make decisions and to choose different options is very useful in programming. For instance, one might want to implement the following ideas in different programs:
If the user hits the jackpot, write some message to say so. "You've won the game!"
If a bank balance is positive then print C for credit otherwise print D for debit.
If the user has typed in one of five things then do something special for each special case, otherwise do something else.
These choices are actually just the same choices that the traveller had to make on his undecided path, thinly disguised. In the first case there is a simple choice: a do of don't choice. The second case gives two choices: do thing 1 or thing 2. The final choice has several possibilities.
C offers four ways of making decisions like the ones above. They are listed here below. The method which is numbered 2b was encountered in connection with the C preprocessor; its purpose is very similar to 2a. 1: if (something_is_true) { /* do something */ } 2a: if (something_is_true) { /* do one thing */ } else { /* do something else */ } 2b: ? (something_is_true) : /* do one thing */ : /* do something else */ 3: switch (choice) { case first_possibility : /* do something */ case second_possibility : /* do something */ .... }
if:
example f1:
if else:
Nested ifs and logic:
Example 14:
Stringing together if..else:
switch:
Example 15:
To try:
Node:if, Next:example f1, Previous:Decisions, Up:Decisions
if
The first form of the if statement is an all or nothing choice. if some condition is satisfied, do what is in the braces, otherwise just skip what is in the braces. Formally, this is written: if (condition) statement;
or if (condition) { compound statement }
Notice that, as well as a single statement, a whole block of statements can be written under the if statement. In fact, there is an unwritten rule of thumb in C that wherever a single statement will do, a compound statement will do instead. A compound statement is a block of single statements enclosed by curly braces.
A condition is usually some kind of comparison, like the ones discussed in the previous chapter. It must have a value which is either true or false (1 or 0) and it must be enclosed by the parentheses ( and ). If the condition has the value `true' then the statement or compound statement following the condition will be carried out, otherwise it will be ignored. Some of the following examples help to show this: int i; printf ("Type in an integer"); scanf ("%ld",&i); if (i == 0) { printf ("The number was zero"); } if (i > 0) { printf ("The number was positive"); } if (i < 0) { printf ("The number was negative"); }
The same code could be written more briefly, but perhaps less consistently in the following way: int i; printf ("Type in an integer"); scanf ("%ld",&i); if (i == 0) printf ("The number was zero");if (i > 0) printf ("The number was positive");if (i < 0) printf ("The number was negative");
The preference in this book is to include the block braces, even when they are not strictly required. This does no harm. It is no more or less efficient, but very often you will find that some extra statements have to go into those braces, so it is as well to include them from the start. It also has the appeal that it makes if statements look the same as all other block statements and it makes them stand out clearly in the program text. This rule of thumb is only dropped in very simple examples like: if (i == 0) i++;
The if statement alone allows only a very limited kind of decision: it makes do or don't decisions; it could not decide for the traveller whether to take the left fork or the right fork of his road, for instance, it could only tell him whether to get up and go at all. To do much more for programs it needs to be extended. This is the purpose of the else statement, described after some example listings..
Node:example f1, Next:if else, Previous:if, Up:Decisions
Example Listings/*****************************************//* *//* If... #1 *//* *//*****************************************/ #include #define TRUE 1#define FALSE 0 /******************************************/ main () { int i; if (TRUE) { printf ("This is always printed"); } if (FALSE) { printf ("This is never printed"); }} /*******************************************//* *//* If demo #2 *//* *//*******************************************/ /* On board car computer. Works out the */ /* number of kilometers to the litre */ /* that the car is doing at present */ #include /*******************************************//* Level 0 *//*******************************************/ main () { double fuel,distance; FindValues (&fuel,&distance);Report (fuel,distance);} /********************************************//* Level 1 *//********************************************/ FindValues (fuel,distance) /* from car */ /* These values would be changing in */ /* a real car, independently of the */ /* program. */ double *fuel,*distance; {/* how much fuel used since last check on values */ printf ("Enter fuel used");scanf ("%lf",fuel); /* distance travelled since last check on values */ printf ("Enter distance travelled");scanf ("%lf",distance);} /**********************************************/ Report (fuel,distance) /* on dashboard */ double fuel,distance; { double kpl; kpl = distance/fuel; printf ("fuel consumption: %2.1lf",kpl);printf (" kilometers per litre\n"); if (kpl <= 1) { printf ("Predict fuel leak or car"); printf (" needs a service\n"); } if (distance > 500) { printf ("Remember to check tyres\n"); } if (fuel > 30) /* Tank holds 40 l */ { printf ("Fuel getting low: %s left\n",40-fuel); }}
Node:if else, Next:Nested ifs and logic, Previous:example f1, Up:Decisions
if ... else
The if .. else statement has the form: if (condition) statement1; else statement2;
This is most often written in the compound statement form: if (condition) { statements }else { statements }
The if..else statement is a two way branch: it means do one thing or the other. When it is executed, the condition is evaluated and if it has the value `true' (i.e. not zero) then statement1 is executed. If the condition is `false' (or zero) then statement2 is executed. The if..else construction often saves an unnecessary test from having to be made. For instance: int i; scanf ("%ld",i); if (i > 0) { printf ("That number was positive!"); }else { printf ("That number was negative or zero!"); }
It is not necessary to test whether i was negative in the second block because it was implied by the if..else structure. That is, that block would not have been executed unless i were NOT greater than zero. The weary traveller above might make a decision such as: if (rightleg > leftleg) { take_left_branch(); }else { take_right_branch(); }
Node:Nested ifs and logic, Next:Example 14, Previous:if else, Up:Decisions
Nested ifs and logic
Consider the following statements which decide upon the value of some variable i. Their purposes are exactly the same. if ((i > 2) && (i < 4)) { printf ("i is three"); }
or: if (i > 2) { if (i < 4) { printf ("i is three"); } }
Both of these test i for the same information, but they do it in different ways. The first method might been born out of the following sequence of thought:
If i is greater than 2 and i is less than four, both at the same time, then i has to be 3.
The second method is more complicated. Think carefully. It says:
If i is greater than 2, do what is in the curly braces. Inside these curly braces i is always greater than 2 because otherwise the program would never have arrived inside them. Now, if i is also less than 4, then do what is inside the new curly braces. Inside these curly braces i is always less than 4. But wait! The whole of the second test is held inside the "i is greater than 2" braces, which is a sealed capsule: nothing else can get in, so, if the program gets into the "i is less than 4" braces as well, then both facts must be true at the same time. There is only one integer which is bigger than 2 and less than 4 at the same time: it is 3. So i is 3.
The aim of this demonstration is to show that there are two ways of making multiple decisions in C. Using the logical comparison operators &&, (AND,OR) and so on.. several multiple tests can be made. In many cases though it is too difficult to think in terms of these operators and the sealed capsule idea begins to look attractive. This is another advantage of using the curly braces: it helps the programmer to see that if statements and if..else statements are made up of sealed capsule parts. Once inside a sealed capsule if (i > 2) { /* i is greater than 2 in here! */ }else { /* i is not greater than 2 here! */ }
the programmer can rest assured that nothing illegal can get in. The block braces are like regions of grace: they cannot be penetrated by anything which does not satisfy the right conditions. This is an enourmous weight off the mind! The programmer can sit back and think: I have accepted that i is greater than 2 inside these braces, so I can stop worrying about that now. This is how programmers learn to think in a structured way. They learn to be satisfied that certain things have already been proven and thus save themselves from the onset of madness as the ideas become too complex to think of all in one go.
Node:Example 14, Next:Stringing together if..else, Previous:Nested ifs and logic, Up:Decisions
Example Listing/***********************************************//* *//* If demo #3 *//* *//***********************************************/ #include /***********************************************/ main () { int persnum,usernum,balance; persnum = 7462;balance = -12; printf ("The Plastic Bank Corporation\n");printf ("Please enter your personal number :"); usernum = getnumber(); if (usernum == 7462) { printf ("\nThe current state of your account\n"); printf ("is %d\n",balance); if (balance < num =" 0;"> 9999) (num <= 0)) { printf ("That is not a valid number\n"); } return (num);}
Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

0 comments: on " "