Info2/2008tavasz/kuka
A MathWikiből
(Változatok közti eltérés)
127. sor: | 127. sor: | ||
pn értéke: 0xbfa8d2f4 | pn értéke: 0xbfa8d2f4 | ||
*pn értéke: -1079454960 | *pn értéke: -1079454960 | ||
+ | |||
+ | * Konstansok: | ||
+ | int n=5; | ||
+ | const int *pn = &n; | ||
+ | esetén *pn értéke konstans, vagyis ez nem változtatható, de n értéke igen. | ||
+ | int c=5; | ||
+ | int *const pc=&c; | ||
+ | esetén pc nem változtatható, de *pc igen. | ||
+ | |||
+ | ===Tömb és mutató=== | ||
+ | * A tömb neve önmagában, index nélkül mutatóként viselkedik (ld. scanf karakterlánc beolvasásánál). | ||
+ | ~/info2/tombmutato.c | ||
+ | #include <stdio.h> | ||
+ | int main(void) | ||
+ | { | ||
+ | int i=0; | ||
+ | char t[] = "karakterlanc"; | ||
+ | char *p = &t[0]; | ||
+ | printf("a tömb első elemének címe: %p\n", p); | ||
+ | printf("a tömb címe : %p\n", t); | ||
+ | for(; t[i]; i++) | ||
+ | printf("%p címen: %c\n", p+i, *(p+i) ); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | ugyanez egészekkel: | ||
+ | ~/info2/tombmutato1.c | ||
+ | #include <stdio.h> | ||
+ | int main(void) | ||
+ | { | ||
+ | int i=0, t[3]={11,12,13}; | ||
+ | int *p = &t[0]; | ||
+ | printf("a tömb első elemének címe: %p\n", p); | ||
+ | printf("a tömb címe : %p\n", t); | ||
+ | for(; i<3; i++) | ||
+ | printf("%p címen: %d\n", p+i, *(p+i) ); | ||
+ | |||
+ | return 0; | ||
+ | } |
A lap 2008. március 6., 23:59-kori változata
Tartalomjegyzék |
4. előadás (2008-03-07)
Karakterláncok (sztringek)
- karakterlánc = karakterek tömbje, melyet egy 0-kódú karakter zár. Pl.
E z \n e g y \" k a r a k t e r l a n c \" \0 69 122 10 101 ... 32 34 ... 0
- Egy karakterlánc deklarálása történhet inicializásással is:
char str[] = "6 betu";
vele ekvivalens (miért 7?):
char str[7] = "6 betu";
- Karakterlánc scanf-fel való beolvasásánál nincs & a tömb neve előtt (miért? ld. később).
Az alábbi programban összefűzünk két karaketrláncot úgy, hogy az első végéről levesszük a '\0' karaktert, majd odamásoljuk a második karakterláncot, amit '\0'-val zárunk.
~/info2/osszefuz.c
#include <stdio.h> int main(void) { char str1[60]="Ez\negy \"karakterlanc\""; // char str1[60]="Ez egy \"karakterlanc\", de nagyon-nagyon hosszu"; char str2[60]=", ez pedig egy masik, amiben van \\."; unsigned sz1 = 0; unsigned sz2 = 0; while (str1[sz1]) sz1++; // az első karakterlánc hossza while (str2[sz2]) sz2++; // a második karakterlánc hossza if(sizeof str1 < sz1 + sz2 + 1) printf("\nAz osszefuzes nem fog menni.\n"); else { sz2 = 0; while(str2[sz2]) str1[sz1++] = str2[sz2++]; str1[sz1] = '\0'; // 0-val zárjuk a karakterláncot printf("\n%s\n", str1); } return 0; }
Feladat: Olvassuk be valaki nevét és korát vesszővel elválasztva, majd írjuk ki a nevét és a korát, de az utóbbiból tagadjunk le 10 évet! Használjuk az stdlib
atoi
nevű függvényét!
#include <stdio.h> #include <stdlib.h> int main(void) { char nev[60]; char kor[4]; int sz1 = 0, sz2 = 0, k = 0; scanf("%[^,], %[0123456789]", nev, kor); while (nev[sz1]) sz1++; // az első karakterlánc hossza while (kor[sz2]) sz2++; // a második karakterlánc hossza k=atoi(kor)-10; printf("Neved: %s, korod: %d\n", nev, k); return 0; }
Mutató (pointer)
- Mutató deklarálása:
int *pn;
- NULL egy (több headerfájlban is definiált) konstans cím, mely a memóriában nem mutat sehová.
int *pn=NULL;
- A NULL cím egyszerűen tesztelhető, vagyis hogy egy mutatónak adtunk-e már valódi címet: az
if(pn==NULL)
ekvivalens aif(!pn)
kóddal. - & a címet adó unér művelet:
int n; int *pn=&n;
- (*pn)++ nem ugyanaz, mint *pn++ a precedenciaszabályok miatt.
- pn++ a *pn típusának megfelelő bájtértékkel növeli a mutató értékét, tehát pl. char esetén 1-gyel, int esetén 4-gyel.
- a scanf függvény mutatót vár, ezért a következőképp olvashatunk be egész számot:
int n = 0, *pn; pn=&n; scanf("%d",pn);
vagy
scanf("%d",&n);
Az alábbi példában egy n változóra mutat a pn mutató. Vizsgáljuk meg az értékeiket a (*pn)++; és a pn++; utasítások után!
~/info2/mutato.c
#include <stdio.h> int main(void) { int n, *pn = NULL; // pn egy mutató, mely egy egészre mutat n = 5; pn = &n; printf("\nn címe: %p\n", &n); printf("n mérete: %d\n", sizeof n); printf("n értéke: %d\n", n); printf("pn címe: %p\n", &pn); printf("pn mérete: %d\n", sizeof pn); printf("pn értéke: %p\n", pn); printf("*pn értéke: %d\n", *pn); (*pn)++; printf(" (*pn)++;\n"); printf("pn értéke: %p\n", pn); printf("*pn értéke: %d\n", *pn); pn++; printf(" pn++;\n"); printf("pn értéke: %p\n", pn); printf("*pn értéke: %d\n", *pn); return 0; }
Egy futás eredménye:
n címe: 0xbfa8d2f0 n mérete: 4 n értéke: 5 pn címe: 0xbfa8d2ec pn mérete: 4 pn értéke: 0xbfa8d2f0 *pn értéke: 5 (*pn)++; pn értéke: 0xbfa8d2f0 *pn értéke: 6 pn++; pn értéke: 0xbfa8d2f4 *pn értéke: -1079454960
- Konstansok:
int n=5; const int *pn = &n;
esetén *pn értéke konstans, vagyis ez nem változtatható, de n értéke igen.
int c=5; int *const pc=&c;
esetén pc nem változtatható, de *pc igen.
Tömb és mutató
- A tömb neve önmagában, index nélkül mutatóként viselkedik (ld. scanf karakterlánc beolvasásánál).
~/info2/tombmutato.c
#include <stdio.h> int main(void) { int i=0; char t[] = "karakterlanc"; char *p = &t[0]; printf("a tömb első elemének címe: %p\n", p); printf("a tömb címe : %p\n", t); for(; t[i]; i++) printf("%p címen: %c\n", p+i, *(p+i) ); return 0; }
ugyanez egészekkel: ~/info2/tombmutato1.c
#include <stdio.h> int main(void) { int i=0, t[3]={11,12,13}; int *p = &t[0]; printf("a tömb első elemének címe: %p\n", p); printf("a tömb címe : %p\n", t); for(; i<3; i++) printf("%p címen: %d\n", p+i, *(p+i) ); return 0; }