Operators
One of the things programs do most is math: the total price, the average score, how much is left. Arithmetic in C works much like in math class, but two things often surprise people: 7 / 2 is 3, and an int can run out of room.
1#include <stdio.h>2 3int main(void) {4 int price = 12;5 int quantity = 3;6 int total = price * quantity;7 printf("Total: $%d\n", total);8 return 0;9}
Total: $36
price * quantity is worked out first, giving 36, and then stored in total. A calculation can go on the right of an assignment, or straight into a printf.
Arithmetic operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | add | 17 + 5 | 22 |
- | subtract | 17 - 5 | 12 |
* | multiply | 17 * 5 | 85 |
/ | divide | 17 / 5 | 3 |
% | remainder | 17 % 5 | 2 |
1#include <stdio.h>2 3int main(void) {4 int a = 17;5 int b = 5;6 printf("%d + %d = %d\n", a, b, a + b);7 printf("%d - %d = %d\n", a, b, a - b);8 printf("%d * %d = %d\n", a, b, a * b);9 printf("%d / %d = %d\n", a, b, a / b);10 printf("%d %% %d = %d\n", a, b, a % b);11 return 0;12}
17 + 5 = 22 17 - 5 = 12 17 * 5 = 85 17 / 5 = 3 17 % 5 = 2
The %% on the last line is from lesson 3: it shows a % in the text of a printf.
Integer division
When you divide one int by another, the result is an int too: the decimal part is simply dropped, not rounded. So 17 / 5 is 3, not 3.4.
1#include <stdio.h>2 3int main(void) {4 printf("%d\n", 7 / 2);5 printf("%d\n", 19 / 4);6 printf("%d\n", 9 / 10);7 return 0;8}
3 4 0
9 / 10 is 0.9, and without the decimal part that is 0. Also, never divide by 0: that is undefined behavior, and our engine stops at that line.
What does this print?
1#include <stdio.h>2 3int main(void) {4 int minutes = 100;5 printf("%d\n", minutes / 60 * 60);6 return 0;7}
It works from left to right: 100 / 60 is integer division and gives 1, then 1 * 60 gives 60. The part that was dropped doesn't come back.
Remainders
% gives the remainder left over from integer division. Divide one number by another: / gives how many times it fits, % gives what is left. They are handy together:
1#include <stdio.h>2 3int main(void) {4 int eggs = 50;5 int boxes = eggs / 6;6 int left = eggs % 6;7 printf("%d eggs: %d full boxes, %d left over\n", eggs, boxes, left);8 printf("%d\n", 8 % 2);9 printf("%d\n", 7 % 2);10 return 0;11}
50 eggs: 8 full boxes, 2 left over 0 1
A number whose % 2 is 0 is even; otherwise it is odd (1, or -1 for a negative odd number). % only works on whole numbers; 7.5 % 2 is a compile error.
Decimal division and casting
If either side is a double, the result is a double and keeps its decimal part. But storing the result of an integer division in a double is too late:
1#include <stdio.h>2 3int main(void) {4 double a = 7.0 / 2;5 double b = 7 / 2.0;6 double c = 7 / 2;7 printf("%f\n", a);8 printf("%f\n", b);9 printf("%f\n", c);10 return 0;11}
3.500000 3.500000 3.000000
c is 3.000000: both sides of 7 / 2 are whole numbers, so it works out 3 first and only then stores it in a double.
When both numbers are int variables, as when you work out an average score, write (double) in front of one to cast it, that is, turn it into a double, before dividing:
1#include <stdio.h>2 3int main(void) {4 int total = 256;5 int count = 3;6 printf("%.2f\n", (double)total / count);7 printf("%.2f\n", (double)(total / count));8 return 0;9}
85.33 85.00
The first line turns total into 256.0 and then divides, giving 85.33. On the second line the parentheses do the integer division first, giving 85, and casting afterward can't bring the decimals back. The other way around, (int)3.9 gives 3, dropping the decimal part.
+= and ++
"Add a bit to what is already there" is so common that it has a shorthand:
| You write | Same as |
|---|---|
balance += 50; | balance = balance + 50; |
balance -= 30; | balance = balance - 30; |
balance *= 2; | balance = balance * 2; |
visits++; | visits = visits + 1; |
visits--; | visits = visits - 1; |
1#include <stdio.h>2 3int main(void) {4 int balance = 100;5 balance += 50;6 balance -= 30;7 balance *= 2;8 printf("Balance: %d\n", balance);9 int visits = 0;10 visits++;11 visits++;12 visits--;13 printf("Visits: %d\n", visits);14 return 0;15}
Balance: 240 Visits: 1
Press Step and watch what balance and visits become after each line. ++ and -- can also go in front (++visits); on a line of their own both forms do the same thing. Inside a bigger calculation they differ, so don't use them that way for now.
Multiply before you add
Just as in math class, *, / and % are worked out before + and -; operators on the same level go from left to right. To make a part go first, put it in parentheses.
1#include <stdio.h>2 3int main(void) {4 int a = 80;5 int b = 90;6 int c = 70;7 printf("%d\n", 2 + 3 * 4);8 printf("%d\n", (2 + 3) * 4);9 printf("%d\n", a + b + c / 3);10 printf("%d\n", (a + b + c) / 3);11 return 0;12}
14 20 193 80
The third line is meant to be the average of three scores, but only c is divided by 3, so it gives 193. The fourth line, with parentheses, gives the right answer, 80.
Tip: When you're not sure what goes first, add parentheses. An extra pair costs nothing and makes the code easier to read.
Integer overflow
As lesson 2 said, an int usually takes 4 bytes, so the numbers it can hold have a top and a bottom. INT_MAX and INT_MIN from <limits.h> are those two numbers:
1#include <stdio.h>2#include <limits.h>3 4int main(void) {5 printf("Largest int: %d\n", INT_MAX);6 printf("Smallest int: %d\n", INT_MIN);7 return 0;8}
Largest int: 2147483647 Smallest int: -2147483648
What happens if you add 1 to the largest one?
1#include <stdio.h>2#include <limits.h>3 4int main(void) {5 int views = INT_MAX;6 printf("%d\n", views);7 views = views + 1;8 printf("%d\n", views);9 return 0;10}
2147483647
signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'What happened: Stopped at line 7. The result doesn't fit in its type: the number is too big.
Going past the range of int is called overflow, and it is undefined behavior too. On an ordinary computer it often turns quietly into a large negative number and the program carries on, so the mistake is hard to spot. Our engine stops at the line where it overflows. When a number might get very big (the population of the world, say), you need a bigger type, such as long long, which you'll meet later.
Practice
Write the code, then press Check. A hint costs nothing; the answer is there when you need it.
Hours and minutes
✓Turn total_minutes into hours and minutes, and print 2 hours 15 minutes.
2 hours 15 minutes
1#include <stdio.h>2 3int main(void) {4 int total_minutes = 135;5 int hours = 0;6 int minutes = 0;7 printf("%d hours %d minutes\n", hours, minutes);8 return 0;9}
Celsius to Fahrenheit
✓Fahrenheit = Celsius × 9 ÷ 5 + 32. Work out fahrenheit and print 36.6°C = 97.9°F.
36.6°C = 97.9°F
1#include <stdio.h>2 3int main(void) {4 double celsius = 36.6;5 double fahrenheit = 0;6 printf("%.1f°C = %.1f°F\n", celsius, fahrenheit);7 return 0;8}
Fix it
✓45 of 60 answers are right, so the score should be 75.0%, but this program prints 0.0%. Fix it so it prints Score: 75.0%.
Score: 75.0%
1#include <stdio.h>2 3int main(void) {4 int correct = 45;5 int total = 60;6 double rate = correct / total * 100;7 printf("Score: %.1f%%\n", rate);8 return 0;9}
What you learned
+ - * / %add, subtract, multiply, divide and give the remainder.- Dividing one
intby another drops the decimal part:7 / 2is 3;%gives the remainder. - If either side is a
double, so is the result; to get decimals from twointvariables, write(double)a / b. +=,-=and*=are shorthands;x++adds 1 andx--subtracts 1.- Multiply and divide before adding and subtracting; same level goes left to right; when unsure, add parentheses.
inthas a limit,INT_MAX; going past it is overflow, which is undefined behavior.