Programming In C: Arithmetic Operators

This article is part of a series – How to Program Anything: C Programming

Preface

This article is a continuation on expressions that can be constructed in the C language.  We’ve studied literal expressions in the previous article.  This article will focus on expressions involving operators.  If you remember, expressions are pieces of code that are executed right away to yield some kind of result, as opposed to a statement which may affect an entire program’s structure.  An example of an expression could be the addition operator (+).  When you add two things together, you work on given data and proffer up a result (the sum) to then be used in another expression such as the assignment operator (=).  Another example of an expression would be the array index operators ( [, ] ), which access a particular element of an array and proffer up the contained value as a result.

Operators in C are half of the equation towards getting stuff done in your programs.  The other half are the statements that make up the structure of a program, however, we have yet to get to that.  Operators are basically actions that are taken in a program on the given data.  It’s all well and good to define variables, which we’ve been doing so far, but we have to be able to do something with those variables.  An example of an action performed on given data is, again, the addition and assignment operators (+, =).  By typing the expression  a = b + c; we are assigning the result of adding b and c together into the variable a.

Operators can be split up into five main classes: program, arithmetic, bitwise, logical, and relational.

Arithmetic Operators

The class most immediately familiar to most programmers are the arithmetic operators, which include addition, assignment, subtraction, multiplication, and division.  Most all of the arithmetic operators are binary operators, meaning they operate over two elements.  We’ll cover these operators first:

Assignment Operator

The first expression we’ll cover is the assignment operator.  Up until now we’ve been using it without explanation to cause variables to equal certain values.  That’s essentially the gist of this operation.

It takes whatever value is on the right of the assignment operator (=) and assigns or places that result in the variable that is listed on the left of the operator.  The left side of the operator is said to be the target of the operator.  The target of an assignment expression must be some kind of identifier that can hold a value.

NOTE: Often you’ll see the terms lvalue and rvalue in compiler error messages.  These simply map to the left side and the right side of the operator, in this case an object that can hold a value, and the value to be stored.

So, it’s general form looks like this:

Expression here may be any valid expression in the C language, including a literal value, or perhaps a complex mathematical construct involving many different other operators (like +, *, or -).

NOTE: In comparison to other programming languages the assignment expression in C can occur anywhere a valid expression is accepted.  Some languages such as Pascal treat the assignment operator as more of a statement, and make special considerations for it.  In C it is simply an expression.  This can actually allow you to chain assignment statements together like so: a = b = c = d = 5;  Something like this would make a, b, c and d all equal 5.  The result of the assignment expression is the value assigned.

Type Conversion

This brings us to an important aspect of assignment expressions that must be addressed before moving on.  This aspect is known as type conversion.  C allows you to specify different data types on either side of the assignment operator.  But how can this be?  The answer is that C automatically converts from one data type to another during the assignment.  The rule is simple: the type on the right side of the equal sign is converted to the data type on the left side of the equal sign.  This ultimately means that you may not receive all the data you planned to receive, because if a piece of data doesn’t fit into the left side, part of it is left out.  C routinely cuts off the higher-order (read the more significant bits) bits of a value to fit it into a smaller space.  Let’s take an example a couple examples:

As stated, when converting from a larger type of data to a smaller type of data the higher-order bits (those of greater value) are cut off.  If I have sixteen bits in an integer such as: 0101000010101110, and I try to fit them into an eight bit char, the bits on the left (the more significant bits), will be eliminated.  I will end up with 10101110 only in my char (as that’s all it can hold).  Likewise, if I try to convert a float or a double into an integer (a type that has no decimal value) I’ll lose the decimal value information and the value will be rounded.

The only tricky bugger here is the signed and unsigned char data type.  If I assign an unsigned char greater than 127 to a signed char, it will turn negative.  I actually won’t lose any data, but the computer will interpret the higher order bit to mean that the number is negative since it is now signed.

NOTE: There is a little programming shorthand trick known as the compound assignment.  The compound assignment takes the place of an expression such as a = a + 5;  or b = b * 2;   You can shorten these same expressions as a += 5;  or b *= 2;    As you can see there is a pattern to it.  Virtually any binary operator that is to be discussed in this and future articles can be shortened this way.

Addition Operator

The addition operator, +, takes the left value and the right value and adds them together resulting in the sum of their parts.  As an example:

You do have to keep in mind type conversion when performing these type of operations.  In the case of the addition, subtraction, multiplication, and division operators, unlike the assignment operator, you have what is called type promotion.  I handle type promotion at the end of the article.

Subtraction Operator

The subtraction operator, -, takes the left value and subtracts the right value from it, resulting in the difference between them.  As an example:

