1 / 77

Programozási Nyelvek (C++) Gyakorlat Gyak 01.

Programozási Nyelvek (C++) Gyakorlat Gyak 01. Török Márk tmark @ caesar.elte.hu D-2.620. Jelmagyarázat. Elméleti vizsgán lesz! Interjúkérdés lehet Haladó C++ -n kifejtve!. Tartalom. Hello Világ! Fordítás, futtatás, debuggolás Interpretált vs bájtkód, fordítás Névtér printf vs cout

lucien
Télécharger la présentation

Programozási Nyelvek (C++) Gyakorlat Gyak 01.

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programozási Nyelvek (C++) GyakorlatGyak 01. Török Márk tmark@caesar.elte.hu D-2.620

  2. Jelmagyarázat • Elméleti vizsgán lesz! • Interjúkérdés lehet • Haladó C++-n kifejtve!

  3. Tartalom • Hello Világ! • Fordítás, futtatás, debuggolás • Interpretált vs bájtkód, fordítás • Névtér • printfvscout • Fejállományok • Streamek

  4. Tartalom – Hello Világ • C vs C++ • Különbségek, okai • Egyszerűsítés (?) • Mi az a belépési pont? • Mikor van vége? • stdio, stdlib

  5. Hello Világ (C) • Példa 1 : #include <stdio.h> /* * Több soros komment */ int main() { printf("Hello World\n"); return0; // egy soros komment }

  6. Hello Világ (C) • Példa 2 : #include <stdio.h> #include <stdlib.h> /* * Több soros komment */ int main() { printf("Hello World\n"); system("pause"); return0; // egy soros komment }

  7. Hello Világ (C) – Fordítás • $ gccmain.c • $ ls main.c, a.out (ez futtatható) • $ ./a.outHello Világ! • $ gccmain.c-o main$ ls main.c, main (ez futtatható) • $ ./mainHello Világ! • $

  8. Hello Világ (C++) #include <iostream> /* * Komment maradt a régi */ int main() { std::cout <<"Hello World\n"<< std::endl; }

  9. Hello Világ (C++) • Kiiratáshoz: • std::ostream::operator<< • Hol van az ostreaminclude? • include-oltuk az iostream-et. • Az iostream-en belüli include-ok: • istream, ostream, …

  10. Hello Világ (C++) – Fordítás • $ g++ main.cpp • $ ls main.cpp, a.out(ez futtatható) • $ ./a.outHello Világ! • $ g++ main.cpp-o main$ ls main.cpp, main(ez futtatható) • $ ./mainHello Világ! • $

  11. Hello Világ – C vs C++ • C : procedurális, strukturálisC++: objektumorientált paradigmával bővítve (később) • stdio.h iostream • printf  std::cout • A változások okai az objektumorientált programozási paradigmák követése, új könyvtárak, állományok implementálása • Belépési pont: • int main() vagy • int main(intargc, char* argv[]) vagy • int main(intargc, char** argv)

  12. Hello Világ – C vs C++ • ISO C++ standard 3.6.1 (mind a kettő helyes) • void main(/*…*/) { … } • Error: main must return int • main(/*…*/) { … } • Fordul, szép, jó és fut! • Kilépési pont, visszatérési érték típusa mindig int. • Visszatérés legyen 0! Minden más érték a hibáké! • C++ esetében: • Nem kötelező megadni visszatérési értéket • main() esetében ez mindig 0 lesz! • Más esetén egy memóriaszemét.

  13. Hello Világ – stdio.h • CStandardInput and Output Library • C-ben stdio.h • C++ cstdio • Az input-output műveletekért felelős • macrok, típusok, függvények, konstansok • Billentyűzet, nyomtató, egyéb perifériaeszközök • stream: lehetőséget biztosít ezek írására, olvasására. • stdin, stdout, stderr(később)

  14. Hello Világ – stdlib.h • C Standard General Utilities Library • Memóriahasználathoz szükséges metódusok • calloc, malloc, realloc, free • Véletlenszám generálás • Környezettel kommunikáló metódusok: • exit, system, … • Konverzió • Keresés, rendezés • ...

  15. Fordítás, futtatás, debuggolás • Ahogy már láttuk: • $ g++ main.cpp-o main • $ ./main • Parancssori paraméterekkel • $ ./main param1 param2 • argv[0] maga a futtatható állomány; argv[1], ... a tényleges paraméterek • Hibákat irassuk ki: • $ g++ -Wallmain.cpp-o main • Error, warning • Hiba kiírása: • fájlnév:sor száma:hibaüzenet

  16. Fordítás, futtatás, debuggolás • printf – formatspecifiers • int a = 9; int b = 10; int c = 100; • printf("%d|%d|%d\n", a, b, c);// 9|10|100 • printf("%3d|%3d|%2d\n", a, b, c);// 9| 10|100 • printf("%03d|%03d|%02d\n", a, b, c);// 009|010|100

  17. Fordítás, futtatás, debuggolás • Nézzünk egy példát:#include <iostream>boolf() {}intmain() {std::cout << f();}

  18. Fordítás, futtatás, debuggolás • $ g++ main.cpp-Wall-o mainmain.cpp: In function ‘bool f()’:main.cpp:4: warning: control reaches end of non-void function

  19. Fordítás, futtatás, debuggolás • Nézzünk egy példát:#include <cstdio>intmain() {printf("%f", 99);} • $ g++ main.cpp -Wall -o mainmain.cpp: In function ‘int main()’:main.cpp:8: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’

  20. Fordítás, futtatás, debuggolás • Több állomány fordítása: voidsayhello (constchar* name);// hello.h #include <stdio.h>// hello.c#include "hello.h”voidsayhello(constchar* name) {printf ("hello, %s", name);} #include "hello.h” // main.cintmain() {sayhello ("world");return0;}

  21. Fordítás, futtatás, debuggolás • $ gcc-Wallmain.chello.c-ohmain • Header: • Két féle include-olást különböztetünk meg. • #include <fájl.h>: systemheader fájlok között nézi meg.(linuxon: /usr/include/stdio.h) • #include ”fájl.h”: a lokális mappában keres, majd a systemheaderek között.

  22. Fordítás, futtatás, debuggolás • Fordítás lépései: • Forrásból object: először nem is futtatható fájl keletkezik, hanem egy object. Ennek kiterjesztése .o. • A második lépés a linkelés: a linker az objectfájlok összefésülését végzi függőségek szerint. Ebből lesz a futtatható állomány. • Csak fordítás -c kapcsolóval:$ gcc-Wall-cmain.c • Eredmény egy main.o, mely a főprogramunk gépi kódját tartalmazza. • $ gccmain.o-o main

  23. Fordítás, futtatás, debuggolás • Külső könyvtárakból: • Archive állományok, kiterjesztése: .a // statikus könyvtárak • Matematikai függvények Math.h-ban, implementációja viszont a libm.a könyvtárban (fordított állomány!). • $ gcc-Wallcalc.c /usr/lib/libm.a-ocalc • Kapcsoló: elkerülhető a hosszú elérésiút:$ gcc-Wallcalc.c-lm-ocalc • Ez annyit jelent, hogy lm = libm.a • Elmondható, hogy lNAME = libNAME

  24. Fordítás, futtatás, debuggolás • Library-k: • Staticlibrary és sharedlibrary (dynamic) • Staticlibrary kiterjesztése: .a • A linkelést követően a használt függvény gépi kódja a library-ból bemásolódik a futtatható állományba. • Sharedlibrary kiterjesztése: .so • Dinamikus kötés (dynamic linking): a sharedlibrary táblázatot tartalmaz hivatkozással az egyes függvényekre. • Fordításkor a linker egy ilyen hivatkozást rak be a futtatható állományba, a teljes gépi kód helyett. A futtatáskor a gépi kód bemásolódik a memóriába a megadott hivatkozás alapján.

  25. Fordítás, futtatás, debuggolás • -Wall kapcsoló: • -Wreturn-type: figyelmeztet, hogy az adott függvény definíció szerint kér visszatérési értéket (azaz nem void), de ezt az implementációjában nem tettük meg. • -Wformat: hibás formatstring a printf, scanf függvényekben. Eltér a format a paraméter típusától. • -Wunused: figyelmeztet, ha használatlan változók vannak a kódban. • -Wimplicite: ha előzőleg nem adtuk meg a függvény specifikációját.

  26. Fordítás, futtatás, debuggolás • Preprocesszor: • A fordító által meghívott, a tényleges fordítás előtt lefutó program. • Mit csinál? Kezeli az alábbi direktívákra: • #include : forrásmegjelölés • #define: macro definiálása • #if: feltételes forrásbetöltés, macrodefiniálás

  27. Fordítás, futtatás, debuggolás • Macro-k: • C-ben fontosabb, C++-ban kevésbé fontos szerepet töltenek be. • Ha tehetjük, akkor kerüljük őket. (Nagyon erősen ajánlott!) • Mivel a fordítóprogram futása előtt a macro-k meghívásra kerülnek, és belenyúlnak a kódba, nem ajánlatos használni őket.Csökken a hatékonysága azon eszközöknek, melyekkel a programunk hatékonyságát, biztonságát tudjuk mérni.Pl.: hibakeresők, kereszthivatkozás-vizsgálók.

  28. Fordítás, futtatás, debuggolás • Macro-k: • #define CSERELD_EZT erre • csere = CSERELD_EZT • A macro lefutását követően az eredmény ez lesz:csere = erre • #define SQUARE(a) a*a • Ebből:int b = 0;int i = SQUARE(b + 2); • Igen ám! De ebből: b + 2*b + 2 => 3b + 2 lesz!

  29. Fordítás, futtatás, debuggolás • Macro-k: • Feltétel:…#ifdef AAA printf(”ez az ág lefutott!”);#endif… • Fordítás: $ gcc -Wall -DAAA main.c • A -D kapcsoló prefixe az adott AAA nevű macro-nak.Így tudunk a macro-nak értéket is adni. • Nyilván ha ezt a kapcsolót kihagyjuk, az adott ág lefutása is elmarad.

  30. Fordítás, futtatás, debuggolás • Debuggoláshoz: • Fordítsunk a -g kapcsolóval. • Hogy miért? Amikor a programunk abnormális futást produkál (elszáll menetközben), az operációs rendszer elmenti a program memóriabeli állapotát egy core nevű fájlba. • Nézzük meg, hogy mi van a core fájlba.

  31. Fordítás, futtatás, debuggolás • Töltsük be a core fájlt a GNU Debuggerbe az alábbi módon: • $ gdb futtatható-állomány core-állomány • Csak együtt tudjuk őket használni, külön nem tudjuk betölteni a core-állományt. • $ gdb a.out coreCore was generated by ‘./a.out’.Program terminated with signal 11, Segmentation fault.Reading symbols from /lib/libc.so.6...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...done.Loaded symbols for /lib/ld-linux.so.2#0 0x080483ed in a (p=0x0) at null.c:1313 int y = *p;(gdb)

  32. Fordítás, futtatás, debuggolás • Debuggolás: • Stack backtrace kilistázása: • (gdb) backtrace • Kilistázza a hívási listát.

  33. Interpretált vs bájtkód, fordítás • C++-forráskód lefordításával hagyományos natív kódot kapunk. A natív kód a processzornak megfelelő módon lefordított gépi kód. • Ha natív C++-alkalmazásunkat több különböző környezetben (32bites, 64bites platformon) is szeretnénk futtatni, akkor külön le kell fordítanunk.

  34. Interpretált vs bájtkód, fordítás • Hogy megy ez máshol? • C# kód fordításával (interpretálásával) kezelt kódot kapunk. Ez egy közbenső nyelv (intermediatelanguage, IL). A magas szintű (C#) és a legalacsonyabb szintű nyelv (assem., gépi kód) között helyezkedik el. • A közös nyelvű futási idejű környezet (CommonLanguageRuntime, CLR) futási időben, menet közben fordítja le a kódot a Just-in-time (JIT) fordító alkalmazásával.

  35. Interpretált vs bájtkód, fordítás • Mit csinál a JIT fordító? • Nem túl hatékony a kódot futásidőben fordítani? • A JIT-fordító nem fordít le egy adott metódust vagy függvényt annak minden egyes meghívásakor, ezt csak az első esetben teszi meg, és ekkor a platformnak megfelelő gépi kódot állít elő. • Használatával csökken az alkalmazás munkahalmaza, a közbenső kód munkaigénye kisebb lesz.

  36. Interpretált vs bájtkód, fordítás • Hogy megy ez Java-ban? • A forrásfájlokban (.java) definiált minden egyes típus interpretálásának eredményeként külön létrejövő típusnév.class fájl tartalmazza a végrehajtható bináris bájtkódot. • A hordozható bájtkódot interpretálás helyett, közvetlenül futtatás előtt platformfüggő gépi kódra fordítja át, mely kód sokkal gyorsabban fut majd, mint a bájtkód interpretálása. • Előnye, a biztonság és a hordozhatóság, hátránya, hogy néhol lassú.

  37. Interpretált vs bájtkód, fordítás • Jittelés Java-ban: • A gyorsabb futás érdekében dinamikus fordítási technika használata: JIT (Just-in-time compiler). • Minden osztály bájtkódjának betöltése után az egész osztály bájtkódját lefordítja gépi kódra. (A további használatban a kód már nem interpretált.) • Előny: többszörösen is gyorsabb lehet a Java kód végrehajtása, viszont egy osztály bájtkódjának (vagy egy metódus végrehajtása) betöltési ideje növekszik.

  38. Fejállományok • Azaz a header-ök! • Lehetővé teszik a kód elkülönítését. • Tartalma: forwarddeclaration (forwardreference) • Osztályok: classClazz; • Alprogramok: voidget(Clazz&clazz); • Váltózókat: hivatkozhatsz egy változóra, mielőtt definiálnád. classClazz{public: intget() { returnvalue; }private: intvalue;} • Egyéb azonosítók.

  39. Fejállományok • Programok kisebb részekre bontása • Osztályokra • Alprogramokra • Definiálása: • #define … • Használata: • #include <fajl.h> • #include ”fajl.h”

  40. Fejállományok • A többszörös include-ok: • Több fejállományt include-oltunk, melyek között van olyan, mely include-ol egy másikat. • Így akár egy fejállomány kétszer vagy többször is include-olásra kerülhet. • A fordítás tovább tart, mert lesznek állományok, melyek többször kerülnek feldolgozásra. • Hatalmasra nő a szemantikus gráfunk. • Ezek megelőzésére: • includeguardok

  41. Fejállományok • Includeguard: • #ifndef, azaz ha még nincs definiálva • #define, akkor definiáljuk • … jön a kód • #endif lezárom az if-et • Más: • #pragma once

  42. Fejállományok • Egyéb kulcsszavak: • #ifdef • #if • #elif • #else

  43. Fejállományok • Nézzük meg, hogy épül fel: // get.h #include<vector>#ifndefGET_H_GUARD #defineGET_H_GUARD voidget(int a); vector<int> getAll(int a);#endif

  44. Fejállományok // a masikallomany #include<vector> #include”get.h”int f() { vector<int> getAll(5);returnget(10);}

  45. Névtér • Programok tagolásának egy eszköze • Mindig valamilyen logikai csoportosítást fejeznek ki. (Egyes deklarációk valamilyen jellemzői alapján összetartoznak.) • Külön hatókört alkotnak • Másik névtérből származó osztályt a névtér nevének minősítésével tudjuk elérni. • namespace kulcsszó. • Konvenció szerint : lowelCamelCase • Legismertebb, legtöbbet használt (a félév során!): std

  46. Névtér • std: • C++ Standard Library • Osztályok és függvények gyüjteménye • Containers (array, list, map,…) • General (algorithm, memory, iterator,…) • Streams • …

  47. Névtér • Más nyelveknél: • Java: package • Itt láthatósági módosító is van! • C++-ben nincs • Ada: csomag • Félúton az osztály és a namespace fogalma között. • Működhet úgy is, mint egy C++-snamespace. • C#: namespace • Még fejlettebb láthatóságikör

  48. Névtér • Példa névtér definiálására: // a.h namespaceNS { classA { // functions… } int f(char a) { // … } }

  49. Névtér • Fordítás:$ g++ a.h-c • -c kapcsoló: • Csak fordít, de nem keres main belépési pontot. • -c kapcsoló nélkül fordítási hiba!

  50. Névtér • Használata: • :: operator • NS:: az NS névtérben lévő neveket (fgv, osztály, …) akarjuk használni

More Related