Több feladat közül futási időben döntöm el, hogy melyiket hajtom végre. A függvényre mutató pointer a függvény kódjának a címére mutat, azon keresztül meghívhatom a függvényt. A pointernek tudnia kell a függvény típusát (paraméterek és visszatérési érték típusa). Pl.:
double fgv(double, double); /* függvény deklarációja */ double (*fptr)(double, double); /* ilyen típusú függvényre mutató pointer deklarációja */ fptr = fgv; /* a függvény nevét adom kezdőértékül, a fordító persze ebből címet állít elő */ fptr(x, y); /* meghívom a függvényt a pointeren keresztül */
F: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányadikat. ============================================================================== #include <stdio.h> #include <math.h> /* sinus négyzet - beépített függvénnyel */ double sin2(double x) { double sinx = sin(x); return sinx*sinx; } /* kettes alapú logaritmus - beépített függvénnyel */ double log2(double x) { return log(x) / log(2); } /* cosinus négyzet - beépített függvénnyel */ double cos2(double x) { double cosx = cos(x); return cosx*cosx; } typedef double (*fgvtip)(double); /* függvényre mutató pointer típusa */ /* melynek double a visszatérési értéke és double típust vár a paraméterlistában */ fgvtip tabla[] = { /* ilyen pointerek tömbje */ sin2, /* a függvény neve értékül adható függvényre mutató pointernek */ log2, cos2 }; int main() { int f, x; char* valasztek = "{ 1: sin2x }\n{ 2: log2x }\n{ 3: cos2x }\n"; /* karakterekre mutató pointer, lényegileg egy string */ printf("Melyik fuggveny legyen?:\n%s?:\t", valasztek); scanf("%d", &f); printf("Argumentum erteke?:\t"); scanf("%d", &x); printf("A fuggveny erteke az adott pontban:\t%lf\n", tabla[f-1](x) ); /* a tömbben lévő pointeren keresztül hívom a függvényt */ /* 1-től 3-ig várt bemenetet a program. 0-tól való indexelés miatt levon 1-et [f-1] és paraméterként átadódik az úgyszint beolvasott érték (x) */ return 0; }
F: Egy tömbbe olvassunk be, majd írassuk ki az elemeket úgy, hogy a tömb bejárását egy függvény végezze, ami megkapja a műveletet. ============================================================================== #include <stdio.h> #define N 10 typedef void (*muvelettipus)(int*); /* függvényre mutató pointer típusa */ /* melynek nincs visszatérési értéke (void) és int-re mutató pointert vár a paraméterlistában */ /* egy tömböt vár illetve a bejar függvény alatt található művelet függvények egyikét */ void bejar(int* tomb, muvelettipus muvelet) { int i; for(i=0; i<N; i++) { (*muvelet)(tomb+i); // ide kerül behelyettesítésre a paraméterként kapott művelet-függvény, mely saját bemeneti paraméterét is megkapja. // azért kerül 'tomb+i' a paraméterlistába, mert a 'tomb' alapjáraton a paraméterként kapott tömb kezdőpozíciójára mutat, // így a for ciklusban végig haladva, mindig i-t hazzáadva mindig a tömb rákövetkező elemét kapjuk } } void beolvas(int* v) { scanf("%d", v); } void kiir(int* v) { printf("%d\n", *v); } void duplaz(int* v) { (*v) *= 2; } int main() { int t[N]; bejar(t, beolvas); bejar(t, kiir); bejar(t, duplaz); bejar(t, kiir); return 0; }
A main függvénynek három paramétere lehet. Az első egy int, a parancssorban kapott argumentumok száma + 1 (a program neve maga is egy argumentum). A második egy olyan pointer-tömb, mely azokra a memóriaterületekre mutatnak, ahol sztringként vannak letárolva a parancssori argumentumok. A harmadik hasonló a másodikhoz, csak ez a környezeti változók címeit tartalmazza.
Írjuk ki a parancssorban lévő argumentumokat:
#include <stdio.h> main(int argc, char **argv) // vagy így is lehet az argv-t deklarálni: // main(int argc, char *argv[]) { int i; printf("argc = %d\n\n",argc); for (i=0; i<argc; ++i) { printf("argv[%d]: %s\n", i, argv[i]); } }
Mentsük el a fenti programot arg.c néven és fordítsuk le!
$ gcc -o arg arg.c $ ./arg alma korte szilva barack palinka argc = 6 argv[0]: ./arg argv[1]: alma argv[2]: korte argv[3]: szilva argv[4]: barack argv[5]: palinka
F: Írj egy programot, ami összeadja a parancssori paramétereket. ============================================================================== #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { int i; int arg = 0; printf("Osszesen %d programargumentumot kaptam!\n",argc); for(i = 0; i< argc; i++) printf("%d : %s\n",i, argv[i]); if(argc > 1) { for(i = 1; i< argc; i++) arg += atoi(argv[i]); } printf("Az argumentumok osszege : %d\n", arg); return 0; }
F: Írj egy programot, amely n-szer egymás után fűzi ugyanazt az s sztringet, ahol n és s is parancssori paraméter. ============================================================================== #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[]) { int i; char *er; if(argc < 3) { printf("Használat: %s <valami szám> <valami sztring>\n", argv[0]); return 1; } er = (char*) calloc ( atoi(argv[1]) + 1 , strlen(argv[2]) ); strcpy(er,argv[2]); for(i=0;i<atoi(argv[1])-1;i++){ strcat(er,argv[2]); } printf("%s\n",er); free(er); return 0; }
Viszont a gyakorlaton való részvétel (így utoljára) kötelező!
szerk.: csak azoknak akikek meglett a minimum a miniZH-kon.
10 feladat került kiadásra. Ezen feladatok elérhetőek az /n/pub/ProgramozasAlapjai/Gyakorlat/ könyvtárban a Progalap-nagy-zh-2014-3-f.pdf fájl formájában.
Elviekben a 8. (elmaradó) zh hetében mindenkinek lesz (remélhetőleg) lehetősége a bírón is kipróbálni 1-1 megoldást.
A házi feladatot megoldani nem kötelező és bemutatni sem kell, viszont a következő gyakorlaton visszakérhető (kikérdezés, táblához hívás, stb. formájában)! Ha a hallgató megoldása ötletes, szép kivitelezésű, plusz pont adható. Amennyiben viszont nem tudja megoldani gyakorlaton a házi feladatban szereplő példákat vagy nem tud válaszolni az azzal kapcsolatban feltett kérdésekre, mínusz pont adható. Plusz és mínusz pontból is egyaránt maximum 10 pontot gyűjthet össze egy-egy hallgató.
Házi feladat 01-hazi.txt .
Vissza a lap tetejére.