De ce contează?
La un campionat sportiv, fiecare concurent primește un număr de ordine — nu mai e „Maria” sau „Andrei”, ci concurentul 65 sau concurentul 97. Calculatorul face exact la fel cu literele: nu știe ce e un „A”, dar știe că „A” are numărul de ordine 65. Tot ce vezi pe ecran ca text, mașina ține minte ca pe niște numere.
Ce este
Tipul char păstrează un singur caracter: o literă, o cifră, un semn de punctuație sau un spațiu. Ocupă un singur octet (8 biți) în memorie.
Dar iată surpriza: în memorie un char nu este chiar litera, ci un cod numeric care reprezintă litera. Tabela care leagă fiecare caracter de codul lui se numește ASCII. Câteva exemple: 'A' are codul 65, 'a' are codul 97, '0' are codul 48, iar spațiul ' ' are codul 32.
Pentru că un char este de fapt un număr, poți face aritmetică cu el — exact ca pe orice întreg.
Cheia care face tipul char util la algoritmică: codurile literelor și ale cifrelor sunt consecutive și în ordine. Literele mici 'a', 'b', ..., 'z' au codurile 97, 98, ..., 122, fiecare cu unul mai mare decât precedenta. La fel, cifrele '0', '1', ..., '9' au codurile 48, 49, ..., 57. De aici toată magia: scăderea a două caractere îți spune câte poziții le separă.
Cum arată
Iată câteva caractere des folosite și codul lor ASCII:
| Caracter | Cod ASCII |
|---|---|
' ' (spațiu) | 32 |
'0' | 48 |
'A' | 65 |
'a' | 97 |
Observă spațierea: literele mari încep de la 65, cele mici de la 97 (cu 32 mai mult), iar cifrele de la 48. Pentru că un grup întreg de litere e consecutiv, codurile lor stau lipite unul de altul:
a | b | c | d | e |
0 | 1 | 2 | 3 | 4 |
97 | 98 | 99 | 100 | 101 |
0 | 1 | 2 | 3 | 4 |
c=99 |
Din a doua diagramă citești direct ideea care contează: 'c' stă cu 2 poziții după 'a', deci 'c' - 'a' dă 99 - 97 = 2. Ai aflat poziția literei în alfabet fără să memorezi niciun cod.
Implementare C++
Declari un char și îi dai o valoare între apostrofuri (un caracter, nu un șir). Ca să-i vezi codul numeric, îl convertești la int cu (int)c:
#include <iostream>
using namespace std;
int main() {
char c = 'A';
// afisam caracterul si codul lui ASCII
cout << c << " are codul " << (int)c << "\n"; // A are codul 65
// pozitia unei litere mici in alfabet: scadem 'a'
char litera = 'c';
int pozitie = litera - 'a';
cout << "Pozitia: " << pozitie << "\n"; // 2
// o cifra-caracter transformata in numarul ei: scadem '0'
char cifra = '7';
int valoare = cifra - '0';
cout << "Valoarea: " << valoare << "\n"; // 7
// litera mica -> litera mare: scadem 32 (97 - 65)
char mic = 'a';
char mare = mic - 32;
cout << "Litera mare: " << mare << "\n"; // A
return 0;
}Trei tipare apar tot timpul la șiruri de caractere:
(int)c— codul ASCII al caracterului ((int)'A'dă 65).c - 'a'— poziția unei litere mici în alfabet ('c' - 'a'dă 2), folosită des pentru a indexa un vector de 26 de poziții (câte una pentru fiecare literă).c - '0'— transformă o cifră scrisă ca text în numărul ei ('7' - '0'dă 7), util când citești un număr caracter cu caracter.
Cea mai frecventă confuzie: '7' NU este numărul 7. Caracterul '7' are codul ASCII 55, deci '7' + 1 dă 56 (codul lui '8'), nu 8. Ca să obții numărul 7 dintr-un caracter-cifră, scazi mereu '0': '7' - '0' dă 7.
A doua capcană, mai subtilă: pe multe compilatoare char este signed, adică poate ține și valori negative. Codurile ASCII trec de 127 pentru caractere speciale (de exemplu litere cu diacritice), iar acolo un char signed le vede ca numere negative. Dacă lucrezi cu astfel de coduri, folosește unsigned char ca să eviți surprizele.