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., 22: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 a if(!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;
}
Személyes eszközök