Programozás alapjai gyakorlat 2014-2015/1

11. gyakorlat



    Függvény pointer

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;
}



    Parancssori argumentumok


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;
}




Jövő héten nem lesz ZH!

Viszont a gyakorlaton való részvétel (így utoljára) kötelező!

szerk.: csak azoknak akikek meglett a minimum a miniZH-kon.

2 hét múlva NagyZH!

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.




Házi feladat

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.