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, *
and /
have
precedence over +
and -
. 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.
Thus, the
expression
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
decrement operator, --
. 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
operators. Hence, - x + y
is equivalent to the unambiguous expression
(-x) + y
, since the unary minus operator has precedence over the
addition operator.
Note that there is a subtle distinction between the expressions a++
and ++a
.
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
incrementation. Thus,
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
a--
and --a
.
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,
the expression !(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
expression
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: +=
, -=
,
*=
, and /=
. 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
operator (? :)
. 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 1
is true (i.e., if its value is nonzero)
then expression 2
is evaluated and becomes the value of the conditional
expression. On the other hand, if
expression 1
is false (i.e., if its value is zero)
then expression 3
is 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
multiplication (*
) 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.