Programozás alapjai gyakorlat 2015-2016/1

6. gyakorlat


    Előző heti plusz pontos házi:

A megoldások az 5. gyakorlat anyagánál elérhetőek, a feladatkiírások helyén.


    Mit is tanultunk az 5. gyakorlaton?

Ismétlő feladat:

    (a) Használjunk konstansokat tömbök létrehozásához, feltöltéséhez és kiíratásához. 1 és 2 dimenziós tömbökkel is dolgozzunk.

    (b) Hozzunk létre egy karakter tömböt. Töltsük fel és különböző képpen írassuk ki. Ellenőrizzük le a hosszát is.

Megoldás letöltése .





    Típus definiálás

A típus definiálás általános alakja:

typedef típus név

Feladat: Hogyan tudunk létrehozni egy olyan vector nevű tömb típust, amely egy háromdimenziós térbeli vektort reprezentál?


typedef double vector[3];

Feladat: Hogyan lehet létrehozni egy N hosszúságú sztringek tárolására szolgáló karaktertömb típust?


typedef char string[N+1];

Feladat: Hozz létre külön típust 16 bites nemnegatív értékek tárolására.


typedef unsigned short int u16;


    Felsorolás típus - enum

Felsorolás adattípus értékhalmaza a típusképzésben felsorolt azonosítók, mint konstans azonosítók által meghatározott értékek.

Feladat: Definiálj egy felsorolástípust a hét napjainak tárolására, majd írasd ki a napok értékeit!


#include <stdio.h>

int main()
{
	enum { Hetfo,
		Kedd,
		Szerda,
		Csutortok,
		Pentek,
		Szombat,
		Vasarnap
	} nap;
	for(nap=Hetfo; nap <= Vasarnap; nap++) {
	    	printf("%d\n", nap);
	}
	return 0;
}

Feladat: Vedd külön a típusdefiníciót és a változódeklarációt!


#include <stdio.h>

typedef enum { Hetfo,
		Kedd,
		Szerda,
		Csutortok,
		Pentek,
		Szombat,
		Vasarnap
} het;

int main()
{
	het nap;
	for(nap=Hetfo; nap <= Vasarnap; nap++) {
	    	printf("%d\n", nap);
	}
	return 0;
}

Egy enum változó tulajdonképpen egy egész változó.

Elmélkedjünk:

F: Mi történik, ha Hetfo=1 -ként adod meg az első elemet?
F: Mi történik, ha Szombat=10 -ként adod meg a hatodik elemet?
F: Adhatod-e az enum mindegyik elemének ugyanazt az int értéket?

Nézzük meg a következő összetettebb példát. Mi is történik és miért?


#include <stdio.h>

int main()
{
    enum het { Hetfo, Kedd, Szerda, Csutortok, Pentek, Szombat, Vasarnap } nap;
    typedef enum { piros, zold, sarga } colors;
    colors col;

    printf("Milyen napon szeretnél almát enni? "); scanf("%d",&nap);
    printf("Milyen színű almát szeretnél enni? "); scanf("%d",&col);
    switch(nap)
    {
        case Hetfo :
        case Kedd :
        case Szerda :
        case Csutortok : 
        case Pentek :
            printf("Csak hétvégén tudok almát felszolgálni!\n");
            break;
        case Szombat :
        case Vasarnap :
            printf("Mivel hétvége van, alma is van!\n");
            switch(col)
            {
                case piros: 
                    printf("A piros alma egészséges, jó választás!\n");
                    break;
                case zold :
                    printf("Vigyázz, a zöldalma savanyú!\n");
                    break;
                case sarga :
                    printf("A sárga alma is nagyon finom!\n");
                    break;
                default :
                    printf("Nem ismerek ilyen színű almát!\n");
            }
            break;
        default:
            printf("A hét csak 7 napból áll!\n");
            break;
    }
    
    return 0;
}


    Karakter típusról komolyabban

sizeof operátor - típusok méretének meghatározása byteokban. Pl.:

int i = sizeof(int);   // ilyenkor az i változóba bele kerül az int típus mérete. ez a C esetén 4 byte

A legtöbb típust mind meglehet adni előjeles vagy előjeltelen formában. Egy típust előjelessé a signed, előjeltelenné az unsigned módosítóval tehetünk. A típusok alapértelmezés szerint általában előjelesek.

C típus         méret(bájt)   alsó határ    felső határ
_______________________________________________________
char                 1                 ?              ?
signed char          1              -128            127
unsigned char        1                 0            255
short int            2            -32768          32767
unsigned short int   2                 0          65535
int                  4       -2147483648     2147483647
unsigned int         4                 0     4294967295
long int             4       -2147483648     2147483647
unsigned long int    4                 0     4294967295
long long            8              -263          263-1
float                4         -+3.4028234663852886E+38
double               8        -+1.7976931348623157E+308
long double          8        -+1.7976931348623157E+308

