Step 1 of 5 · Reading · ~3 min
Learn
Getting Started
Variables and Types
By the end of this lesson you can declare variables of C's core types, read numbers into them with scanf, and predict exactly what happens when a double is turned into an int.
A variable is a name for some bytes
A C variable is a name for some bytes at a real address, with a type that tells the compiler how many bytes there are and how to read them.
int count = 42; // 4 bytes, whole number, about +/-2.1 billion
long long big = 5000000000LL; // 8 bytes, for when int is too small
double price = 9.99; // 8 bytes, floating point (has a fractional part)
char grade = 'A'; // 1 byte; single quotes mean one character
Type first, then name. double is the default floating type (float exists but is less precise). C had no boolean type until C99; #include <stdbool.h> gives you bool, true and false, and older code uses an int where 0 means false and anything else means true.
Uninitialized means garbage
int x;
printf("%d\n", x); // prints whatever those bytes held before
C does not zero local variables. The bug often hides because the garbage happens to be 0 in small tests. The rule costs nothing: initialize at declaration, as in double price = 0.0;.
Reading input: scanf and the &
scanf is the reverse of printf: a format string, then the variables to fill, each prefixed with &. The & means "the address of", because scanf needs to know where to store the value. Forget it and the program compiles, then crashes or corrupts memory.
The specifier must match the variable's type, and here C is inconsistent in a way every C programmer memorises:
| Type | read with scanf | print with printf |
|---|---|---|
int | %d | %d |
double | %lf | %f |
char | %c | %c |
A small program that reads one temperature and echoes it:
#include <stdio.h>
int main(void) {
double celsius = 0.0;
scanf("%lf", &celsius);
printf("%f\n", celsius);
return 0;
}
Input 21.5 prints 21.500000: %f always shows six decimal places (the next lesson shows how to choose fewer). Numeric specifiers skip spaces and newlines first, so values on one line or on separate lines read the same way.
Two wrong versions of that program, and what they do with the input 21.5:
scanf("%f", &celsius)with adouble:%finscanfmeansfloat, which is 4 bytes, so only half ofcelsiusis written. The printed value is nonsense.int celsiusread with%d:scanfreads21, stops at the., and leaves.5unread for the nextscanf, which then fails.
Converting double to int: truncation
Assigning a double to an int compiles silently and drops the fractional part, moving toward zero. It does not round.
| value | (int)value |
|---|---|
| 3.99 | 3 |
| 0.5 | 0 |
| -0.5 | 0 |
| -3.99 | -3 |
Write the cast yourself, int whole = (int)price;, so a reader sees the conversion. Never hand a double to %d without the cast: printf trusts the specifier and prints an unrelated integer.
Common mistakes
- Declaring the variables as
int. With input2.5and1.25, reading stops at the first., so the sum comes out wrong instead of3.750000. - Rounding instead of truncating. A sum of
2.9must give2, not3; adding0.5before the cast is a different operation. - Rounding negatives down. A sum of
-0.75casts to0and-2.75casts to-2, because truncation moves toward zero. - Using
%finscanf, or%dfor adoubleinprintf. Both compile and print garbage.
Your exercise
Read two decimal numbers, then print their sum as a double and the sum converted to int. The starter is only the skeleton of main: you write the declarations, the scanf and both printf calls. The mistake to watch is the specifier: %lf to read a double, %f to print one.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…