bevezető - atw.huusers.atw.hu/nemethbogi/c_prog/gyorstalpalo/gyorstalpalo.pdf · dev-c++ microsoft...

14
Németh Levente Gyorstalpaló – C programozás ÓE-KVK Bevezető Ez cikksorozat elsősorban azoknak készül, akik nem győzik elolvasni a „kötelező” szakirodalmat, akik tűkön ülve várják, hogy elkezdhessék megírni az első „Hello world!” programjukat. Ez tulajdonképpen nem baj, mert később eldönthetik, hogy akarják-e folytatni, avagy nem. Ha ez előbbi úton indulnak el, akkor maguktól rádöbbennek, hogy igenis szükséges az a szakirodalom, s majd önállóan kezdenek el kutakodni utána. A C programozási nyelv platformfüggetlen használható Linux, Windows, Macintosh és egyéb operációs rendszereken át az Intel, Atmel, Microchip mikrokontrollereken keresztül mindenhol, ahol program fut. Az én cikkem az operációs rendszereken használt C programról, azon belül is Linuxon futó programok írásáról szól. Példák az egyéb helyeken használható fordítókra: Fordító neve Környezet Programozási nyelv Licensz Dev-C++ Microsoft Windows, Linux C, C++ nyíltforrású Lcc-win32 Microsoft Windows C nyíltforrású Keil C51 Mikrokontroller C (Intel 8051) shareware HI-Tech Mikrokontroller C (PIC) shareware Microchip MCCxx Mikrokontroller C (PIC) shareware WinAVR Mikrokontroller C (AVR) freeware Code VisionAVR Mikrokontroller C (AVR) shareware Természetesen rengeteg sok más egyéb fordító létezik, mindenféle felhasználásra Tehát mint említettem mi a Linuxon futó C fordítóval (gcc) fogunk megismerkedni, de elsősorban a magával a programozási nyelvvel, illetve annak struktúrájával. 1

Upload: others

Post on 30-Dec-2019

1 views

Category:

Documents


0 download

TRANSCRIPT

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Bevezető

Ez cikksorozat elsősorban azoknak készül, akik nem győzik elolvasni a „kötelező” szakirodalmat, akik tűkön ülve várják, hogy elkezdhessék megírni az első „Hello world!” programjukat.Ez tulajdonképpen nem baj, mert később eldönthetik, hogy akarják-e folytatni, avagy nem. Ha ez előbbi úton indulnak el, akkor maguktól rádöbbennek, hogy igenis szükséges az a szakirodalom, s majd önállóan kezdenek el kutakodni utána.

A C programozási nyelv platformfüggetlen használható Linux, Windows, Macintosh és egyéb operációs rendszereken át az Intel, Atmel, Microchip mikrokontrollereken keresztül mindenhol, ahol program fut.

Az én cikkem az operációs rendszereken használt C programról, azon belül is Linuxon futó programok írásáról szól.

Példák az egyéb helyeken használható fordítókra:

Fordító neve Környezet Programozási nyelv

Licensz

Dev-C++ Microsoft Windows, Linux C, C++ nyíltforrású

Lcc-win32 Microsoft Windows C nyíltforrású

Keil C51 Mikrokontroller C (Intel 8051) shareware

HI-Tech Mikrokontroller C (PIC) shareware

Microchip MCCxx Mikrokontroller C (PIC) shareware

WinAVR Mikrokontroller C (AVR) freeware

Code VisionAVR Mikrokontroller C (AVR) shareware

Természetesen rengeteg sok más egyéb fordító létezik, mindenféle felhasználásraTehát mint említettem mi a Linuxon futó C fordítóval (gcc) fogunk megismerkedni, de elsősorban a magával a programozási nyelvvel, illetve annak struktúrájával.

1

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Szia Világ! 1.0

Elsősorban meg kell ismerkedni néhány alapfogalommal:

• Allomány: A programunkhoz tartozó minden egyes forrásfájlt állománynak nevezünk, ezek *.c vagy *.h (header állomány) fájlok. A headerben - mint a neve is mutatja (fejléc) -, előre definiálhatunk függvényeket, makrókat, előfordítói feladatokat, stb.

