Elmélet | Példa | Feltöltendő | Feladatok | Megjegyzések
A forráskódtól a végrehajtható programig
Előfeldolgozás (preprocess)
Az előfeldolgozás során a forráskódú programból egy ugyancsak forráskódú
programot kapunk, amelyben a makrodefiníciók (#define) ki vannak terjesztve, és
tartalmazza az „include” file-okat (#include).
Fordítás (compile)
A fordítás révén a forráskódból (pl. C, C++) tárgykódot (object) kapunk. C,
illetve C++ programok esetén a bemenet egy C vagy C++ forráskódot tartalmazó
állomány, kimenetként egy tárgykódú állományt kapunk. A fordítóprogram elvégzi
az előfeldolgozást is. A UNIX-beli C fordító általában a bemeneti állománnyal
azonos nevű, de „.o” kiterjesztésű tárgykódú állományt hoz létre.
Összeszerkesztés (link)
Ennek a munkafázisnak a szerepe, hogy esetleg több tárgykódú állományból, és
ha szükséges a program által használt könyvtárakból egy végrehajtható állományt
hozzon létre. Ez azért szükséges, mert egy program több modulból is állhat,
amelyeket külön fordítunk le. Ugyanakkor külső könyvtárakat is használhatunk.
A gcc/g++ fordítóprogram
A gcc fordítóprogram jelenleg az egyik legerősebb C fordító. C++ forráskód
fordításához kiterjesztett változata a g++, amit ugyancsak meghívhatunk gcc
néven is. A forráskódú állomány kiterjesztése alapján dönti el a fordító, hogy
milyen kódról van szó. „.c” kiterjesztés C, míg „.C”, „.cc”, „.cpp”, „.c++”,
stb. kiterjesztés C++ forráskódot jelent. Ez a fordítóprogram elvégzi az
előfeldolgozást, a fordítást és az összeszerkesztést is. Ha nem akarunk minden
fázison végigmenni, opciókkal, illetve az állománynév kiterjesztésével
jelezhetjük ezt a fordítóprogramnak. Ha nem adtuk meg a parancssorban másként, a
létrehozott végrehajtható file az a.out. Részletek: man gcc.
Példák:
Egyetlen modul:
gcc pelda.C -o pelda
Több modul:
gcc pelda.C -c
gcc seged.cc -c
gcc pelda.o seged.o -o pelda
Külső könyvtár is szükséges:
gcc pelda.C -c
gcc seged.cc -c
gcc pelda.o seged.o -I/usr/lib/libncurses.a -o pelda
A make segédprogram – makefile
Nagyobb, összetett programok esetén a program több, illetve sok modulból épül fel. Ezek a modulok egymástól függnek, egy modul változása szükségessé teheti több más modul újrafordítását is, illetve az egész program összeszerkesztését. A modulok között „függőségek” vannak. A make segédprogram segítségével egyszerűen lefordíthatunk egy nagy projektet úgy, hogy csak azokat a modulokat fordítja újra, amelyeket a függőségek alapján szükséges, nem kell a programozó figyeljen minden változásra. A make segédprogram a makefile-ban található szabályok és az állományok „időbélyege” alapján dönti el, hogy milyen parancsokat kell végrehajtson.
Egy makefile szabályokat, változódefiníciókat, direktívákat és kommentárokat tartalmazhat.
Szabályok
Egy szabály azt adja meg, hogy a szabály célállománya melyik
állományoktól függ, illetve milyen paranccsal hozzuk létre. Ha a függést okozó
file-ok közül bármelyik időbélyege újabb, mint a célállományé, a parancssor
végrehajtásra kerül. Egy szabály szerkezete:
célállomány: függést okozó állományok
parancssor
célállomány: függést okozó állományok; parancssor
A parancssort általában újsorba írjuk, ekkor kötelezően egy <Tab> karakterrel kezdődik. Tartalmazhat több parancsot is. Ezeket vagy „;”-vel elválasztva, vagy <Tab> karakterrel kezdődő új sorba írjuk.
Változódefiníciók
A változódefiníció egy olyan sor, amely egy változó értékeként egy karaktersort
ad meg. A továbbiakban a változó nevét ezzel a karaktersorral helyettesíti a
program.
Direktívák
Egy direktíva azt jelzi a make segédprogramnak, hogy a makefile beolvasása
közben valamilyen speciális feladatot végezzen el. Ez lehet például egy másik
makefile beolvasása, valamilyen feltétel, stb.
Kommentárok
A program a „#” utáni részt kommentárnak tekinti, nem értelmezi. Hasonlóan az
üres sor is kommentár.
A make segédprogramot meghívhatjuk egyszerűen paraméterek nélkül, ebben az esetben „makefile”, „Makefile”, „GNUmakefile” kell legyen a makefile neve, vagy -f opcióval megadhatjuk a makefile nevét.
Részeletek: info make
Jó összefoglaló: http://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html
# Változó deklarációk
CC = g++
CCFLAGS = -Wall
SRC = seged.cc \
pelda.cc
OBJ = seged.o \
pelda.o
PROGRAM = pelda
# fordítási szabályok
$(PROGRAM) : $(OBJ)
$(CC) $(OBJ) -o $(PROGRAM)
seged.o : seged.cc adat.h
$(CC) seged.cc -c $(CCFLAGS)
pelda.o : pelda.cc adat.h
$(CC) pelda.cc -c $(CCFLAGS)
# Törlési parancsok
.PHONY : clean
clean :
rm -f $(PROGRAM) $(OBJ) core *~
Az állományokat a
tar -czf zipnev.gz allomanynevek
paranccsal csomagoljuk.
Kicsomagolni a
tar -xzf zipnev.gz
vagy
tar -xzf zipnev.gz -C katalogus/
paranccsal lehet.
Részeletek: man tar.
1. Írjunk egy „gyok(k,a)” függvényt, amelyik kiszámítja a k-ad rendű gyökét e=0.00000001 pontossággal (k>2 természetes szám, a pozitív valós), mint az xn+1 = 1/k ((k-1) xn +a/xnk-1) sorozat határértékét tudva, hogy x0 = a/2. Ezt a függvényt használjuk az S = gyok(k,x1) + ... + gyok(k,xn) összeg kiszámítására, ahol az x1, x2, ..., xn pozitív valós értékek, melyeket az „input.dat” file-ból olvasunk be.
2. Írjunk egy „lnko(k,m)” függvényt, amelyik kiszámítja k és m legnagyobb közös osztóját. Ezt a függvényt használjuk az x1, x2, ..., xn, n>1, természetes számok legnagyobb közös osztójának kiszámítására. A számokat az „input.dat” file-ból olvasunk be.
3. Írjunk egy „lkkt(k,m)” függvényt, amelyik kiszámítja k és m legkisebb közös többszörösét. Ezt a függvényt használjuk az x1, x2, ..., xn, n>1, természetes számok legkisebb közös többszörösének kiszámítására. A számokat az „input.dat” file-ból olvasunk be.
4. Írjunk egy „szhal(a,b,c)” függvényt, amelyik ellenőrzi, hogy az a, b és c számok számtani haladványt alkotnak-e. Ezt a függvényt használjuk arra, hogy eldöntsük, hogy az x1, x2, ..., xn, n>1, számok számtani haladványt alkotnak-e. A számokat az „input.dat” file-ból olvasunk be.
5. Írjunk egy „mhal(a,b,c)” függvényt, amelyik ellenőrzi, hogy az a, b és c számok mértani haladványt alkotnak-e. Ezt a függvényt használjuk arra, hogy eldöntsük, hogy az x1, x2, ..., xn, n>1, számok mértani haladványt alkotnak-e. A számokat az „input.dat” file-ból olvasunk be.
6. Írjunk egy „teszt(k)” függvényt, amelyik ellenőrzi, hogy az k természetes szám megegyezik-e azzal a számmal, amit a számjegyek fordított sorrendben történő felírásával kapunk. Ezt a függvényt használjuk arra, hogy megszámoljuk, az x1, x2, ..., xn, n>1, természetes számok közül hány rendelkezik ezzel a tulajdonsággal. A számokat az „input.dat” file-ból olvasunk be.
7. Írjunk egy „tokeletes(k)” függvényt, amelyik ellenőrzi, hogy a k természetes szám tökéletes szám-e, azaz osztóinak összege (önmagát nem beleszámítva) megegyezik-e a számmal, pl. 6=1+2+3. Ezt a függvényt használjuk arra, hogy megszámoljuk, az x1, x2, ..., xn, n>1, természetes számok közül hány tökéletes szám. A számokat az „input.dat” file-ból olvasunk be.
8. Írjunk egy „enorma(x,n)” függvényt, amelyik kiszámítja az x = (xi), i = 1, ..., n vektor elemeinek euklideszi normáját (a vektor elemei négyzetösszegének a négyzetgyöke). Ezt a függvényt használjuk k vektor normájának kiszámítására. A vektorokat az „input.dat” file-ból olvassuk be, az eredményt pedig, a bemenő adatokkal együtt az „output.dat” file-ba írjuk.
9. Írjunk egy „tavolsag(x,y,n)” függvényt, amelyik kiszámítja az x = (xi) és y = (yi), i = 1, ..., n vektorok euklideszi távolságát (a vektorok azonos rangú elemei különbsége négyzetösszegének a négyzetgyöke). Ezt a függvényt használjuk 2 vektor távolságának kiszámítására. A vektorokat az „input.dat” file-ból olvassuk be, az eredményt pedig, a bemenő adatokkal együtt az „output.dat” file-ba írjuk.
10. Írjunk egy „csere(x,n,m)” függvényt ( m < n természetes számok), amelyik az x = (xi), i = 1, ..., n vektor utolsó n - m elemét a vektor elejére, az első m elemet pedig a vektor végére viszi. Ezt a függvényt használjuk k vektor feldolgozására. A vektorokat az „input.dat” file-ból olvassuk be, az eredményt pedig, a bemenő adatokkal együtt az „output.dat” file-ba írjuk.
11. Írjunk egy „min(n,x,k)” függvényt ( k <= n természetes számok), amelyik megkeresi az x = (xi), i = 1, ..., n számsorozat első k elemének minimumát. Ezt a függvényt használjuk az y = (yi), yi = min(n,x,i), i = 1, ..., n számsorozat meghatározására. A számsorozatot az „input.dat” file-ból olvassuk be, az eredményt pedig az „output.dat” file-ba írjuk.
12. Írjunk egy „osszeg(n,x,k)” függvényt ( k <= n természetes számok), amelyik kiszámítja az x = (xi), i = 1, ..., n számsorozat első k eleme négyzetének összegét. Ezt a függvényt használjuk az y = (yi), yi = osszeg(n,x,i), i = 1, ..., n számsorozat meghatározására. A számsorozatot az „input.dat” file-ból olvassuk be, az eredményt pedig az „output.dat” file-ba írjuk.
13. Írjunk egy „egyesit(A,B,C,n,m,k)” függvényt, amelyik meghatározza a C=A U B halmaz elemeit, ahol A = {a1, a2, ..., an}és B = {b1, b2, ..., bm} valós számhalmazok.. Ezt a függvényt használjuk az R = A1 U A2 U ... U Ap halmaz elemeinek meghatározására. A halmazokat az „input.dat” file-ból olvassuk be, az eredményt pedig a bemenő adatokkal együtt az „output.dat” file-ba írjuk.
14. Írjunk egy „csere(A,n,m,i,k)” függvényt, amelyik felcseréli az A = (aij , i = 1, ..., n, j = 1, ..., m) mátrix i-edik és k-adik sorát. Ezt a függvényt használjuk egy B mátrix sorainak a felcserélésére úgy, hogy az első oszlop elemei növekvő sorrendben legyenek. A mátrixot az „input.dat” file-ból olvassuk be, az eredményt pedig, a bemenő adatokkal együtt az „output.dat” file-ba írjuk.
15. Írjunk egy „segit(A,n,m,i,k)” függvényt, amelyik az A = (aij
, i
= 1, ..., n, j = 1, ..., m) mátrix i-edik sorában és
k-adik oszlopában levő elem helyére a 0-tól különböző szomszédainak
számtani középarányosát írja, ha ez az elem 0 . Ezt a függvényt
használjuk egy B mátrix minden 0 értékű elemének módosítására. A B mátrix
elemei valósak és legyen minden 0 elemének legalább két 0-tól különböző eleme. A
mátrixot az „input.dat”
file-ból olvassuk be, az eredményt pedig, a bemenő adatokkal együtt az „output.dat”
file-ba írjuk.
1. A programokat C-ben írjuk, és legalább 2 C modulból kell álljanak.
2. A deklarációkat egy .h header file-ban kell megadni.
3. Minden feladathoz meg kell írni a makefile-t is.
4. A végrehajtandó állomány neve kötelezően „p”.
5. Az „input.dat” és „output.dat” szöveges file-ok.
6. Teszteléshez a következő script-et használom:
rm -IR *
cp ../input$1.dat input.dat
tar -xzf $2
make
./p
more output.dat
ahol $1 a feladat száma, $2 a .gz filenév. Amennyiben a linux-on futtatva hibajelzést kapok a feladatot „???”-lel utasítom vissza.