Informatika2-2012/Eloadas07

A MathWikiből
(Változatok közti eltérés)
(Új oldal, tartalma: „== Egyéb hasznosságok C programozáshoz == === Konstansok === === A program paraméterezése === A main() paraméterezése: <c> #include <stdio.h> #include <stdl…”)
 
1. sor: 1. sor:
 
== Egyéb hasznosságok C programozáshoz ==
 
== Egyéb hasznosságok C programozáshoz ==
  
=== Konstansok ===
+
=== Konstansok és makrók ===
  
=== A program paraméterezése ===
+
A konstansok olyan "változók" amiknek az értékét nem lehet megváltoztani. Például hasznos lehet ilyen, ha a programban a pi értékét sok helyen szeretnénk használni (ehhez elég lenne egy globális változó..), és még véletlenül sem szeretnénk felülírni az értékét a program futása során, hogy minden számítás ugyanazzal a pontossággal számolódjon. Többféle megoldást is használhatunk erre.
  
A main() paraméterezése:
+
==== Előfordítóval ====
  
 +
Konstansokat az eredeti C-ben csak az előfordító segítségével hozhattunk létre.
 +
Minden olyan kódsor ami '#' jellej kezdődik, a preprocesszornak vagyis az előfeldolgozónak szóló utasítás. (Kicsit lejjebb lesznek még példák.)
 +
 +
A "#define" preprocesszor-utasítással definiálhatunk konstansokat.
 +
Csak abban a file-ban érvényes egy konstans ahol deklaráltuk.
 +
 +
<c>
 +
/* Konstansdeklaráció: eredeti C-s megoldás, előfordítónak szóló utasítással */
 +
#define PI 3.14159
 +
#define NULLA 0
 +
#define SZOVEG "Ha ezt a sort el tudja olvasni, nincs szüksége szemüvegre \n"
 +
</c>
 +
Itt nem kell pontosvessző a sorok végére.
 +
Az előfordító a program lefordítása előtt a konstansok minden előfordulási helyére behelyettesíti a megfelelő értéket (betűről betűre, kiértékelés nélkül, lecseréli pl. a "PI"-t "3.14"-re).
 +
 +
A konstansneveket mindig nagybetűvel kell írni!
 +
 +
C-ben egy konstansot megsemmisíteni is lehet az "#undef konstansnév" paranccsal, illetve ellenőrizhetjük az "#ifdef" ill. "#ifndef" preprocesszor-parancsokkal, hogy van-e (ill. nincs-e) már definiálva adott névvel konstans (ne felejtsük el lezárni az if-et):
 +
 +
<c>
 +
#ifndef PI
 +
#define PI 3.14
 +
#endif
 +
</c>
 +
 +
===== Makro-függvények =====
 +
 +
Akár kicsi ''makrofüggvények'' írásásra is használhatjuk ezt a behelyeetesítő mechanizmust.
 +
De vigyáznunk kell arra hogy az előfordító, mint nyelven kívüli eszköz mindent gondolkodás nélkül helyettesít, ráadásul az eredményt egy sorba írva azt sem teszi lehetővé, hogy a makrohelyettesítést lépésenként nyomkövessük.
 +
 +
Egy elrettentő példa:
 +
 +
<c>
 +
// a háromoperandusú feltételes operátort használjuk, mert rövid
 +
#define abs(val) (val < 0) ? -val : val     
 +
 +
int y, x = 3;
 +
y = abs( x++ );    // Várt eredmény: x = 4, y = 3;
 +
</c>     
 +
 +
Az abszolút érték makro fenti alkalmazása esetén az előfordító a hívás helyén (ahol y-nak adunk értéket) behelyettesíti az ''abs()'' makrot, a belsejébe pedig paraméterként behelyettesíti a "val" helyére az "x++"-t. Első ránézésre azt várnánk, hogy az ''y = abs(x++)'' végrehajtása után, mivel előtte x értéke 3 volt, x értéke 4 lesz, míg y értéke 3. Ez így is lenne, ha az abs-ot függvényként realizálnánk. Ezzel szemben a előfordító ebből a sorból a következőt készíti:
 +
 +
<c>
 +
y = (x++ < 0) ? - x++ : x++;
 +
</c>
 +
 +
azaz az x-et kétszer növeli, minek következtében az utasítás végrehajtása után x értéke 5, míg y-é 4 lesz. A előfordítóval definiált makrok tehát veszélyesek lehetnek.
 +
 +
 +
==== A const típusmódosítóval ====
 +
 +
Az ANSI (szabványos) C-ben (és majd C++-ban) a ''const'' típusmódosító szó segítségével bármely memóriaobjektumot definiálhatunk konstansként, vagyis "csak olvasható változó"-ként. Ez azt jelenti, hogy a fordító figyelmeztet, ha a változó nevét értékadás bal oldalán szerepeltetjük, vagy ebből nem konstansra mutató pointert inicializálunk.
 +
 +
<c>
 +
/* ANSI C megoldás PI definiálására */
 +
const float PI = 3.14;
 +
</c>
 +
 +
Mutatók esetén lehetőség van annak megkülönböztetésére, hogy a mutató által megcímzett objektumot, vagy magát a mutatót szeretnénk csak olvashatóvá tenni:
 +
 +
<c>
 +
const char * p;  // p által címzett karakter nem módosítható, (const char) * p
 +
char * const q;  // q mutatót nem lehet megváltoztatni, (char *) const q
 +
</c>
 +
 +
=== Fájl olvasás és írás ===
 +
File-kezelés
 +
 +
http://www.math.utah.edu/~carlson/c/cbook.pdf
 +
 +
Writing Data to a File
 +
Our first example is a C program which creates a file of random integers.
 +
The number of integers generated is under the control of the user, and the user
 +
can select the name of the file in which these integers are stored.
 +
 +
<c>
 +
/* randfile.c: creates a file of N random numbers */
 +
#include <stdlib.h>
 +
#include <stdio.h>
 +
main() {
 +
    int i, N;
 +
    FILE *fp;
 +
    char *fname;
 +
    printf("Number of random integers to generate: ");
 +
    scanf("%d", &N);
 +
    printf("File name: ");
 +
    scanf("%s", fname);
 +
    fp = fopen(fname, "w");
 +
    for (i = 0; i < N; i++)
 +
        fprintf(fp, "%5d\n", rand());
 +
    fclose(fp);
 +
}
 +
</c>
 +
 +
=== A program paraméterezése ===
 +
main() paraméterezése
 +
http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html
  
 
<c>
 
<c>
18. sor: 115. sor:
 
}
 
}
 
</c>
 
</c>
 +
 +
Example 10.1
  
 
http://www.cprogramming.com/tutorial/c/lesson14.html
 
http://www.cprogramming.com/tutorial/c/lesson14.html
<c>
 
 
#include <stdio.h>
 
#include <stdio.h>
  
 +
<c>
 
int main ( int argc, char *argv[] ) {
 
int main ( int argc, char *argv[] ) {
 
     /* argc should be 2 for correct execution */
 
     /* argc should be 2 for correct execution */
51. sor: 150. sor:
 
}
 
}
 
</c>
 
</c>
 +
 +
=== Több fájlból álló program ===
 +
 +
röviden a linkelésről.
 +
 +
 +
Gyakorlaton include-oljunk egy másik fáljt, ha lesz rá idő.
  
  
112. sor: 218. sor:
 
Amit a zh-ra tudni kell:  
 
Amit a zh-ra tudni kell:  
 
* makrók definiálása
 
* makrók definiálása
* stringek kezelése (előző előadás végén is volt)
+
* stringek kezelése (előző? előadás végén is volt)
 
* main paraméterezése hogy néz ki
 
* main paraméterezése hogy néz ki
 
* file olvasás, írás
 
* file olvasás, írás
  
 
=== Források és további olvasnivalók: ===
 
=== Források és további olvasnivalók: ===
 +
* http://www.tankonyvtar.hu/informatika/objektum-orientalt-080905-103
 
* http://www.math.utah.edu/~carlson/c/cbook.pdf
 
* http://www.math.utah.edu/~carlson/c/cbook.pdf
 
* The C library reference guide: http://www.acm.uiuc.edu/webmonkeys/book/c_guide/index.html
 
* The C library reference guide: http://www.acm.uiuc.edu/webmonkeys/book/c_guide/index.html
 
* http://www.cprogramming.com/tutorial/c/lesson14.html
 
* http://www.cprogramming.com/tutorial/c/lesson14.html
 
* http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html
 
* http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html
 +
* http://en.wikipedia.org/wiki/Include_guard

A lap 2012. március 20., 12:31-kori változata

Tartalomjegyzék

Egyéb hasznosságok C programozáshoz

Konstansok és makrók

A konstansok olyan "változók" amiknek az értékét nem lehet megváltoztani. Például hasznos lehet ilyen, ha a programban a pi értékét sok helyen szeretnénk használni (ehhez elég lenne egy globális változó..), és még véletlenül sem szeretnénk felülírni az értékét a program futása során, hogy minden számítás ugyanazzal a pontossággal számolódjon. Többféle megoldást is használhatunk erre.

Előfordítóval

Konstansokat az eredeti C-ben csak az előfordító segítségével hozhattunk létre. Minden olyan kódsor ami '#' jellej kezdődik, a preprocesszornak vagyis az előfeldolgozónak szóló utasítás. (Kicsit lejjebb lesznek még példák.)

A "#define" preprocesszor-utasítással definiálhatunk konstansokat. Csak abban a file-ban érvényes egy konstans ahol deklaráltuk.

/* Konstansdeklaráció: eredeti C-s megoldás, előfordítónak szóló utasítással */
#define PI 3.14159
#define NULLA 0
#define SZOVEG "Ha ezt a sort el tudja olvasni, nincs szüksége szemüvegre \n"

Itt nem kell pontosvessző a sorok végére. Az előfordító a program lefordítása előtt a konstansok minden előfordulási helyére behelyettesíti a megfelelő értéket (betűről betűre, kiértékelés nélkül, lecseréli pl. a "PI"-t "3.14"-re).

A konstansneveket mindig nagybetűvel kell írni!

C-ben egy konstansot megsemmisíteni is lehet az "#undef konstansnév" paranccsal, illetve ellenőrizhetjük az "#ifdef" ill. "#ifndef" preprocesszor-parancsokkal, hogy van-e (ill. nincs-e) már definiálva adott névvel konstans (ne felejtsük el lezárni az if-et):

#ifndef PI
#define PI 3.14
#endif
Makro-függvények

Akár kicsi makrofüggvények írásásra is használhatjuk ezt a behelyeetesítő mechanizmust. De vigyáznunk kell arra hogy az előfordító, mint nyelven kívüli eszköz mindent gondolkodás nélkül helyettesít, ráadásul az eredményt egy sorba írva azt sem teszi lehetővé, hogy a makrohelyettesítést lépésenként nyomkövessük.

Egy elrettentő példa:

// a háromoperandusú feltételes operátort használjuk, mert rövid
#define abs(val) (val < 0) ? -val : val      
 
int y, x = 3;
y = abs( x++ );     // Várt eredmény: x = 4, y = 3;

Az abszolút érték makro fenti alkalmazása esetén az előfordító a hívás helyén (ahol y-nak adunk értéket) behelyettesíti az abs() makrot, a belsejébe pedig paraméterként behelyettesíti a "val" helyére az "x++"-t. Első ránézésre azt várnánk, hogy az y = abs(x++) végrehajtása után, mivel előtte x értéke 3 volt, x értéke 4 lesz, míg y értéke 3. Ez így is lenne, ha az abs-ot függvényként realizálnánk. Ezzel szemben a előfordító ebből a sorból a következőt készíti:

y = (x++ < 0) ? - x++ : x++;

azaz az x-et kétszer növeli, minek következtében az utasítás végrehajtása után x értéke 5, míg y-é 4 lesz. A előfordítóval definiált makrok tehát veszélyesek lehetnek.


A const típusmódosítóval

Az ANSI (szabványos) C-ben (és majd C++-ban) a const típusmódosító szó segítségével bármely memóriaobjektumot definiálhatunk konstansként, vagyis "csak olvasható változó"-ként. Ez azt jelenti, hogy a fordító figyelmeztet, ha a változó nevét értékadás bal oldalán szerepeltetjük, vagy ebből nem konstansra mutató pointert inicializálunk.

/* ANSI C megoldás PI definiálására */
const float PI = 3.14;

Mutatók esetén lehetőség van annak megkülönböztetésére, hogy a mutató által megcímzett objektumot, vagy magát a mutatót szeretnénk csak olvashatóvá tenni:

const char * p;  // p által címzett karakter nem módosítható, (const char) * p
char * const q;  // q mutatót nem lehet megváltoztatni, (char *) const q

Fájl olvasás és írás

File-kezelés

http://www.math.utah.edu/~carlson/c/cbook.pdf

Writing Data to a File Our first example is a C program which creates a file of random integers. The number of integers generated is under the control of the user, and the user can select the name of the file in which these integers are stored.

/* randfile.c: creates a file of N random numbers */
#include <stdlib.h>
#include <stdio.h>
main() {
    int i, N;
    FILE *fp;
    char *fname;
    printf("Number of random integers to generate: ");
    scanf("%d", &N);
    printf("File name: ");
    scanf("%s", fname);
    fp = fopen(fname, "w");
    for (i = 0; i < N; i++)
        fprintf(fp, "%5d\n", rand());
    fclose(fp);
}

A program paraméterezése

main() paraméterezése http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char **argv) {
    while(argc--)
    printf("%s\n", *argv++);
    exit(EXIT_SUCCESS);
}

Example 10.1

http://www.cprogramming.com/tutorial/c/lesson14.html

  1. include <stdio.h>
int main ( int argc, char *argv[] ) {
    /* argc should be 2 for correct execution */
    if (argc != 2) {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s filename", argv[0] );
    }
    else {
        // We assume argv[1] is a filename to open
        FILE *file = fopen( argv[1], "r" );
 
        /* fopen returns 0, the NULL pointer, on failure */
        if (file == 0) {
            printf( "Could not open file\n" );
        }
        else {
            int x;
            /* read one character at a time from file, stopping at EOF, which
               indicates the end of the file.  Note that the idiom of "assign
               to a variable, check the value" used below works because
               the assignment statement evaluates to the value assigned. */
            while ((x = fgetc(file)) != EOF ) {
                printf( "%c", x );
            }
            fclose( file );
        }
    }
}

Több fájlból álló program

röviden a linkelésről.


Gyakorlaton include-oljunk egy másik fáljt, ha lesz rá idő.


C függvénykönyvtárak

Matematikai függvények

math.h http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.7.html

Standard definíciók

stddef.h http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.11.html

Standard I/O

stdio.h http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.12.html

Standard dolgok

stdlib.h http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html

Macros:

   NULL
   RAND_MAX

Variables:

   typedef size_t
   typedef wchar_t

Functions: abs(); labs(); atof(); atoi(); atol(); malloc(); calloc(); free(); qsort(); rand(); srand();


Stringből számmá konvertáló függvények

atoi(), atof(),

Random számok generálása

rand(); srand();


Stringek

string.h http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.14.html


Ellenőrző kérdések

Amit a zh-ra tudni kell:

  • makrók definiálása
  • stringek kezelése (előző? előadás végén is volt)
  • main paraméterezése hogy néz ki
  • file olvasás, írás

Források és további olvasnivalók:

Személyes eszközök