• Változó: A program futása során megváltozható értékeket változókban tároljuk.Típusai lehetnek:

• char karakteres• int egész• float lebegőpontos tört

• Függvény: Bemeneti és visszatérési értékkel rendelkező összetartozó utasításcsoport.Legfontosabb és egyben elengedhetetlen függvény a main() függvény. Minden programnak rendelkeznie kell main() függvénnyel.

• Operátor: Értékek közötti művelet, ill. utasítás.

Íme egy példaprogram:

A példaprogramot megtalálod a gyűjteményben (src: hello.c)

A példaprogramokat le lehet tölteni tömörítve itt.Ha letöltötted, nyisd meg a terminált, futtasd a peldak.sh (navigálj a peldak mappába, majd ./peldak.sh) nevű scriptet. Ha egy példaprogram működését szeretnéd megnézni, akkor ezentúl mindig ezt a műveletet kell megtenned. Ha Microsoft® terméket futtatsz gépeden, akkor itt tudod letölteni a példaprogramokat. A tömörített mappában megtalálod a *.c forrásfájlokat (amiket a Dev-C++ programmal fordítottam) és a *.exe futtatható fájlokat. Az összefoglalót a peldak.exe tartalmazza.

2

#include <stdio.h> // stdio.h header-t is fordítjuk

void main(void) // a főprogram kezdete

{ // ez a karakter nyitja meg a programtörzset

int a, b, c; // a, b, c egész típusú változók deklarációja

a = 5; // a értéke mostantól 5

b = 10; // b értéke 10

c = a + b; // c változóba a kettő összege kerül

printf("A c változó értéke: %i\n",c); // kiíratjuk a képernyőre

} // lezárjuk függvényt

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Operátorok és használatuk

Az előző példában már használtunk operátorokat, például az egyenlőségjel vagy az összeadás. Nézzük meg, hogy valójában milyen operátorok léteznek és mire is jók egyáltalán.

Leggyakrabban használt operátorok az aritmetikai- és logikai operátorok, valamint az elválasztást végző operátorok:

Operátor Operátor neve Kiértékelés menete Operátor típusa

+ összeadás balról jobbra aritmetikai

- kivonás balról jobbra aritmetikai

* szorzás balról jobbra aritmetikai

/ osztás balról jobbra aritmetikai

% maradékképzés balról jobbra aritmetikai

= értékadás balról jobbra aritmetikai

- egyoperadusú mínusz jobbról balra aritmetikai

&& logikai ÉS balról jobbra logikai

|| logikai VAGY balról jobbra logikai

! logikai NEM jobbról balra logikai

A maradékképző (modulo) operátor egy kicsit érdekes. Működését példán mutatnám be:

Első esetben k = 105

= 2 ez teljesen világos, de 10 osztva 5-el miért 0? A modulo az

osztás eredményét figyelmen kívül hagyja, csak az érdekli, hogy mennyi a maradék. Így már világos, ha a 7-et elosztjuk 5-el, megvan 1-szer (ez minket nem érdekel), maradt a 2.A modulo-nak nagy szerepe van például páros számok keresésénél pl.: i = x%2; ha i értéke 0, akkor x páros, ha nem nulla, akkor értelemszerűen páratlan.

3

void main( void ){

int i = 10; // i változót deklaráltuk és 10 egész szám értéket kapottint j = 5; // j változó 5 egész értéket kapott/* egyszerűbben így nézne ki: int i=10,j=5; */int k; // k deklarálvaint l; // l deklarálva

k = i/j; // k értéke 2 leszl = i%j; // l értéke 0 leszl = 7%j; // l értéke 2 lesz

}

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Kamaszodunk

A példákat végignézve gyorsan rájövünk, hogy a programokat nem azért fogjuk írni, hogy a különböző kiíratásokban gyönyörködjünk, amit két szám egymással való osztásából nyertünk.Sokkal komplexebb feladatokat fogunk megoldani.

A kecskeméti Kandó Kálmán Szakközépiskola átlagon felüli mindennapjaiba belefér, szegény megkeseredett lelkületű diákok életét nyomorgassák a replusz művelettel.