Túlcsordulás: Ha egy művelet eredménye túlhalad valamelyik irányban az azt eltárolni próbáló változó értékkészletén, akkor túlcsordulásról beszélünk. (Ha lefelé halad túl, szoktuk alulcsordulásnak is hívni.) Ilyenkor a "számláló körbefordul", tehát ha pl. egy unsigned char változóhoz, aminek az értéke 250 hozzáadunk 10-et, a változó értéke 4 lesz. ( Mivel a char típus mérete 1 byte = 8 bit. 250 + 10 = 260 bit. 5 bit a túlcsordulás. )


F: Hány bájton tárolódik a char típus?
==============================================================================

#include <stdio.h>

int main() {
	printf("char: %d\n", sizeof(char));
	return 0;
}

F: Írasd ki a 64 és 95 közé eső kódú karaktereket.
==============================================================================

#include <stdio.h>

int main() {
	char c;
	for(c=64; c<96; c++) {
		printf(" %c", c);
	}
	putchar('\n');
	return 0;
}
F: Alakítsd át az előző példát: írasd ki az 'a' és 'z' közé eső karakterek kódjait.

F: Mi a különbség a signed char és az unsigned char értékkészlete között?
   Írasd ki -128-tól 255-ig egy signed és egy unsigned char típusú változó
   számértékét!
==============================================================================

#include <stdio.h>

int main() {
	int i;
	signed char sc;
	unsigned char uc;
	for(i=-128; i<=255; i++) {
		sc=i;
		uc=i;
		printf("%hhd %hhu\n", sc, uc);
	}
	return 0;
}

Feladat: Olvass be két legfeljebb 20 karakter hosszúságú szót, és fűzd őket egymás után egy harmadik sztringbe. A string.h függvényeit használd!


#include <stdio.h>
#include <string.h>

int main() {
	char egyik[21], masik[21], harmadik[41];
	scanf("%s %s", egyik, masik);
	strcpy(harmadik, egyik);
	strcat(harmadik, masik);
	printf(" -> %s\n", harmadik);
	return 0;
}


    Float


F: Hány bájton tárolódik a float és double típus?
==============================================================================

#include <stdio.h>

int main() {
	printf("float : %d\n", sizeof(float));
	printf("double: %d\n", sizeof(double));
	return 0;
}

F: Mi a különbség a float és a double pontossága között? Add hozzá az 1, 0.1,
   0.01, 0.001, ... sorozat elemeit egy-egy float és double változóhoz. Milyen
   értékeket kapsz lépésenként?
==============================================================================

#include <stdio.h>

int main() {
	int i;
	float  f = 0.0, df = 1.0;
	double d = 0.0, dd = 1.0;
	for(i=0; i<20; i++) {
		f += df;
		d += dd;
		df *= 0.1;
		dd *= 0.1;
		printf("%d: float: %22.20f; double: %22.20lf\n", i + 1, f, d);
	}
	return 0;
}

F: Mi a különbség a float és a double értékkészlete között? Szorozgasd egy
   float és double változó értékét 0.1-gyel, amíg 0 nem lesz mindkettő. Milyen
   értékeket kapsz lépésenként?
==============================================================================

#include <stdio.h>

int main() {
	float  f = 1.0;
	double d = 1.0;
	int i = 0;
	do {
		printf("%d: float: %g; double: %lg\n", ++i, f, d);
		f *= 0.1;
		d *= 0.1;
	} while((f!=0.0) || (d!=0.0));
	return 0;
}


    Integer


F: Hány bájton tárolódik a short int, int, long int, long long típus?
==============================================================================

#include <stdio.h>

int main() {
	printf("short int: %d\n", sizeof(short int));
	printf("int      : %d\n", sizeof(int));
	printf("long int : %d\n", sizeof(long int));
	printf("long long: %d\n", sizeof(long long));
	return 0;
}

F: Mi a különbség ugyanazon típus előjeles és előjeltelen verziója között?
   Deklarálj 6 változót (signed/unsigned, short/long/long long) változót, 0
   kezdőértékkel, és vonj ki belőlük egyet. Milyen értékeket kapsz? Add
   értékül a változóknak a legnagyobb előjelesen ábrázolható értéket (ez fele
   az előjeltelen maximális értéknek), és adj hozzá egyet. Most mik a változók
   értékei?
==============================================================================

#include <stdio.h>

