Info2/2008tavasz/kuka

A MathWikiből
(Változatok közti eltérés)
1. sor: 1. sor:
=== A C nyelv ===
+
== 2. előadás (2008-02-22) ==
  
* története
+
===Változók, alap adattípusok, konstansok===
** C programozási nyelv: Dennis Ritchie 1972, Bell Telephone Laboratories
+
** K&R C 1978 (Brian Kernighan, Dennis Ritchie: The C Programming Language)
+
** ANSI (American National Standards Institute) 1989 -> C89
+
** ISO (International Organization for Standardization) ISO/IEC 9899:1990 -> C90 (lényegében azonos)
+
** ISO 9899:1999 (ANSI 2000) -> C99
+
** hatás, utódok: Objective-C, C++, C#
+
* tulajdonságai
+
** általános célú, blokkstruktúrált, imperatív (utasításokból áll, melyek megváltoztatják a program állapotát), procedurális (az előbbi megvalósítása eljáráshívásokkal) nyelv
+
** Unixra készült, ma szinte minden platformon
+
** rendszerprogramok, beágyazott rendszerek, alkalmazási programok
+
** alacsony szintű memóriahozzáférés, hatékonyan fordul gépi kódra
+
** támogatja a gépfüggetlen programozást
+
  
==== Fogalmak ====
 
  
* változók, aritmetikai kifejezések
+
===Utasítások===
* konstans
+
* műveletek
+
* relációk
+
* if, if else, for, while, do while
+
* karakteres adatok be és kivitele
+
  
==== Fordítás ====
+
====Vigyázzunk a pontosvesszőkre====
  
A fordítás lépései
+
if (a > b);
 +
  b = a;
  
  gcc -E hello.c >hello.ee    (csak az előfeldolgozó fut le  -> standard outputra ír)
+
  if (a > b)
gcc -S hello.c              (fordít, de az assembler nem  -> hello.s -- assembly kód)
+
  b = a;
gcc -c hello.c              (fordít, de nem szerkeszt      -> hello.o -- object file)
+
gcc hello.c                (előfeldolgoz+fordít+szerkeszt -> a.out -- futtatható állomány)
+
  
A -o opció nélkül a.out lesz a futtatható állomány neve.
+
do {
 +
  ...
 +
} while (a < b);
  
==== Példák ====
+
while (a < b) {
 +
  ...
 +
}
  
Állománymásoló három változatban:
+
====Műveletek, relációk====
  
~/info2/allomanymasolo1.c
+
;++ --
 +
:csak változó előtt/után
 +
;i---j
 +
:mohó lexikális elemzés miatt = i-- - j
 +
;---i
 +
:értelmetlen (mohó algoritmus miatt = -- -i)
  
#include <stdio.h>
+
;bitműveletek
int main (void)
+
:~ bitenkénti NOT
{
+
:& | ^ AND, OR, XOR
  int c;
+
  c = getchar();
+
  while (c != EOF) {
+
    putchar(c);
+
    c = getchar();
+
  }
+
  return 0;
+
}
+
  
~/info2/allomanymasolo2.c
+
;logikai műveletek
 +
: && || !
  
#include <stdio.h>
+
====Bitszámlálás*====  
int main (void)
+
{
+
  int c;
+
  while ((c = getchar()) != EOF) putchar(c);
+
  return 0;
+
  }
+
  
~/info2/allomanymasolo3.c
+
Számoljuk meg az unsigned i, egészként deklarált szám 2-es
 +
számrendszerbeli alakjában az 1-es biteket.
  
  #include <stdio.h>
+
  unsigned i;
  main ()
+
  int sz;
{
+
...
  int c;
+
for (sz=0; i != 0; i >>= 1) if (i & 01) sz++;
  while ((c = getchar()) != EOF) putchar(c);
+
  ...
  }
+
  
Bájtszámláló
+
Ha i 2-es komplemens alakban van tárolva, akkor i&(i-1) az utolsó 1-es
 +
bitet törli (MIÉRT?). Ezt kihasználva cseréljük ki a fenti sort egy vele
 +
ekvivalens, de gyorsabbra (amely ráadásul int-nek deklarált i-re is
 +
jól fut).
  
~/info2/bajtszamlalo.c:
+
====Precedencia (műveletek végrehajtási sorrendje)====
  
  /* Megszámolja és kiírja, hogy a bemenet hány bájtból áll.
+
  if ( a&04 ) ... ;
  * `n=n+1' helyett `n++'-ot írtunk.
+
  */
