Operators and expressions

Introduction

C works out expressions with the usual maths rules: *, / and % before + and -, and brackets first. One rule surprises almost everyone, though.

Arithmetic in C follows the type of its values, not what you might expect from maths. Most wrong averages and strange negative numbers in student programs come from the rules in this lesson.

How it works

Shortcuts: ++, -- and +=

#include <stdio.h>

int main(void) {
    int x = 10;
    x += 5;
    x *= 2;
    x -= 4;
    int i = 0;
    i++;
    i++;
    printf("x = %d, i = %d\n", x, i);
    return 0;
}
Open in compiler
  • x += 5 means x = x + 5. There are also -=, *=, /= and %=.
  • i++ adds 1 to i. In a statement of its own, i++ and ++i do the same thing.

Numbers have limits

An int holds values up to 2147483647. Going past that is called overflow. In real C the result silently becomes a wrong number; StepVioz stops and shows you where it happened:

#include <stdio.h>

int main(void) {
    int big = 2000000000;
    long long safe = (long long)big * 2;
    printf("%lld\n", safe);
    int wrong = big * 2;
    printf("%d\n", wrong);
    return 0;
}
Open in compiler

Use long long (up to about 9 × 10^18, printed with %lld) when numbers can get large, such as factorials.

Syntax

int q = 7 / 2;                // 3
int r = 7 % 2;                // 1
double x = (double)7 / 2;     // 3.5
n += 5;
n++;

Example

#include <stdio.h>

int main(void) {
    int a = 7, b = 2;
    int whole = a / b;
    int left = a % b;
    double exact = (double)a / b;
    printf("%d remainder %d, exactly %.1f\n", whole, left, exact);
    return 0;
}
Open in compiler

7 / 2 is 3, not 3.5: when both sides are int, C throws the fraction away. To get 3.5, make one side a double, either with 7.0 or with a cast such as (double)a. The calculation box shows each step with the values filled in.

The remainder operator % gives what is left over: 7 % 2 is 1. It is how you test for even numbers (n % 2 == 0) and take the last digit of a number (n % 10).

Line by line

  1. a is 7 and b is 2, both ints.
  2. a / b gives 3, because both sides are ints.
  3. a % b gives the 1 that was left over.
  4. (double)a / b converts a first, so the division keeps its fraction.
  5. printf shows all three, using %.1f for the double.

Expected result

3 remainder 1, exactly 3.5

In the real world

The remainder operator decides which server handles a request, and which row a seat is in. Overflow has caused real disasters, including the loss of the Ariane 5 rocket in 1996.

Common mistakes

  • average = sum / count; with two ints: the fraction is lost before it reaches the double. Write (double)sum / count.
  • % works only on whole numbers. For doubles use fmod from math.h.
  • Writing x =+ 5 (which means x = +5) instead of x += 5.

Best practices

  • Use brackets whenever the order is not obvious.
  • Cast before dividing when you want a fraction.
  • Think about the largest value a calculation can reach.

Summary

C's arithmetic follows the types involved. Dividing two ints drops the fraction, % gives the remainder, and a cast converts a value on purpose. int has limits, and long long gives far more room.

Quick check

1. What is 9 / 4 in C, when both are ints?
2. What is 17 % 5?
3. Which line makes avg equal 2.5 when a = 5 and b = 2 are ints?

Key takeaways

  • Two ints divided give an int.
  • Cast before you divide.
  • Use long long when a product can be large.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.