int main() {
	signed short int   ssi = 0;
	unsigned short int usi = 0;
	signed long int    sli = 0;
	unsigned long int  uli = 0;
	signed long long   sll = 0;
	unsigned long long ull = 0;
	ssi -= 1;
	usi -= 1;
	sli -= 1;
	uli -= 1;
	sll -= 1;
	ull -= 1;
	printf("0 mínusz 1\n");
	printf("s16: %hd\n",  ssi);
	printf("u16: %hu\n",  usi);
	printf("s32: %ld\n",  sli);
	printf("u32: %lu\n",  uli);
	printf("s64: %lld\n", sll);
	printf("u64: %llu\n", ull);
	ssi = usi /= 2;
	sli = uli /= 2;
	sll = ull /= 2;
	printf("Legnagyobb ábrázolható előjeles szám...\n");
	printf("s16: %hd\n",  ssi);
	printf("u16: %hu\n",  usi);
	printf("s32: %ld\n",  sli);
	printf("u32: %lu\n",  uli);
	printf("s64: %lld\n", sll);
	printf("u64: %llu\n", ull);
	ssi += 1;
	usi += 1;
	sli += 1;
	uli += 1;
	sll += 1;
	ull += 1;
	printf("... plusz 1\n");
	printf("s16: %hd\n",  ssi);
	printf("u16: %hu\n",  usi);
	printf("s32: %ld\n",  sli);
	printf("u32: %lu\n",  uli);
	printf("s64: %lld\n", sll);
	printf("u64: %llu\n", ull);
	return 0;
}


Nézzünk néhány érdekesebb példát:

Írjunk egy ciklust, amely végig ellenőrzi egy bemenetként kapott n szám esetén, hogy 1-től 1000-ig mely számok oszthatóak n^2+n+1-gyel.

Megoldás letöltése .


Plusz pontos házi feladat

Írjunk egy bombakereső játékot. A játékot a számítógép ellen játszuk. A számítógép induláskor feltölt egy 10*10-es tömböt random 0-kal és 1-esekkel, úgyh pl. 10 darab 1-es legyen a táblán, a többi mind 0. Az 1-esek szimbolizálják a bombákat. A játék kezdésekor a játékos úgyszint kitölt egy ugyanekkora táblát a saját elképzelése szerint, úgy, hogy megadja, hogy melyik pozícióra kerüljönek a bombái: [i,j]. Miután a random generátor feltöltötte az ellenfél tábláját, illetve a játékos is feltöltötte a sajátját, megkezdődhet a játék. Ezután felváltva találgathat a két játékos, hogy szerintük hol lehet bomba az ellenfél tábláján. Az nyer, aki előbb megtalálja az ellenfél összes bombáját. A játék végén írjuk ki, hogy ki nyerte a játszmát.

Beküldési határidő: keddieknek 2015. 10. 09., éjfél, csütörtökieknek 2015. 10. 11., éjfél.

Küldés STUD-os email címről, melynek tárgya: [progalap2015][06][plusz], tartalma pedig maga a kód, vagy a csatolt .c fájl.

Egy kis segítség: nyugodtan töltsük fel mindkét táblát kezdetben 0-kal, majd ahova érkezik 1-es, ott csak írjuk felül. A számítógép táblájának feltöltésére egy lehetséges megoldás, hogy két számot generáltatunk: az egyik lesz az oszlop indexe, a másik pedig a sornak az indexe. Így jön ki pl., hogy hova kerüljön 1-es. Bevezethetünk két segéd változót, amely azt figyeli, hogy ki hány bombát talált eddig. Ha valamelyik változó értéke eléri a 10-et, meg van az összes bomba, a játék véget ér. (Arra ügyeljünk, hogy kétszer ugyanoda tippelve, ne szerezzen egyik játékos sem mégegyszer pontot, legyegyszerűbb, ha egy találat esetén egyből felülírjuk 0-val az adott pozíciót az adott tömbben.)

A feladat megoldását/próbálgatását erősen ajánlom mindenkinek. Sok mindenre rá lehet jönni ilyenkor. Próbáljunk meg a körülményekhez mérten felhasználóbarát programot készíteni!

Egy lehetséges megoldás letöltése .



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ó.

A házi feladat és további gyakorló példák elérhetőek a PUB-ban ( /n/pub/ProgramozasAlapjai/Gyakorlat/gyak06/ )

Bárkinek bármi kérdése adódik a feladatokkal kapcsolatban írjon nyugodtan! ( Gyakoroljatok sokat! )




    Jövő héten 4. miniZH (2015.10.13./15.)

Téma:

  5. gyakorlat anyaga. (De tudni kell az előző - 3. és 4. - gyakorlat anyagát is!)

  Gyakorlásra:

    A honlapomon a 3., 4. és 5. gyakorlathoz tartozó anyag, magyarázatokkal, példákkal.

    A gyakorlatok végén lévő házi feladat és gyakorló feladatok megoldása.

    A honlapom mellet további feladatok találhatóak a PUB-ban. (/n/pub/ProgramozasAlapjai/Gyakorlat/ - erős átfedés van az "itt" és "ott" található feladatok között).

Egyéb infó:

Előreláthatóan 35 percetek lesz a feladatok megoldására és beadására (tehát 8:45-ig/12:35-ig). A feladatokat a BÍRÓ rendszeren keresztül fogjátok megkapni és beadni is, és az értékelést is a bíró fogja csinálni ott helyben. Tehát egyből látni fogjátok a pontszámokat amiket a bíró adott. Aki késik, az is csak a fenti időintervallum alatt írhatja a ZH-t (a bíró rendszer nyit, majd automatikusan zár is). Hiányozni csak igazolással lehet, de a ZH akkor sem pótolható!


     Vissza a lap tetejére.