+
#include <stdio.h>
+
int main(void) {
+
  int n=0;
+
  while (0<=getchar()) n++;
+
  printf("%d\n", n);
+
  return 0;
+
}
+
  
Kipróbálás:
+
if ( a&04 != 0 ) ... ;
 +
if ( a & (04!=0) ) ... ;
  
  $ echo sok | ./bajtszamlalo
+
  bajt = felso<<4 + also;
  4
+
  bajt = felso << (4 + also);
$ echo -n sok | ./bajtszamlalo
+
3
+
  
Sorszámláló
+
bajt = (felso<<4) + also;
 +
bajt = felso<<4 | also;
  
~/info2/sorszamlalo.c:
+
if ( ( (ev%4 == 0) && (ev%100 != 0) ) || (ev%400 = 0) ) printf("szokoev");
 +
if ( (ev%4 == 0 && ev%100 != 0) || ev%400 = 0 ) printf("szokoev");
 +
if ( ev%4 == 0 && ev%100 != 0 || ev%400 = 0 ) printf("szokoev");
  
/* Megszámolja és kiírja, hogy a bemenet hány sorból áll.
+
====Kiértékelési sorrend====
  * Az utolsó sor nem számít, ha nincs a végén soremelés.
+
 
  */
+
Egy <= irány
  #include <stdio.h>
+
 
  int main(void) {
+
  a = b = c = 0;
  int c, n=0;
+
 
  while (0<=(c=getchar())) {
+
Egy => irány
     if (c=='\n') n++;
+
 
 +
  if ( n!=0 && osszeg/n < atlag ) ... ;
 +
if ( n==0 || osszeg/n < epszilon ) ... ;
 +
 
 +
====Lógó else====
 +
 
 +
Helyes:
 +
 
 +
if ( a == 0 )
 +
  if ( b == 0 )
 +
    return 0;
 +
  else {
 +
     c = f(a,b);
 +
    return c;
 
   }
 
   }
  printf("%d\n", n);
 
  return 0;
 
 
  }
 
  }
  
Kipróbálás:
+
Helytelen:
  
  $ ls /bin/bash /usr/bin/id /dev/null /etc/inputrc | ./sorszamlalo
+
if ( a == 0 )
  4
+
  if ( b == 0 )
 +
    return 0;
 +
else {
 +
  c = f(a,b);
 +
  return c;
 +
}
  
~/info2/szoszamlalo.c (ld. K&R alapján)
+
Az else mindig a legközelebbi else-nélküli if-hez tartozik!
  
/* Megszámolja és kiírja, hogy a bemenet hány bájtból,
+
Javítás: (a kapcsos zárójelek használata segít)
  * hány szóból és hány sorból áll. Szó a bemenet olyan
+
 
  * maximális része, melyben nincs szóköz, tabulátor és
+
  if ( a == 0 ) {
  * újsor karakter.
+
  if ( b == 0 )
  */
+
     return 0;
  #include <stdio.h>
+
} else {
#define KINN 0
+
  c = f(a,b);
#define BENN 1
+
   return c;
int main(void) {
+
  int c, bajtok_sz, szavak_sz, sorok_sz, allapot=KINN;
+
  bajtok_sz=szavak_sz=sorok_sz=0;
+
  while ((c=getchar()) != EOF) {
+
    ++bajtok_sz;
+
    if (c == '\n') sorok_sz++;
+
     if (c == ' ' || c == '\n' || c == '\t')
+
      allapot = KINN;
+
    else if (allapot == KINN) {
+
      allapot = BENN;
+
      szavak_sz++;
+
    }
+
  }
+
  printf("%d %d %d\n", bajtok_sz, szavak_sz, sorok_sz);
+
   return 0;
+
 
  }
 
  }
 +
 +
 +
===Tömbök===
 +
 +
====Asszimetrikus korlátok====
 +
 +
Írjunk Mapleben 1-től, majd k-tól 7-elemű ciklust:
 +
 +
for i from 1 to 7 do ... end do;
 +
for i from k to k+7-1 do ... end do;
 +
 +
A tömbök indexelése 1-től! Szimmetrikus intervallum!
 +
 +
- + - - - - - - + - - -
 +
  0 1 2 3 4 5 6 7 8 9
 +
    ^          ^
 +
