Data Types & bool
Every variable in C has a data type. The type decides how much memory the variable uses, which values it can hold and what you can do with it. Choosing the right type is one of the first decisions you make for every value in a C program.
In this lesson you will meet the basic types, learn the printf specifier for each, see why decimal numbers are not exact, and learn how C23 made bool, true and false part of the language.
The basic types
| Type | Holds | Typical size | printf |
|---|---|---|---|
char | One character, or a small number | 1 byte | %c (or %d for its code) |
short | Small whole numbers | 2 bytes | %hd |
int | Whole numbers up to about ±2.1 billion | 4 bytes | %d |
long | Whole numbers | 4 or 8 bytes | %ld |
long long | Very large whole numbers | 8 bytes | %lld |
float | Decimal numbers, about 6-7 significant digits | 4 bytes | %f |
double | Decimal numbers, about 15-16 significant digits | 8 bytes | %f |
bool | true or false | 1 byte | %d |
The sizes are typical for a 64-bit computer. The C standard sets only minimum sizes, so they can differ between systems; Sizes, Limits & Overflow shows how to check them.
Whole numbers: int and its relatives
int is the everyday type for whole numbers: marks, counts, ages, years. When a value might be larger than about 2.1 billion, use long long. Each whole-number type also has an unsigned version that cannot be negative but reaches twice as high. Print unsigned values with %u, %lu or %llu.
#include <stdio.h>
int main(void)
{
int students = 62;
unsigned int seats = 120;
long long views = 5000000000LL; // 5 billion does not fit in an int
printf("Students: %d\n", students);
printf("Seats: %u\n", seats);
printf("Video views: %lld\n", views);
return 0;
}Students: 62 Seats: 120 Video views: 5000000000
The LL at the end of 5000000000LL is a suffix that makes the number a long long constant. Other suffixes are u for unsigned (120u), L for long, and f for float (3.5f). A decimal number with no suffix, such as 3.5, is a double.
Decimal numbers: float and double
float and double store floating-point numbers, numbers with a decimal point. double has about twice the precision of float and is the normal choice; use float only when memory is very tight, for example in large graphics or sensor arrays.
Floating-point numbers are stored in binary, and most decimal fractions, such as 0.1, have no exact binary form. The computer stores the nearest value it can:
#include <stdio.h>
int main(void)
{
float f = 0.1f;
double d = 0.1;
printf("float : %.20f\n", f);
printf("double: %.20f\n", d);
printf("0.1 + 0.2 = %.17f\n", 0.1 + 0.2);
return 0;
}float : 0.10000000149011611938 double: 0.10000000000000000555 0.1 + 0.2 = 0.30000000000000004
The double is much closer to 0.1 than the float, but neither is exact, and 0.1 + 0.2 is not exactly 0.3. This is why you should never use == to compare two decimal results, and why programs that handle money usually store whole paise in an integer type: Rs 1,299.50 becomes 129950 paise, and every calculation stays exact.
Characters are small numbers
A char stores one character, written in single quotes. Inside the computer it is just a small number, the character's code. In ASCII, the basic character code used by C on almost every system, 'A' is 65, 'B' is 66 and the digit '0' is 48.
#include <stdio.h>
int main(void)
{
char letter = 'A';
char digit = '7';
printf("%c has code %d\n", letter, letter);
printf("The letter after %c is %c\n", letter, letter + 1);
printf("Digit character %c has value %d\n", digit, digit - '0');
return 0;
}A has code 65 The letter after A is B Digit character 7 has value 7
Because the digit characters '0' to '9' have codes in a row, subtracting '0' turns a digit character into its number. Remember the difference between quotes: 'A' is one character, while "A" is a string, which you will study in Strings.
bool, true and false
A Boolean value is either true or false. Use the type bool for yes-or-no facts such as "has the student passed?" or "is the shop open?".
#include <stdio.h>
int main(void)
{
int marks = 72;
bool passed = marks >= 40;
bool has_backlog = false;
printf("passed = %d\n", passed);
printf("has_backlog = %d\n", has_backlog);
printf("Result: %s\n", passed ? "Pass" : "Fail");
bool from_number = 25; // any non-zero value becomes true
printf("from_number = %d\n", from_number);
return 0;
}passed = 1 has_backlog = 0 Result: Pass from_number = 1
A bool stores only 1 for true and 0 for false, so printing it with %d shows 1 or 0. When you store any other number in a bool, zero becomes false and every non-zero value becomes true. To print words instead of digits, the line passed ? "Pass" : "Fail" picks one of two strings; this is the conditional operator, explained in Operators & Precedence.
void: the absence of a type
void means "no value". You have already seen it in int main(void), where it says that main takes no inputs. You will also use it for functions that return nothing, in Functions & Prototypes. You cannot create a variable of type void.
Common mistakes
- Storing a phone number in an
int. A 10-digit mobile number such as 9876543210 is larger than the biggestint. It is also not a quantity you calculate with, so store it as text. - Using
floatordoublefor money. Rounding errors creep in. Store paise in an integer type instead. - Wrong format specifier.
%dwith adouble, or%fwith anint, prints nonsense.-Wallwarns about this. - Double quotes for a character.
char grade = "A";is wrong; writechar grade = 'A';. - Comparing decimals with
==. Check whether the difference is very small instead.
Key points
intis the everyday whole-number type; uselong longfor values beyond about 2.1 billion.- Unsigned types cannot hold negative numbers; print them with
%u,%luor%llu. doubleis the normal decimal type; floating-point values are approximate, so avoid==on them.- A
charstores one character as a small number code;'A'is 65 in ASCII. - In C23,
bool,trueandfalseare keywords; older code usesstdbool.hor plainintflags. - Choose a type for the meaning of the data, not just its digits: phone numbers are text, money is whole paise.
Exercise
Write a program for a Kochi electronics shop. Store the number of laptops in stock (45) in an int, the shop's yearly turnover in paise (3250000000, which is Rs 3.25 crore) in a long long, the average customer rating (4.6) in a double, the store's category letter ('E') in a char, and whether the shop offers EMI (true) in a bool. Print all five values with the correct format specifiers.
Show solution
#include <stdio.h>
int main(void)
{
int laptops = 45;
long long turnover_paise = 3250000000LL;
double rating = 4.6;
char category = 'E';
bool offers_emi = true;
printf("Laptops in stock: %d\n", laptops);
printf("Turnover (paise): %lld\n", turnover_paise);
printf("Rating: %.1f\n", rating);
printf("Category: %c\n", category);
printf("Offers EMI: %d\n", offers_emi);
return 0;
}Laptops in stock: 45 Turnover (paise): 3250000000 Rating: 4.6 Category: E Offers EMI: 1
The turnover in paise is larger than the biggest int, so it needs long long and %lld. %.1f prints the rating with one decimal place.
Quick Quiz
1. Which type should store the value 5,000,000,000 (five billion)?
An int holds up to about 2.1 billion on common systems; long long holds much larger values.
2. What does printf("%d", true); print in C23?
true is stored as 1, and %d prints it as a number.
3. Why is 0.1 + 0.2 == 0.3 false in C?
Most decimal fractions are stored as close approximations, so the sum is slightly different from 0.3.
4. Before C23, what did programs usually include to use bool?
C99 programs included stdbool.h, which defined bool, true and false as macros.
Learn C with a mentor
Free lessons get you started. Our Java, C & C++ Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
