Tak jak w Javie czy Pascalu, obowiązuje w C/C++ zasada ścisłej kontroli typu. Wszystkie występujące w programie zmienne muszą być przed ich pierwszym użyciem zadeklarowane i zdefiniowane. O ile jednak np. w Javie deklaracja zmiennej jest zawsze jednocześnie jej definicją (to znaczy wiąże się z przydzieleniem tej zmiennej pamięci), o tyle w C/C++ deklaracja nie zawsze oznacza definicję — zmienną definiować, czyli przydzielać jej miejsce w pamięci można oczywiście tylko raz, ale deklarować wielokrotnie. Jak to możliwe, wyjaśnimy bardziej szczegółowo w rozdziale na temat zmiennych zewnętrznych . Samą zmienną możemy uważać za nazwane miejsce w pamięci, w którym przechowywana jest wartość pewnego znanego kompilatorowi typu. Kompilator potrzebuje tej informacji, aby zarezerwować na zmienną odpowiednią ilość pamięci i aby wiedzieć, jak interpretować różne operacje na tej zmiennej.
Zasady poprawności identyfikatorów (nazw) zmiennych są w C/C++ podobne jak w innych językach: identyfikatory mogą składać się z liter, cyfr i znaku podkreślenia; nie mogą rozpoczynać się cyfrą (w odróżnieniu od niektórych innych języków, znaki waluty nie są w identyfikatorach dozwolone).
Tak więc nazwy (identyfikatory) A_book i a_book będą traktowane jako różne.
Wbudowane typy podstawowe są podobne do tych, jakie być może Czytelnik zna z Javy. Występują jednak pewne różnice. W szczególności, nie jest gwarantowana stała długość (w bajtach) reprezentacji maszynowej zmiennych poszczególnych typów. Na przykład, zmienne typu int mogą mieć rozmiar, w zależności od implementacji, 2, 4 lub 8 bajtów (obecnie jednak prawie zawsze są to cztery bajty). W związku z tym istnieje przydatny, wbudowany operator sizeof, który zwraca długość reprezentacji binarnej zmiennej danego typu na danej platformie (w bajtach). Użyć tego operatora możemy tak jak funkcji, której jedynym argumentem jest albo dowolna zmienna typu, dla którego chcemy poznać długość reprezentacji, albo nazwa samego typu (w pierwszym z tych przypadków nawias jest opcjonalny). Podanie nazwy typu wystarczy, gdyż
Jak powiedzieliśmy, wszystkie zmienne — nazwane
obszary pamięci o określonym adresie i typie — musza być przed
pierwszym użyciem zadeklarowane i zdefiniowane. Jak to zrobić, pokażmy
na przykładzie zmiennych typu
int:
      1.  #include <iostream>
      2.  using namespace std;
      3.  
      4.  int main() {
      5.      int k1;
      6.      int k2();
      7.      int k3(1);
      8.      int k4{};
      9.      int k5{1};
     10.      int n=1, m = n, i{1}, j{i};
     11.  }
Jak widać, podajemy najpierw nazwę typu, a potem nazwę definiowanej zmiennej. Nie musimy, ale raczej powinniśmy, nadać nowowprowadzonej zmiennej jakąś sensowną wartość. Robimy to poprzez zainicjowanie zmiennej od razu w miejscu definicji. Na przykład w powyższym programie:
       int n = 1;
       int m = n;
       int i{1};
       int j{i};
z czego widać, że, na przykład, definiując
m
 możemy traktować
n
 jako już istniejącą zmienną.
      1.  #include <iostream>
      2.  #include <string>
      3.  using namespace std;
      4.  
      5.  int main() {
      6.      long double ld = 0;
      7.      string      st = "Hermenegilda";
      8.      short       sh = 0;
      9.      long       *lo = 0;
     10.      cout << "long double: " << sizeof ld         << endl
     11.           << "double     : " << sizeof(double)    << endl
     12.           << "float      : " << sizeof(float)     << endl
     13.           << "long long  : " << sizeof(long long) << endl
     14.           << "long       : " << sizeof(long)      << endl
     15.           << "int        : " << sizeof(int)       << endl
     16.           << "short      : " << sizeof sh         << endl
     17.           << "char       : " << sizeof(char)      << endl
     18.           << "bool       : " << sizeof(bool)      << endl
     19.           << "string     : " << sizeof st         << endl
     20.           << "long*      : " << sizeof lo         << endl;
     21.  }
dał wyniki następujące ma maszynie 32-bitowej
    long double: 12
    double     : 8
    float      : 4
    long long  : 8
    long       : 4
    int        : 4
    short      : 2
    char       : 1
    bool       : 1
    string     : 4
    long*      : 4
Widać, że w tym systemie typ
long
 ma tę samą
reprezentację co
int
 (tak zwykle jest na
maszynach 32-bitowych).
Ten sam program na maszynie 64-bitowej może wypisać
    long double: 16
    double     : 8
    float      : 4
    long long  : 8
    long       : 8
    int        : 4
    short      : 2
    char       : 1
    bool       : 1
    string     : 8
    long*      : 8
Tu, jak widać, typ
long
 ma tę sama reprezentację co
long long.
Widać też, że w obu przypadkach zmienna typu string ma tyle bajtów, ile wskaźnik (na przykład long* w ostatnim wierszu) — a więc prawdopodobnie jest wskaźnikiem (choć pewnie nie zwykłym, a „inteligentnym”).
Jak widać, deklaracja typu ma postać
Typ zmienna;choć, w C++11 może to być też
auto zmienna = wartość;lub
decltype(wyrażenie) zmienna;Słowo kluczowe auto znaczy tu, że kompilator sam ma się domyślić, patrząc na wartość inicjującą, jaki ma być typ deklarowanej/definiowanej zmiennej (oczywiście typ ten będzie ściśle ustalony i nie może być potem zmieniony). Z kolei decltype znaczy, że zmienna ma być tego typu, co wartość wyrażenia podanego w nawiasie. Przykład powinien wyjaśnić sposób, w jaki sposób obie konstrukcje mogą być zastosowane:
      1.  #include <iostream>
      2.  using namespace std;
      3.  
      4.  int main() {
      5.      auto k = 7;             // k jest typu int
      6.      auto x = 1.;            // x jest typu double
      7.      decltype(x) y = 7;      // y jest typu double, choć
      8.                              // '7' jest literałem typu int
      9.      decltype(k*x) z = 7;    // iloczyn k*x jest typu double
     10.      cout << "k/2="   << k/2 << ", y/2=" << y/2
     11.           << ", z/2=" << z/2 << endl;
     12.  }
Programik ten drukuje
    k/2=3, y/2=3.5, z/2=3.5
co pokazuje, że rzeczywiście
y
 i 
z
 są typu
double
 — gdyby były typu
int, to dzielenie przez
2 dałoby wynik dokładnie 3 (tak jak to jest w przypadku
k)
Przydatność tych konstrukcji może się na tym etapie wydawać wątpliwa, ale przekonamy się, że są one niezwykle przydatne!
T.R. Werner, 21 lutego 2016; 20:17