- + - - - - - - + - - -
 +
  1 2 3 4 5 6 7 8 9
 +
    ^          ^
 +
 +
Írjunk C-ben 0-tól, majd k-tól 7-elemű ciklust:
 +
 +
for ( i=0; i<7; i++) ... ;
 +
for ( i=k; i<k+7; i++) ... ;
 +
 +
A tömbök indexelése 0-tól! Aszimmetrikus intervallum!
 +
 +
- + - - - - - - + - -
 +
    0 1 2 3 4 5 6 7 8
 +
    ^            ^
 +
- + - - - - - - + - -
 +
  1 2 3 4 5 6 7 8 9
 +
    ^            ^

A lap 2008. február 21., 21:08-kori változata

Tartalomjegyzék

2. előadás (2008-02-22)

Változók, alap adattípusok, konstansok

Utasítások

Vigyázzunk a pontosvesszőkre

if (a > b);
  b = a;
if (a > b)
  b = a;
do {
  ...
} while (a < b);
while (a < b) {
  ...
}

Műveletek, relációk

++ --
csak változó előtt/után
i---j
mohó lexikális elemzés miatt = i-- - j
---i
értelmetlen (mohó algoritmus miatt = -- -i)
bitműveletek
~ bitenkénti NOT
& | ^ AND, OR, XOR
logikai műveletek
&& || !

Bitszámlálás*

Számoljuk meg az unsigned i, egészként deklarált szám 2-es számrendszerbeli alakjában az 1-es biteket.

unsigned i;
int sz;
...
for (sz=0; i != 0; i >>= 1) if (i & 01) sz++;
...

Ha i 2-es komplemens alakban van tárolva, akkor i&(i-1) az utolsó 1-es bitet törli (MIÉRT?). Ezt kihasználva cseréljük ki a fenti sort egy vele ekvivalens, de gyorsabbra (amely ráadásul int-nek deklarált i-re is jól fut).

Precedencia (műveletek végrehajtási sorrendje)

if ( a&04 ) ... ;
if ( a&04 != 0 ) ... ;
if ( a & (04!=0) ) ... ;
bajt = felso<<4 + also;
bajt = felso << (4 + also);
bajt = (felso<<4) + also;
bajt = felso<<4 | also;
if ( ( (ev%4 == 0) && (ev%100 != 0) ) || (ev%400 = 0) ) printf("szokoev");
if ( (ev%4 == 0 && ev%100 != 0) || ev%400 = 0 ) printf("szokoev");
if ( ev%4 == 0 && ev%100 != 0 || ev%400 = 0 ) printf("szokoev");

Kiértékelési sorrend

Egy <= irány

a = b = c = 0;

Egy => irány

if ( n!=0 && osszeg/n < atlag ) ... ;
if ( n==0 || osszeg/n < epszilon ) ... ;

Lógó else

Helyes:

if ( a == 0 )
  if ( b == 0 )
    return 0;
  else {
    c = f(a,b);
    return c;
  }
}

Helytelen:

if ( a == 0 )
  if ( b == 0 )
    return 0;
else {
  c = f(a,b);
  return c;
}

Az else mindig a legközelebbi else-nélküli if-hez tartozik!

Javítás: (a kapcsos zárójelek használata segít)

if ( a == 0 ) {
  if ( b == 0 )
    return 0;
} else {
  c = f(a,b);
  return c;
}


Tömbök

Asszimetrikus korlátok

Írjunk Mapleben 1-től, majd k-tól 7-elemű ciklust:

for i from 1 to 7 do ... end do;
for i from k to k+7-1 do ... end do;

A tömbök indexelése 1-től! Szimmetrikus intervallum!

- + - - - - - - + - - -
 0 1 2 3 4 5 6 7 8 9
   ^           ^
- + - - - - - - + - - -
 1 2 3 4 5 6 7 8 9
   ^           ^

Írjunk C-ben 0-tól, majd k-tól 7-elemű ciklust:

for ( i=0; i<7; i++) ... ;
for ( i=k; i<k+7; i++) ... ;

A tömbök indexelése 0-tól! Aszimmetrikus intervallum!

- + - - - - - - + - - 
   0 1 2 3 4 5 6 7 8
   ^             ^
- + - - - - - - + - - 
 1 2 3 4 5 6 7 8 9
   ^             ^
Személyes eszközök