The – operator actually plays a small double duty as identifying numbers as negative.  However, it’s easy to tell the difference since the – operator to identify numbers as negative is unary (taking one argument), and will lack a left argument.  You do have to keep in mind type conversion when performing these type of operations.  In the case of the addition, subtraction, multiplication, and division operators, unlike the assignment operator, you have what is called type promotion.  I handle type promotion at the end of the article.

Multiplication Operator

The multiplication operator, *, takes the left value and multiplies it by the right value, resulting in the product of them both.  As an example:

You do have to keep in mind type conversion when performing these type of operations.  In the case of the addition, subtraction, multiplication, and division operators, unlike the assignment operator, you have what is called type promotion.  I handle type promotion at the end of the article.

Division Operator

The division operator, /, takes the left value and divides it by the right value, resulting in the division of them both.  It is important to note here that unless you are working with floats or doubles there will be no fractional remainder stored in the result.  Integers will divide to integers.  An example could be:

You do have to keep in mind type conversion when performing these type of operations.  In the case of the addition, subtraction, multiplication, and division operators, unlike the assignment operator, you have what is called type promotion.  I handle type promotion at the end of the article.

Modulus Operator

The modulus operator, %, takes the left value and divides it by the right value resulting in the remainder of the division.  Because it deals in the remainder of a division it cannot be used on doubles or floats.  An example might be:

Because modulus only operates on integers or whole numbers, type conversion is less of a concern.

The Unary Arithmetic Operators: Increment and Decrement

C includes two special operators that are shorthand for a more complex expression.  These are the increment and decrement operators.  They are typed in code as ++ and — respectively.  x++;  is shorthand for x = x + 1;  and x--;  is shorthand for x = x - 1; .  The ++ and — of these unary operators can be on either side of the operand, but it is important to understand the difference when doing so.  When an increment or decrement comes before its operand the expression is evaluated and the result returned as the result of the expression.  When it comes after its operand the expression’s resultant value is the value of the operand before the operation, even though the operation still occurs.  A code example can illustrate this difference:

In example 1 a will equal 6, as x is incremented and returned as the value of the expression.  However, in example 2 a will equal 5 as the value of the operand is returned as the value of the exprsession.  This doesn’t mean b++ isn’t processed, it is, and b will still equal 6 after the composite expression in example 2.

Order of Precedence

Arithmetic operators have an order of precedence, just like how math expressions have their order of precedence.  You read an expression from left to right, performing the given operations before moving down the list and starting over from left to right.  Here is the order of precedence of the arithmetic operators first:

  1. increment and decrement, ++ and —
  2. – (unary negative)
  3. multiplication, division and modulus, * / and %
  4. addition and subtractino, + –

So for example:

It is possible to interrupt or cause certain operators to be evaluated before others, breaking up the precedence by using the parentheses.  Anything in parenthese is executed first, from the inner most parentheses out, for example:

Type Promotion

You’ll find yourself mixing different types of literals and variables in arithmetic expressions often.  When this occurs, all the values are converted to the same type by the compiler.  Since we wouldn’t want to lose any information in the calculations, the compiler promotes the smaller data types to larger data types.  This is called type promotion.  It is actually a bit of an involved process, but in essence “two” steps happen.  The first step is straight-forward and is called integral promotion.  This is when all char and short int values are interpreted as straight up int values.  The second step is less straight forward and is executed at every operation.

Essentially in each operation the second operand is “converted” or promoted to the same data type as the first operand.  That is if the left hand operand is a float and the right hand operand is not a float, the right hand operand is promoted to a float by the compiler, and the resulting expression will return a float.  This occurs operation by operation in complex arithmetical expressions.

Conclusion

C includes the basic arithmetic operators, including assignment, division, multiplication, addition, subtraction and modulus.  When you operate on variables and other literals you have to be careful of your type conversions that C automatically does for you, lest you lose some of the data you are trying to protect.  There are also the increment and decrement operators, which are short hand for longer assignment and addition statements involving the number 1.  In fact, most C compilers actually process increment and decrement operations faster than their long hand companions.  In the next article we’ll be moving on to relational and logical operators which enable us to determine how variables relate to each other.

This article is part of a series – How to Program Anything: C Programming

If you appreciate this article you might consider supporting my Patreon.

But if a monthly commitment is a bit much, I get it, you might consider buying me a coffee.

photo credit: mikecogh Arithmetic via photopin (license)

kadar

I'm just a wunk, trying to enjoy life. I am a cofounder of http//originalpursuitssoc.com/ and I like computers, code, creativity, and friends.

You may also like...

1 Response

  1. October 16, 2017

    […] program, arithmetic, bitwise, logical, and relational.  We covered arithmetic operators in a previous article in the series.  We also already covered relational and logical operators in this article.  If […]

Leave a Reply

%d bloggers like this: