Informatika2-2012/Eloadas07
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
- 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:
- http://www.tankonyvtar.hu/informatika/objektum-orientalt-080905-103
- 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
- http://www.cprogramming.com/tutorial/c/lesson14.html
- http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html
- http://en.wikipedia.org/wiki/Include_guard