- 1 1. Sissejuhatus
- 2 2. Mis on char massiiv?
- 3 3. char massiivi deklareerimine ja initsialiseerimine
- 4 4. Teksti operatsioonid
- 5 5. char massiivi ja pointeri erinevus
- 6 6. Kuidas edastada char massiivi funktsioonile
- 7 7. Praktiline näide: stringi pööratud kuvamine
- 8 8. Levinud vead ja nende lahendused
- 9 9. Kokkuvõte
1. Sissejuhatus
C keel on endiselt laialdaselt kasutatav keel süsteemi- ja sisseehitatud arenduse valdkonnas. Nende seas on “char massiiv” üks kõige põhilisi ja olulisi süntaksielemente stringide käsitlemiseks.
C keeles ei ole standardset stringitüüpi. Selle asemel kasutatakse tähemärkide massiivi (char massiiv) stringide esitamiseks. See ei ole algajatele väga intuitiivne, mistõttu võib char massiivi mõistmine olla C keele õppimisel suur takistus.
Lisaks, kui ei mõista täpselt char massiivi ja char pointeri (char*
) kasutamise erinevusi ning nullmärgi (\0
) olemasolu, võib see põhjustada ootamatuid vigu.
Selles artiklis keskendutakse teemale “C keel char massiiv“, selgitades selgelt aluseid, rakenduslikke tehnikaid ja levinud vigade vältimise meetodeid.
Kui plaanite C keelt põhjalikult õppida või soovite char massiivi üle vaadata, lugege julgelt lõpuni. Järgmises peatükis selgitatakse kõigepealt char massiivi määratlust ja selle põhimõistet.
2. Mis on char massiiv?
C keeles tähendab “char massiiv” märki (char tüüp) massiivi, mis hoiab mitut üksust. See on põhiline struktuur stringide käsitlemisel.
char tüüp?
C keeles on char
tüüp andmetüüp, mis esindab ühte märki. Näiteks saab defineerida ühe märgi muutujat järgmiselt.
char c = 'A';
Nagu näidatud, 'A'
sarnane üksik märk, mis on ühejuttega ümbritsetud, defineeritakse char
tüübina.
char massiivi põhiline süntaks
Mitme tähe salvestamiseks kasutatakse char
tüüpi massiivi. See defineeritakse järgmiselt:
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
See massiiv eraldab 5-tähelist stringi "Hello"
koos nullmärgiga ( \0
) ning reserveerib 6 tähe pikkuse mälu.
Nullmärgi ( 'Massiivi suurus ja tähelepanekud
'
) tähtsus
Massiivi suurus ja tähelepanekud
'C keeles kasutatakse stringi lõpu näitamiseks nullmärki '\0'
. Kui seda sümbolit ei ole, ei tööta stringi manipuleerimise funktsioonid õigesti ja võib esineda ootamatuid käitumisi.
char str[] = "Hello"; // automaatselt lõppu '\0' lisatakse
Nagu eespool näidatud, kui kasutatakse kahekordsete jutumärkidega ümbritsetud stringilitteraali, lisab kompilaator automaatselt '\0'
lõppu.
3. char massiivi deklareerimine ja initsialiseerimine
char massiivi kasutamisel on põhiline tagada vajalik tähemärkide arv + 1 (nullmärgi jaoks) suurus. Kui massiivi suurus on liiga väike ja sinna määratakse string, võib see põhjustada puhvri ületäitumist ja programm võib ootamatult lõpetada.
Staatiline deklareerimine ja initsialiseerimine
char massiivi kasutamiseks on kõigepealt vaja sobivat deklareerimist ja initsialiseerimist . Siin selgitame C-keeles char massiivi põhilist deklareerimisviisi, initsialiseerimist ning ka dünaamilise mälu kasutamist.
Stringi literaliga initsialiseerimine
Kõige põhilisema meetodina on massiivi suurus selgelt määrata, deklareerida see ja initsialiseerida üksikuid tähemärke.
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
Nii tehes saab str
käsitleda stringina "Hello"
. Oluline on, et lõpus peab alati olema '\0'
.
Määratud suurusega literalide omistamine
C-keeles on võimalik kasutada lihtsat initsialiseerimist stringi literaliga, nagu allpool näidatud.
char str[] = "Hello";
Selles olukorras määratakse massiivi suuruseks automaatselt "Hello"
+ '\0'
, mis on 6 tähemärki. Kui soovite stringi sisu muuta, tuleb deklareerida see char massiivina, mis võimaldab turvalist muutmist.
Dünaamilise mälu eraldamine (malloc) kasutamine
Massiivi suurust määrates on võimalik initsialiseerida stringi literaliga, kuid suuruse puudumisele tuleb tähelepanu pöörata.
char str[5] = "Hello"; // ❌ Vea põhjus (suurus ebapiisav)
Nagu eespool näidatud, vajab "Hello"
5 tähemärki + 1 tähemärk (‘\0’), kokku 6 tähemärki. Seega peab olema vähemalt char str[6]
.
4. Teksti operatsioonid
Kui soovite stringidega paindlikumalt töötada, on olemas meetod, kus malloc
abil eraldatakse dünaamiliselt char massiiv.
#include
#include
char* str = malloc(6 * sizeof(char));
strcpy(str, "Hello");
Selles meetodis eraldatakse mälu dünaamiliselt ja stringi käsitletakse selle pointeri kaudu. Pärast kasutamist tuleb free(str);
abil mälu vabastada, seda ei tohi unustada.
Teksti kopeerimine: strcpy
C keeles on tavapärane kasutada standardraamatukogu funktsioone char massiivi
kasutades tekstide käsitlemisel. Siin selgitame põhilisi tekstide käsitlemise funktsioone ja nende kasutamist konkreetsete näidetega.
Teksti liitmine: strcat
strcpy
on funktsioon, mis kopeerib ühe teksti teise char massiivi.
#include
char src[] = "Hello";
char dest[10];
strcpy(dest, src);
Märkus: dest
ei ole piisava suurusega, võib see põhjustada puhvri ületäitumist. Tagake, et suurus oleks kopeeritava teksti pikkus + 1 (nullmärk).
Teksti pikkuse hankimine: strlen
strcat
liidab kaks teksti. Teise argumendi sisu lisatakse esimese argumendi lõppu.
#include
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);
Selle tulemusena muutub str1
väärtuseks "Hello World"
. Samuti eeldatakse, et esimese argumendi massiivis on piisavalt ruumi kogu liidetud teksti jaoks.
Teksti võrdlemine: strcmp
strlen
funktsioon tagastab teksti pikkuse (nullmärki arvestamata).
#include
char str[] = "Hello";
int len = strlen(str); // len = 5
Nullmärk ei loe, seega peavad C keelega mittekogenud kasutajad olema ettevaatlikud.
Teksti otsimine: strchr
ja strstr
Kahe teksti võrdlemiseks kasutage strcmp
.
#include
char str1[] = "Hello";
char str2[] = "World";
if (strcmp(str1, str2) == 0) {
// võrdsed
} else {
// erinevad
}
See funktsioon tagastab 0, kui tekstid on võrdsed, ja erinevuse korral tagastab tähemärkide koodide vahe.
5. char massiivi ja pointeri erinevus
Määratud tähe või alamsõne otsimiseks saab kasutada järgmisi funktsioone.
#include
char str[] = "Hello World";
// tähemärgi otsimine
char *ptr1 = strchr(str, 'o'); // viit esimesele 'o'-le
// alamsõne otsimine
char *ptr2 = strstr(str, "World"); // viit "World" alguspunkti
Kui ei leita, tagastab mõlemad funktsioonid NULL
.
Deklaratsiooni erinevus
C-keeles stringide käsitsemisel, char massiiv
ja char pointer (char*)
on sarnased, kuid neil on tegelikult erinevad omadused. Selle erinevuse õige mõistmine aitab vältida mälu valesti kasutamist ja ootamatuid vigu.
Muudetavuse erinevus
Alustuseks vaatame deklaratsiooniviisi erinevusi.
char str1[] = "Hello"; // char massiiv
char *str2 = "Hello"; // char pointer
str1
on tõelise sisuga massiiv, mis võtab mälu 6 baiti (“Hello” + ‘\\0’). Teisest küljest, str2
on pointer mälupiirkonnale, kus on salvestatud string literal.
Mälu struktuuri erinevus
char massiiv str1
võimaldab muuta massiivi sisalduvaid tähti vabalt.
str1[0] = 'h'; // OK
Kuid kui nagu char* str2 = "Hello";
viitab string literalile, siis selle sisu muutmine on määratlemata käitumine.
str2[0] = 'h'; // ❌ Määratlemata käitumine (võib põhjustada jooksva aja vea)
Suuruse hankimise erinevus
char massiiv
pinnalchar'i osoitaja
konstantsed piirkonnad (kirjutuskaitstud)heap’i piirkond (malloc jne)mälukasutuse puhul tuleb olla ettevaatlik
Kokkuvõte: kasutamise punktid
Massiivi puhul, sizeof(str1)
tagastab massiivi kogu baitide arvu.
char str1[] = "Hello";
printf("%lu", sizeof(str1)); // → 6 ('\\0' sisaldab)
Teisest küljest, pointeri puhul sizeof(str2)
tagastab pointeri enda suuruse (tavaliselt 4–8 baiti), seega ei sobi see massiivi suuruse hankimiseks.
char *str2 = "Hello";
printf("%lu", sizeof(str2)); // → 8 (64-bit keskkond)
6. Kuidas edastada char massiivi funktsioonile
Üksus | char-massiivi | char’i osoitaja |
---|---|---|
Sisu muutmine | võimalik | Principiililiselt keelatud (literaliseerimisel) |
Suuruse saamine | sizeof() | strlen() |
Kirjutamise kasutus | sobiv | Ei sobi (kirjutuskaitstud) |
Paindlikkus | kindel suurus | Paindlik, kuid tuleb olla ettevaatlik |
Põhijuhis: char massiivi edastamine argumendina
C gengo puhul, massiivid funktsioonile edastamisel toimub mitte väärtuse edastamine, vaid pointeri edastamine. See kehtib char massiivi
puhul samuti, ning funktsioonile edastamisel antakse massiivi algus aadress (pointer).
Selle mehhanismi mõistmine on funktsioonide vahel stringide manipuleerimisel või sisu muutmisel väga oluline.
Funktsioon, mis muudab sisu
#include
void printString(char str[]) {
printf("String: %s\n", str);
}
int main() {
char greeting[] = "Hello";
printString(greeting);
return 0;
}
Selles näites antakse funktsioonile printString
argument, mis on tüüpi char[]
, kuid tegelikult võetakse see vastu kui char*. See tähendab, et char str[]
on char *str
sama tähendus.
Massiivi suuruse haldamine
Ka funktsiooni sees massiivi sisu muutamisel saab antud aadressi kaudu otse andmeid manipuleerida.
void toUpperCase(char str[]) {
for (int i = 0; str[i] != ' '; i++) {
if ('a' <= str[i] && str[i] <= 'z') {
str[i] = str[i] - ('a' - 'A');
}
}
}
int main() {
char text[] = "hello world";
toUpperCase(text);
printf("%s\n", text); // Väljund: HELLO WORLD
return 0;
}
Nii et isegi kui soovite massiivi sisu muuta, käsitletakse seda pointerina, funktsiooni sees tehtud muudatused kajastuvad kutsujas.
Lugemiseks ainult argument const kasutades
C gengo puhul ei edastata massiivi suuruse infot funktsioonile. Seetõttu on parim praktika edastada suurus samuti argumendina, et tagada turvaline kasutamine.
void printChars(char str[], int size) {
for (int i = 0; i < size; i++) {
printf("%c ", str[i]);
}
printf("\n");
}
Samuti on tavaline kasutada strlen
funktsiooni stringi pikkuse dünaamiliseks saamiseks. Kuid tuleb olla ettevaatlik, et seda ei kasutata massiivide puhul, mis ei lõpe nullterminatsiooniga.
7. Praktiline näide: stringi pööratud kuvamine
Kui stringi funktsiooni sees ei muuda, on soovitatav kasutada const char*
et selgelt näidata, et see on ainult lugemiseks.
void printConstString(const char *str) {
printf("%s\n", str);
}
See aitab vältida soovimatuid muudatusi ja selgitab funktsiooni spetsifikatsiooni.
Eesmärk
Siin kasutame seni õpitud char massiivi
teadmisi, et luua tegelikult stringi pööratud kuvamise programm.
Näidis kood
Kasutaja sisestatud stringi väljastatakse üks täht korraga lõpusõna suunas algusse. See on väga kasulik massiivi operatsioonide, stringi pikkuse hankimise ja tsükli töötlemise harjutamiseks.
Selgitus
#include
#include
void printReversed(char str[]) {
int len = strlen(str);
for (int i = len - 1; i >= 0; i--) {
putchar(str[i]);
}
putchar('\n');
}
int main() {
char text[100];
printf("Palun sisestage string: ");
fgets(text, sizeof(text), stdin);
// Eemalda reavahetustäht (vastumeede fgets kasutamisel)
size_t len = strlen(text);
if (len > 0 && text[len - 1] == '\n') {
text[len - 1] = '\0';
}
printf("Pööratud kuvamisel: ");
printReversed(text);
return 0;
}
Käivitamise näide
fgets
- Lisage kindlasti ka protsess, mis eemaldab sisendi lõpus lisatud (reavahetus).
strlen()
Rakendamise näpunäited
Palun sisestage string: OpenAI
Pööratud kuvamisel: IAnepO
8. Levinud vead ja nende lahendused
See protsess viib rakendusteni, nagu stringi palindroomi tuvastamine ja virna struktuuri mõistmine jne, mis on kasulik algoritmide õppimisel. Samuti on võimalik kasutada pointeriarvutusi ümberkirjutamiseks, muutes selle sobivaks keerukamate harjutuste jaoks.
1. Nullterminaatori(2. Puhvri suuruse puudumine
)unustamine
2. Puhvri suuruse puudumine
C keeles char massiiv
käsitsemisel, algajatest kuni edasijõudnuteni on mitmeid lõkse, millesse võivad sattuda. Siin selgitame sagedasti esinevaid vigu ja nende ennetamise ning lahendamise meetodeid konkreetsemalt.
3. Stringilitteraali muutmine
Üks kõige tavalisemaid vigu on unustada lisada nullmärk (\0
) stringi lõppu.
char str[5] = {'H', 'e', 'l', 'l', 'o'}; // ❌ lõpus '\0' puudub
printf("%s\n", str); // määratlemata käitumine
Lahendus:
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // ✅ õige
Või kasutades stringilitteraali, lisatakse nullmärk automaatselt.
4. fgets’i reavahetuse tähe töötlemise unustamine
strcpy
ja strcat
funktsioonide kasutamisel, kui sihtmassivi suurus ei ole piisav, põhjustab see mälu rikkumise (puhvri ülevoolu).
char str1[5];
strcpy(str1, "Hello"); // ❌ kopeerib 6 tähemärki massiivi suurusega 5
Lahendus:
- Kopeerimispaikale tuleb tagada (näiteks: “tähtede arv + 1”)
- Kaalu turvalisemat kasutamist
char str1[6];
strncpy(str1, "Hello", sizeof(str1) - 1);
str1[5] = '\0'; // lisab lõppu nullmärgi kindluse huvides
5. Näitaja ja massiivi segadus
char *str = "Hello";
nagu deklareeritud näitaja on, võib viidata kirjutamiskindlale alale. Kui sellesse kirjutada, tekib jooksuaegne viga.
char *str = "Hello";
str[0] = 'h'; // ❌ jooksuaegne Segmentation fault
Lahendus:
char str[] = "Hello"; // ✅ deklareeritud muudetavana massiivina
str[0] = 'h';
9. Kokkuvõte
fgets
kasutamisel, tuleb tähele panna, et lõpus võib jääda reavahetuse märk (\n
).
fgets(str, sizeof(str), stdin);
// str sisaldab näiteks "Hello\n\0"
Lahendus:
size_t len = strlen(str);
if (len > 0 && str[len - 1] == '\n') {
str[len - 1] = '\0';
}
Mida selles artiklis õppisime
Kuna need näevad sarnased, char*
ja char[]
segi ajamine võib viia määratlemata käitumiseni. suuruse ( sizeof
) erinevus ja muutmisvõimaluste erinevus tuleb meeles pidada.
Nõuanded edasiseks õppeks
Selles artiklis oleme käsitlenud “C keele char massiivi” põhialatest kuni rakendusteni järk-järgult. Lõpuks vaatame artikli sisu üle ja tutvustame edasise õppe suuniseid.
Mida selles artiklis õppisime
- char-taustade roll ja deklaratsioonimeetod C-keeles ei ole stringitüüpi olemas, seetõttu stringide käsitlemiseks kasutatakse char-tüüpi massiivi.
- String literalide ja null-merkide (
\0
) tähtsus Stringi esitamiseks on lõpus null-merk hädavajalik. - Standard library functionide kasutamine stringide manipuleerimiseks , , , Kui kasutada neid, saab tõhusalt stringe töödelda.
- char-taheliste massiivi ja char-pointri erinevus Massiivid ja pointrid on sarnased, kuid mitte samad ning neil on selged erinevused mälu struktuuri ja muutmise võimaluse osas.
- Kuidas funktsioonidele massiivi edastada ja ohutuse tagamine Massiivid edastatakse tegelikult punktiirina, seetõttu tuleb olla ettevaatlik muudatuste ja suuruse haldamisega.
- Arusaamise kinnistumine praktiliste näidiste ja tavapäraste vigade kaudu Õppisin praktilise koodi rakendamise ja vigade käsitlemise kaudu realistlikumat kasutamist.
Nõuanded edasiseks õppeks
Char massiivi kasutamise mõistmine on esimene samm C keeles mäluoperatsioonide aluste mõistmiseks. Siin õpitud teadmisi saab rakendada järgmistes sammudes, nagu allpool näidatud.
- Näituri aritmeetika
- Dünaamiline mälu haldamine
malloc
free
- struktuuriga kombinatsioon
Lisaks saab teiste kirjutatud koodi lugemise kaudu omandada vaatenurki ja kirjutamisstiile, mis sul endal puuduvad. Tegelike projektide ja OSS (avatud lähtekoodiga tarkvara) lugemise harjumus on samuti väga kasulik.
C keel on väga paindlik, kuid kui seda valesti kasutada, võib see olla ohtlik. Kui aluseid hoolikalt üles ehitad, saab see olema väga võimas tööriist. Char massiivi mõistmine on see esimene samm. Palun kasuta seda artiklit juhendina ja tõsta oma oskusi kindlalt edasi.