Pe scurt
Un pointer la caracter poate indica un element al unui tablou C de caractere. Dacă char s[] = "ana";, pointerul p=s indică prima literă; *(p+1) este „n”. Un șir C se termină la caracterul nul '\0', pe care îl întâlnim la parcurgerea prin pointer.
În detaliu
Un pointer la caracter, char *p, păstrează adresa unui caracter din memorie. Pentru char s[] = "ana"; numele s desemnează adresa primului caracter, deci char *p = s; face ca p să indice litera a de pe poziția 0. Operatorul *p dă caracterul indicat, iar *(p + 1) dă caracterul următor, adică n; expresia p + 1 este adresa următorului caracter și poate fi folosită ca un șir care începe de acolo: p + 1 este textul "na". Un șir C se termină la caracterul nul '\0', pe care îl întâlnim la parcurgerea prin pointer. Scăderea a doi pointeri din același tablou dă numărul de poziții dintre ei, (p - s). Aritmetica pointerilor este validă numai în interiorul aceluiași tablou, cel mult până la poziția imediat următoare ultimului element, care nu se dereferențiază.
Exemplul 1 — lungimea unui șir parcurs prin pointer.
#include <iostream>
using namespace std;
int main() {
char s[] = "ana";
char *p = s;
int n = 0;
while (*p != '\0') {
++n;
++p;
}
cout << n;
return 0;
}
Pointerul trece prin a, n, a, apoi se oprește la terminator; se afișează 3. Avansarea lui p nu modifică literele și nu schimbă adresa stocată în numele tabloului s. Terminatorul oprește parcurgerea numai dacă șirul C este corect format.
Exemplul 2 — poziția unui caracter sau subșir. Funcțiile strchr și strstr întorc un pointer la potrivire sau NULL. Pentru char s[] = "mare";, strchr(s, 'r') indică litera r, iar strchr(s, 'r') - s este poziția 2. strstr(s, "ar") indică începutul subșirului, la poziția 1. Verifică întâi că rezultatul nu este NULL, apoi scade adresa de început.
char s[] = "mare";
char *p = strchr(s, 'r');
if (p != NULL)
cout << (p - s);
Cu <cstring> inclus, ieșirea este 2.
Exemplul 3 — copiere, concatenare, ștergere. strcpy(dest, s) copiază textul împreună cu terminatorul, iar strcat(dest, "!") adaugă semnul la final; destinația trebuie să aibă loc pentru rezultat și pentru terminator. După char t[10] = "ma"; strcat(t, "re"); tabloul t conține mare. Ștergerea caracterului indicat de p se face mutând sufixul: memmove(p, p + 1, strlen(p)). Din ana, cu p la poziția 1, rezultă aa; sunt mutate și caracterul nul.
Exemplul 4 — parcurgerea de la sfârșit. Pointerul poate porni de la ultimul caracter, p = s + strlen(s) - 1, și poate scădea până ajunge la începutul tabloului. Pentru mare, p indică inițial litera e; afișând *p și scăzând p, ciclul while (p >= s) scrie e, r, a, m, adică eram. Dacă ciclul ar avea condiția p > s, litera m de la poziția 0 ar fi omisă. Un pointer care iese din tablou, cum ar fi s - 1, nu trebuie dereferențiat.
Exemplul 5 — numărarea aparițiilor cu strchr. Căutarea se reia de la poziția următoare ultimei potriviri, până când strchr întoarce NULL.
char s[] = "banana";
int c = 0;
for (char *p = strchr(s, 'a'); p != NULL; p = strchr(p + 1, 'a'))
++c;
cout << c;
Potrivirile sunt pe pozițiile 1, 3 și 5, deci se afișează 3. Dacă reluarea ar începe de la p, nu de la p + 1, aceeași potrivire ar fi găsită la nesfârșit și ciclul nu s-ar opri.
Exemplul 6 — inversarea unui șir cu doi pointeri. Pointerul i pornește de la început, j de la ultimul caracter, iar la fiecare pas se schimbă cele două litere și pointerii se apropie.
char s[] = "mare";
char *i = s, *j = s + strlen(s) - 1;
while (i < j) {
swap(*i, *j);
++i;
--j;
}
cout << s;
Primul schimb dă eara, al doilea dă eram, apoi i și j se întâlnesc și ciclul se oprește. La un șir de lungime impară, cum este ana, caracterul din mijloc rămâne pe loc, pentru că i și j ajung să indice aceeași poziție.
Pentru admitere
Pentru char s[] = "mare";, expresia s + 1 indică al doilea caracter și poate fi folosită ca șirul "are", deoarece la final există terminatorul '\0'. Se afișează un șir C prin cout << p, caracterele de la p până la terminator. În C, funcțiile se declară în <string.h> și se scriu fără std::: strchr, strstr, strcpy și strcat. Funcțiile de copiere și concatenare cer destinație suficient de mare. Poziția găsită de strchr sau strstr se obține scăzând adresa de început: pentru char s[] = "ana";, strstr(s, "na") - s este 1. Verifică întâi că pointerul nu este NULL.
Exemplu în formatul examenului. Ce se afișează în urma executării secvenței de mai jos?
char s[] = "mare";
char *p = s + 1;
cout << p << ' ' << *p << ' ' << (p - s);
- a)
mare m 1 - b)
are a 1 - c)
are a 0 - d)
a a 1
Răspunsul corect este b). Pointerul p indică al doilea caracter al tabloului, deci cout << p afișează șirul care începe acolo, adică are. Expresia *p este caracterul indicat, a. Diferența p - s este numărul de poziții dintre cele două adrese, adică 1. Varianta a) presupune că p indică începutul tabloului, iar varianta d) tratează p ca pe un singur caracter, dar un pointer la caracter este afișat ca șir.
Al doilea exemplu în formatul examenului. Ce se afișează în urma executării secvenței de mai jos?
char s[] = "banana";
char *p = strchr(s, 'n');
cout << (p - s) << ' ' << (p + 1) << ' ' << strlen(p);
- a)
2 ana 4 - b)
2 nana 4 - c)
3 ana 4 - d)
2 ana 3
Răspunsul corect este a). Primul n este pe poziția 2, deci p - s este 2. Expresia p + 1 indică al treilea a, iar cout afișează șirul ana. Funcția strlen(p) numără caracterele de la p până la terminator, adică nana, deci 4. Varianta b) afișează șirul de la p, nu de la p + 1; varianta c) numără de la 1; varianta d) măsoară șirul de la p + 1.
Greșeli frecvente
- Greșit:
cout << pafișează adresa dinp.Corect: pentruchar *pafișează șirul care începe la acea adresă, până la terminator. - Greșit:
strcatmărește singură destinația.Corect: destinația trebuie declarată suficient de mare, inclusiv pentru terminator. - Greșit:
strchrîntoarce poziția numerică a caracterului.Corect: întoarce un pointer; poziția se obține prinp - s.
Testează-te pe această lecție
Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.
Înainte și după
Surse și referințe
Redactare proprie, conform programei:
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa X intensiv; rocnee.eu
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa XI; plan de încadrare: OMEC 7723/2024, anexa 2, tabelele 1–25, legislatie.just.ro; filiera tehnologică: OMEC 7724/2024, anexa 4, tabelul calificării, legislatie.just.ro
- UNSTPB, Regulament admitere licență 2026, Anexa II-1.2 p. Anx II-14 și Anexa XI-3 p. Anx XI-6–7 (PDF p. 64, 120–121); admitere.pub.ro
- OMECTS 4800/2010, anexa 2, Informatică, p. 3–4; edu.ro
Documente consultate
- Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE, p. 4–5, clasa XI; rocnee.eu
- Programa de bacalaureat la informatică, matematică-informatică (anexa 2 la OMECTS 4800/2010), Ministerul Educației, p. 3–4; edu.ro
- Subiectele și baremele Bacalaureatului 2026; subiecte2026.edu.ro
- UNSTPB, Regulament admitere licență 2026, Anexa II-1.2 p. Anx II-14 și Anexa XI-3 p. Anx XI-6–7 (PDF p. 64, 120–121)
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa X intensiv
Desene: Redactare proprie (desen original), conform Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu
