C variables, types and sizeof
Builds on lessons 1 to 2. Start at lesson 1
Learn
Types and sizeof
In C, a variable is not a magic box. It is a specific number of bytes somewhere in memory, and its type tells the compiler how many bytes and how to read them.
int age = 16; // a whole number
char letter = 'A'; // one byte, often used for characters
double price = 2.5; // a floating point number
long long big = 9000000000LL; // a wider whole numberEach declaration reserves that many bytes, and the name is the compiler's label for where they start:
letter [ ] 1 byte
age [ ][ ][ ][ ] 4 bytes
price [ ][ ][ ][ ][ ][ ][ ][ ] 8 bytesA char is just a 1-byte number: 'A' is stored as 65. You must declare the type before you use a variable, and it never changes, so the compiler knows the layout of everything in advance. That is part of why C is fast.
The sizeof operator tells you how many bytes something takes. It gives a value of type size_t, which you print with %zu:
printf("%zu\n", sizeof(int));Learn
Sizes and printf codes
Most sizes are implementation-defined. The C standard only guarantees that char is 1 byte and gives minimum ranges for the others. This runner compiles to 32-bit WebAssembly, so int, long and pointers are all 4 bytes and long long is 8. On a typical 64-bit laptop, int is still 4, but pointers are 8 bytes (and long is 8 on Linux and macOS, 4 on Windows). So sizeof(int*) prints 4 here and 8 there. Neither is wrong.
To print values, printf uses format codes: %d for int, %c for char, %f for double (%.2f for two decimals), %lld for long long. Use the wrong one and you get garbage, because printf trusts you about what bytes it was handed.
Learn
Dividing whole numbers
The type of the values decides the arithmetic. 7 / 2 is two ints, so the CPU does whole-number division and the answer is 3: the fraction is dropped, always towards zero, so -7 / 2 is -3. Storing the result in a double afterwards does not bring the .5 back, because it was gone before the assignment happened.
To divide properly, make at least one side a double: 7 / 2.0, or a cast, (double)7 / 2. A cast converts a value to another type. Going the other way, (int)2.99 chops the fraction off and gives 2. No rounding.
Try
Run it: sizes of variables
The example is already in the editor. Run it, change one thing, and run it again.
#include <stdio.h>
int main(void) {
int age = 16;
char grade = 'B';
double height = 1.72;
printf("age %d uses %zu bytes\n", age, sizeof(age));
printf("grade %c uses %zu byte\n", grade, sizeof(grade));
printf("height %.2f uses %zu bytes\n", height, sizeof(height));
printf("a pointer here uses %zu bytes\n", sizeof(int *));
return 0;
}
Practice
Measure the types
Use sizeof to print the size of char, int and long long, one per line, in this format:
char: 1int: 4long long: 8
#include <stdio.h>
int main(void) {
printf("char: %zu\n", sizeof(char));
return 0;
}
Practice
Declare and print three types
Declare an int called level set to 7, a char called rank set to 'S' and a double called score set to 98.5. Print: Level 7, rank S, score 98.50
#include <stdio.h>
int main(void) {
// declare level, rank and score here
printf("Level ?, rank ?, score ?\n");
return 0;
}
PracticePredict the output
Pizza slices and casts
Seven slices, two people. Read the program and type exactly what it prints, line by line.
#include <stdio.h>
int main(void) {
int slices = 7;
int people = 2;
double share = slices / people;
printf("%.1f\n", share);
printf("%.1f\n", (double)slices / people);
printf("%d\n", -slices / people);
printf("%d\n", (int)2.99);
return 0;
}
Your turn
Pages and star ratings
A video app shows per_page videos on each page. Write int pages_needed(int videos, int per_page), which rounds up so the last part-full page still counts (0 videos need 0 pages). Then write double average_rating(int stars, int votes), the exact average with its fraction kept. Assume per_page and votes are at least 1.
On your own. Hints open after your first check.
Passed
You can now
Keep going