There are four main arithmetic operators in C. These are:
addition + subtraction - multiplication * division /Unbelievably, there is no built-in exponentiation operator in C (C was written by computer scientists)! Instead, there is a library function (pow) which carries out this operation (see later).
It is poor programming practice to mix types in arithmetic expressions. In other words, the two operands operated on by the addition, subtraction, multiplication, or division operators should both be either of type int or type double. The value of an expression can be converted to a different data type by prepending the name of the desired data type, enclosed in parenthesis. This type of construction is known as a cast. Thus, to convert an integer variable j into a floating-point variable with the same value, we would write
(double) jFinally, to avoid mixing data types when dividing a floating-point variable x by an integer variable i, we would write
x / (double) iOf course, the result of this operation would be of type double.
The operators within C are grouped hierarchically according to their
precedence (i.e., their order of evaluation).
Amongst the arithmetic operators,
-. In other words,
when evaluating expressions, C performs multiplication and division
operations prior to addition and subtraction operations. Of course,
the rules of precedence can always be bypassed by judicious use of parentheses.
a - b / c + dis equivalent to the unambiguous expression
a - (b / c) + dsince division takes precedence over addition and subtraction.
The distinguishing feature of unary operators is that
they only act on single operands. The most common unary operator
is the unary minus, which occurs
when a numerical constant, variable, or expression
is preceded by a minus sign. Note that the unary minus is distinctly different
from the arithmetic operator (
-) which denotes subtraction, since the latter
operator acts on two separate operands. The two other common unary
operators are the increment operator,
++, and the
--. The increment operator causes its
operand to be increased by 1, whereas the decrement operator causes
its operand to be decreased by 1. For example,
-i is equivalent to i = i - 1. A cast is also considered to be
a unary operator. Note that unary operators have precedence over arithmetic
- x + y is equivalent to the unambiguous expression
(-x) + y, since the unary minus operator has precedence over the
Note that there is a subtle distinction between the expressions
In the former case, the value of the variable
a is returned before
it is incremented. In the latter case, the value of
a is returned after
b = a++;is equivalent to
b = a; a = a + 1;whereas
b = ++a;is equivalent to
a = a + 1; b = a;There is a similar distinction between the expressions
There are four relational operators in C. These are:
less than < less than or equal to <= greater than > greater than or equal to >=The precedence of these operators is lower than that of arithmetic operators.
Closely associated with the relational operators are the two equality operators:
equal to == not equal to !=The precedence of the equality operators is below that of the relational operators.
The relational and equality operators are used to form logical expressions, which represent conditions that are either true or false. The resulting expressions are of type int, since true is represented by the integer value 1 and false by the integer value 0. For example, the expression i < j is true (value 1) if the value of i is less than the value of j, and false (value 0) otherwise. Likewise, the expression j == 3 is true if the value of j is equal to 3, and false otherwise.
C also possess two logical operators. These are:
&& and || orThe logical operators act on operands which are themselves logical expressions. The net effect is to combine the individual logical expressions into more complex expressions that are either true or false. The result of a logical and operation is only true if both operands are true, whereas the result of a logical or operation is only false if both operands are false. For instance, the expression (i >= 5)
&&(j == 3) is true if the value of i is greater than or equal to 5 and the value of j is equal to 3, otherwise it is false. The precedence of the logical and operator is higher than that of the logical or operator, but lower than that of the equality operators.
C also includes the unary operator
! that negates the value of a logical
expression: i.e., it causes an expression that is originally true to become
false, and vice versa. This operator is referred to as the
logical negation or logical not operator. For instance,
!(k == 4) is true if the value of k is not
equal to 4, and false otherwise.
Note that it is poor programming practice to rely too heavily on operator precedence, since such reliance tends to makes C programs very hard for other people to follow. For instance, instead of writing
i + j == 3 && i * l >= 5and relying on the fact that arithmetic operators have precedence over relational and equality operators, which, in turn, have precedence over logical operators, it is better to write
((i + j) == 3) && (i * l >= 5)whose meaning is fairly unambiguous, even to people who cannot remember the order of precedence of the various operators in C.
The most common assignment operator in C is
=. For instance, the
f = 3.4causes the floating-point value 3.4 to be assigned to the variable f. Note that the assignment operator
=and the equality operator
==perform completely different functions in C, and should not be confused. Multiple assignments are permissible in C. For example,
i = j = k = 4causes the integer value 4 to be assigned to i, j, and k, simultaneously. Note, again, that it is poor programming practice to mix data types in assignment expressions. Thus, the data types of the constants or variables on either side of the
=sign should always match.
C contains four additional assignment operators:
/=. The expression
i += 6is equivalent to
i = i + 6. Likewise, the expression
i -= 6is equivalent to
i = i - 6. The expression
i *= 6is equivalent to
i = i * 6. Finally, the expression
i /= 6is equivalent to
i = i / 6. Note that the precedence of assignment operators is below that of all the operators discussed previously.
Simple conditional operations can be carried out with the conditional
(? :). An expression that makes use
of the conditional operator is called a conditional expression.
Such an expression takes the general form
expression 1 ? expression 2 : expression 3If
expression 1is true (i.e., if its value is nonzero) then
expression 2is evaluated and becomes the value of the conditional expression. On the other hand, if
expression 1is false (i.e., if its value is zero) then
expression 3is evaluated and becomes the value of the conditional expression. For instance, the expression
(j < 5) ? 12 : -6takes the value 12 if the value of j is less than 5, and the value -6 otherwise. The assignment statement
k = (i < 0) ? n : mcauses the value of n to be assigned to the variable k if the value of i is less than zero, and the value of m to be assigned to k otherwise. The precedence of the conditional operator is just above that of the assignment operators.
As we have already mentioned, scientific programs tend to be extremely resource intensive.
Scientific programmers should, therefore, always be on the lookout for methods
of speeding up the execution of their codes. It is important to realize that
*) and division (
/) operations consume considerably
more CPU time that addition (
+), subtraction (
-), comparison, or assignment
operations. Thus, a simple rule of thumb for writing efficient code is to try to
avoid redundant multiplication and division operations. This is particularly important
for sections of code which are executed repeatedly: e.g., code which lies within
control loops. The classic illustration of this point is the evaluation of a
polynomial. The most straightforward method of evaluating (say) a fourth-order polynomial
would be to write something like:
p = c_0 + c_1 * x + c_2 * x * x + c_3 * x * x * x + c_4 * x * x * x * xNote that the above expression employs ten expensive multiplication operations. However, this number can be reduced to four via a simple algebraic rearrangement:
p = c_0 + x * (c_1 + x * (c_2 + x * (c_3 + x * c_4)))Clearly, the latter expression is far more computationally efficient than the former.