Feladatunk ezért – a Kandósokon okulva –, egy replusz program megírása lesz:két szám szorzatát el kell osztanunk ugyanazon két szám összegével, ha lehetséges, ezeket a számokat tizedes tört formában adjuk meg.

A példaprogramot megtalálod a gyűjteményben (src: replusz1.c)

De valahogy ez mégsem tökéletes, mert így is megtudom mondani az RE értékét (5.4545), hiszen van a változóknak kezdőértékük.

A következő példában a program meg is kérdezi az ellenállások értékét, majd azokkal számol, amit megadunk neki, sőt még kulturáltan köszön is! :)

A példaprogramot megtalálod a gyűjteményben (src: replusz2.c)

4

#include <stdio.h>

void main( void ){

float R1=10, R2=12, RE;

RE = (R1*R2)/(R1+R2);

printf("Az eredő ellenállás értéke: %f\n",RE);}

#include <stdio.h>

void main( void ){

float R1, R2, RE;printf("\nÜdvözlöm kedves lelkes!\n\n");printf("Kérem adja meg R1 értékét ohm-ban: ");scanf("%f", &R1);printf("\nKérem adja meg R2 értékét ohm-ban: ");scanf("%f", &R2);RE = (R1*R2)/(R1+R2);printf("Az eredő ellenállás értéke: %f ohm (párhuzamos kapcs. esetén)\n",RE);

}

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Még mindig a matematika

Sok feladat elvégzéséhez szükségünk lesz a matematikában már megszokott és alkalmazott képletekre is. Ha egy szám négyzetére vagyunk kíváncsiak akkor megszorozzuk önmagával, ez triviális. De mi van akkor, ha éppen 16-dik hatványát szeretnénk megtudni? Elég hosszadalmas lenne begépelgetni, ugyanakkor annak a rizikó faktora is megnő, hogy elrontjuk. Vagy esetleg egy szög szinuszára, koszinuszára vagyunk kíváncsiak... Ilyen esetekben bizony be kell vonnunk még egy header állományt a játékba, mégpedig a math.h-t.

A következő példában egy kör adatait fogjuk kiszámolni:

A példaprogramot megtalálod a gyűjteményben (src: kor.c)

A math.h-ból elérhető legfontosabb konstansok:

Hivatkozási név Konstans értéke

M_E e

M_LOG10E lge

M_PI π

M_PI_2π2

M_1_PI1π

M_SQRT2 2

M_SQRT1_21

2

5

#include <stdio.h> #include <math.h>

void main( void ) {

float r,d,K,T; printf("\nKérem adja meg a kör kerületét: "); scanf("%f", &r); d = 2 * r; // Átmérő kiszámításaK = d * M_PI; // Kerület, M_PI a math.h-ban van definiálvaT = ( pow(r,2) * M_PI ); // pow a hatványozás

printf("\nA kör adatai: \n\n"); printf("Átmérő: %f egység\nKerület: %f egység\nTerület: %f egység\n\n",d,K,T);

}

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

A math.h-ból elérhető legfontosabb függvények:

Visszatérési érték Függvény Matematikai jelentés

double acos(double)arcus cosinus

float acosf(float)

double asin(double)arcus sinus

float asinf(float)

double atan(double)arcus tangens

float atanf(float)

double cos(double)cosinus

float cosf(float)

double pow(double, double)hatványozás

float powf(float, float)

double sin(double)sinus

float sinf(float)

double sqrt(double)gyökvonás

float sqrtf(float)

double tan(double)tangens

float tanf(float)

6

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Körbe-körbe

Az alapok megvannak, most ismerkedjünk meg néhány illetve az összes ciklusszervező utasítással, hiszen ciklusok nélkül nagyon bonyolult lenne egy valamire való program. Tételezzük fel, hogy egy értéket 25-ször kellene kiíratni a képernyőre, ciklus használata nélkül mind a 25-ször be kellene gépelni a printf() függvényt és argumentumait, rémes lenne.

A ciklus végrehajtása mindig egy feltételtől függ, tehát egy ciklus mindig magában foglal egy feltételvizsgálatot is. Attól függően, hogy ez hol történik meg, léteznek elöltesztelő illetve hátultesztelő ciklusok.

