</>CodexBash
C
CBeginner11 min

Variables and data types

Declaring variables, C's number and character types and their sizes, overflow, sizeof, constants, and converting between types.

Variables are named boxesstep 1/6
?
age
?
name
?
count
Three variables, not yet given a value. Each is a named box in memory.

In C, every variable has a fixed type, chosen when you declare it, and the type decides how much memory it uses and what it can hold.

Declaring variables#

int age = 21;
double price = 99.5;
char grade = 'A';

The type comes first, then the name, then optionally a starting value. A variable declared without a value holds whatever was in that memory before, so always initialise:

int total;          // unknown value: a bug waiting to happen
int count = 0;      // known

The common types#

TypeTypical sizeHolds
char1 byteone character, or a small number
int4 byteswhole numbers to about ±2.1 billion
long long8 byteswhole numbers to about ±9.2 × 10^18
double8 bytesnumbers with a fraction, about 15 significant digits
float4 bytesthe same, about 7 digits; rarely worth using

bool with true and false comes from #include <stdbool.h>. Underneath, false is 0 and anything else is true.

sizeof#

sizeof tells you how many bytes a type or variable uses on your machine:

printf("%zu\n", sizeof(int));        // usually 4
printf("%zu\n", sizeof(long long));  // 8

%zu is the placeholder for the size type that sizeof produces.

Overflow#

An int has a largest value, INT_MAX from <limits.h>, which is 2147483647. Go past it and the result is wrong without any warning:

int big = 2147483647;
big = big + 1;      // undefined behaviour: in practice usually -2147483648

This is the single most common source of wrong answers in C. When values can approach a billion, or you add many of them up, or multiply two of them, use long long:

long long total = 0;
total += 1000000000LL * 3;   // 3000000000, fits

The LL suffix makes the literal itself a long long, so the multiplication happens in 64 bits.

Characters are numbers#

A char stores a small integer, the character's code. That makes arithmetic on characters useful:

char c = '7';
int digit = c - '0';      // 7
char lower = 'b';
int index = lower - 'a';  // 1
char upper = lower - 32;  // 'B' in ASCII; toupper() from <ctype.h> is clearer

Single quotes are one char; double quotes are a string. 'A' and "A" are different things.

Constants#

const int DAYS_IN_WEEK = 7;
#define MAX_STUDENTS 100

const makes a variable read-only. #define is a text substitution done before compiling; it is common in older code and for array sizes.

Converting between types#

Mixing types converts the narrower one automatically, but integer division happens before any conversion:

int a = 7, b = 2;
double wrong = a / b;            // 3.0: the division was between ints
double right = (double) a / b;   // 3.5
int truncated = (int) 3.9;       // 3: the fraction is dropped, not rounded

(double) a is a cast: an explicit conversion.

Key points#

  • Declare a type for every variable, and always give it a starting value.
  • int overflows past about 2.1 billion; use long long for large values.
  • char is a small number, so c - '0' and c - 'a' are everyday tricks.
  • Dividing two ints throws the fraction away; cast first to keep it.

Next: operators, including a few that C has and many languages do not.

Practise it

The same idea, in the order it is worth meeting it.

  1. Not startedHow many digitsEasy
  2. Not startedTurn the digits aroundEasy
Create a free account to track your progress