Az első, amivel meg fogunk ismerkedni, az a for ciklus. Ennek az utasításnak minimum 3 kifejezést kell megadnunk példa szerint:

for( kifejezés1; kifejezés2; kifejezés3 ) // a ciklus feje{

.

. // ciklustörzs

.}

A feltételvizsgálat a ciklus „fejében” történik, tehát ez elöltesztelő. A ciklus elindulása pillanatában az 1. kifejezés teljesül (csak egyszer hajtódik végre), majd megvizsgálja a 2. kifejezést, ami egy feltétel. Ha nem bizonyul igaznak, akkor lép a 3. kifejezésre, ha teljesül, akkor kilép a ciklusból.Ezt a folyamatot egy ábrával demonstrálnám:

7

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

A következő, amivel meg fogunk ismerkedni az a while ciklus:

while( kifejezes ) // a ciklus feje{

.

. // ciklustörzs

.}

Amíg a feltétel (kifejezés) igaznak bizonyul, addig hajtja végre a ciklus törzsében leírtakat.Ha a kifezes nem igaz, akkor be sem lép. A while ciklus is hátultesztelő.

While folyamatábrája:

8

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

És végül, de nem utolsó sorban a do-while ciklus:

do{

.

.

.}while( kifejezés )

Ebben az esetben a ciklustörzs egyszer mindenképpen lefut, majd megvizsgálja a kifejezés értékét és ha az igaz, akkor még egyszer lefut. Ez addig fog ismétlődni, amíg a kifejezés hamis nem lesz. A do-while szerkezet egy hátultesztelő ciklus.

Do-while folyamatábrája:

9

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

A ciklusok futását befolyásoló parancsok:

➢ break: Hatására a program kilép az aktuális ciklusból. Egymásba ágyazott ciklusok esetén a break után eggyel feljebb lévő ciklusba kerül a program.

➢ continue: Hatására a ciklus további futása helyett a ciklus feltétele kerül újbóli kiértékelésre, tehát a ciklus az elejére ugrik, for ciklus esetén végrehajtódik a 3. kifejezés.

Mint az az ábrákból kiderülhetett ezeket az utasításokat önmagában értelmetlen lenne használni. Éppen ezért fogunk a következőkben megismerkedni a feltételvizsgálatokkal.

Végtelen ciklusokat is képezhetünk, ilyenkor a ciklustörzs végtelenségig fut, ezt a következőképpen tehetjük meg:

for(;;) while(1){ {

// ciklustörzs // ciklustörzs} }

10

Ne feledd, ami nem 0, az a C-ben igaznak minősül, tehát a -12 is igaz, mert nem nulla!

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Feltétlenül szükséges feltételek

Ha már ennyi mindent tudunk – változót deklarálni, matematikai műveleteket végezni, ciklusokat szervezni –, akkor tanuljuk határt szabni. Ezzel a művelettel programunkat el tudjuk ágaztatni különböző feltételek mellett.

Például egy megadott számig elszámolva szeretnénk megtudni, hogy hány darab páros szám van. Először is egy ciklust kell szerveznünk, amely 1-től elszámol az adott számig. A ciklus törzsében el kell helyeznünk egy modulo osztást, az éppen aktuális számot 2-vel, ha a maradék 0, akkor páros, ilyenkor egy számlálót léptetünk, majd a végén kiíratjuk a számláló értékét. Az eddigi tudásunk szerint a „szám modulo 2”-ig jutnánk el, hiszen itt egy feltételvizsgálatot kell végezni.

Az if vagy if-else szerkezet elvégzi nekünk a vizsgálatot és elágaztatja a programot. Az if létezhet else nélkül, de fordítva nem.

if( feltétel ){

.

. // A feltétel teljesülése esetén}

VAGY

if( feltétel ){

.

. // Ha a feltétel igaz}else{

.

. // Ha a feltétel hamis}

11

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Most már meg tudjuk írni programocskánkat:

A programot futtatva látjuk (remélem), hogy elég lett volna 2-vel elosztani a megadott számot és máris ugyanazt az eredményt kapjuk. De mi van akkor, ha „n”-ig keressük azokat a négyzetszámokat, amelyek oszthatóak 2-vel, de 5-el már nem. Ilyenkor teljesen más a leányzó fekvése, ehhez a feladathoz megéri programot írni. Íme a példaprogram:

12

#include <stdio.h>

int main() {

int i, n, modulo, szamlalo = 0; printf("\n\nKérem adjon meg egy egész számot: "); scanf( "%i", &n ); for( i = 1; i <= n; i++ ) // A ciklus 1-től n-ig egyesével léptetve tart{

modulo = i%2; // A 2-vel való osztás maradéka

if( modulo == 0 ) // Ha ez nulla,{

szamlalo++; // A számláló értéke eggyel nő}

} printf("\n\n1-től %i-ig %i db páros számot találtam.\n\n", n, szamlalo);

}

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

A példaprogramot megtalálod a gyűjteményben (src: matek.c)

Ezt a programot nem taglalom, mert elég egyértelműnek tűnik.

13

#include <stdio.h> #include <math.h> // Használjuk a math.h-t

int main() {

int i, n, negyzet, szamlalo = 0; // Azért van két sorban, int modulo2, modulo5; // hogy kiférjek :)

printf("\n\nKérem adjon meg egy egész számot: "); scanf( "%i", &n ); for( i = 1; i <= n; i++ ) // A ciklus 1-től n-ig egyesével léptetve tart {

negyzet = pow( i,2 ); // Négyzetre emelés

if( negyzet > n ) // Ha a négyzet nagyobb, mint a "n", {

break; // kilép a ciklusból } else {

modulo2 = negyzet%2; // A 2-vel való osztás maradéka modulo5 = negyzet%5; // Az 5-el való osztás maradéka

} if( modulo2 == 0 && modulo5 != 0 ) // Ha modulo2 nulla

// ÉS modulo5 nem nulla, {

szamlalo++; // A számláló értéke eggyel nő

} } printf("\n\n1-től %i-ig %i db páros, 5-el NEM osztható négyzetszámot

találtam.\n\n", n, szamlalo); }

Németh Levente Gyorstalpaló – C programozás ÓE-KVK

Az előző példa egy kicsit tömörebb formában:

Rövidebb, de mit is csinál valójában? A math.h header állomány eltűnt, a ciklus maradt, kevesebb változó lett. Magában a feltételvizsgálatban végeztünk egy egyszerű szorzást, ami a szám négyzetét adja, ha ez nagyobb mint „n”, akkor kilép a ciklusból. Láthatóan elhagytam a kapcsos zárójeleket az if-nél, ez megengedhető abban az esetben, ha csak EGYETLEN utasítást kell végrehajtani, ha feltétel igaznak bizonyul. Ha a ciklus folytatódik akkor jön a következő vizsgálat, amely hét lépést tartalmaz egyben:

a) szorzok → négyzetb) modulo 2-vel → páros-e a négyzet? Ha igen akkor 1, ha nem akkor 0.c) kizáró VAGY kapcsolat (exlusive OR, XOR) 1-eld) szorzok → négyzete) modulo 5-el → osztható-e 5-el a négyzet? Ha igen, akkor 1, ha nem akkor 0.f) XOR 0-valg) a két értéket logkai ÉS kapcsolatba helyezem egymással

Az XOR (ejtsd: ikszor) művelet eredménye akkor ad logikai 1 értéket, ha a két különbözik:

A B XOR A,B

0 0 0

0 1 1

1 0 1

1 1 0

Lehet agyalni, hogy hogyan működik a program. A magyarázat nem férne ki 1 oldalon, ezért nincs.

14

#include <stdio.h>

int main() {

int i, n, szamlalo = 0;

printf("\n\nKérem adjon meg egy egész számot: "); scanf( "%i", &n ); for( i = 1; i <= n; i++ ) // A ciklus 1-től n-ig egyesével léptetve tart {

if( (i*i) > n ) // Négyzetre emelés, vizsgálat, kilépés break; if( 1^((i*i)%2) && 0^((i*i)%5) ) // Oszthatóság vizsgálataszamlalo++; // számláló léptetése

} printf("\n\n1-től %i-ig %i db páros, 5-el NEM osztható négyzetszámot

találtam.\n\n", n, szamlalo); }