C++ előadás és gyakorlat

Kitlei Róbert

2008/2009 tavaszi félév

Bevezetés

A tárgy célja

Kapcsolat

Követelmények

Eredet

Történet

Bjarne Stroustrup

Kapcsolódó nyelvek

Milyen egy jó programnyelv?

Miért érdemes C++-t tanulni?

Miért érdemes C++-t tanulni?

tiobe

Trendek a tiobe.com oldalon: Java, C, C++, Visual Basic, PHP, C#, Python, Perl, Delphi, JavaScript

Mit nem tartalmaz a C++?

Tervezési szempontok

Ajánlott irodalom

Interpreter és fordítóprogram

Előnyök, hátrányok

Virtuális gép (virtual machine)

A program lefordítása

Előfordító

#include <iostream>
#include "sajat.h"

Előfordító

// sajat.h tartalma

#ifndef __SAJAT_H_
#define __SAJAT_H_

// sajat.h érdemi tartalma

#endif

Előfordító

A fordítás menete

g++ verem.cpp verem.h -c    ⇒   verem.o
g++ verem.o foprogram.cpp ⇒ a.out

A fordítás menete

Fordítási idő

A fordítás menete

Szerkesztési idő

Futási idő (runtime): az az idő, amikor a program utasításainak végrehajtása folyik

Szerkesztés

Szerkesztés

A g++ fordítóprogram

További fejlesztői eszközök

A program futtatása

  1. a program betöltődik a memóriába
    • nem biztos, hogy fordításkor ismert, hová töltődik be
  2. relatív címek feloldása (relokáció): a programkód betöltési címtől függő részeinek frissítése
  3. tényleges programvégrehajtás
    • virtuális gép: előtte ellenőrzi a betöltött kódot
    • a main függvény indul el

A program futásának vége

Szintaxis és szemantika

A szabályok ellenőrzése

Lexikai szerkezet

Lexikai szerkezet: a programszöveg alapelemeit írja le

Ábécé

Azonosítók

Azonosítók

Számok

Egész számok

Lebegőpontos számok

Karakterek, szövegek

Karakterek

Literálok

Pontosvessző

struct S
{
int f() { return i; }
int i;
};

Tördelés (indentation)

if (i > 0)
j = i;
// ha ide is kerül egy utasítás,
// az a feltételtől függetlenül végrehajtódik

Megjegyzések vagy kommentek (comment)

Operátorok

int i = *p/*q;
int i = *p / *q;
int f(char*=0);     // *=
int f(char* = 0);

Adattípus szerepe

2 / "abc"

Nyelv típusozása

Nyelvek típusozási lehetőségei

Nyelv típusozása

Nyelv típusozása

Példák nyelvekre

statikusdinamikus
erősC++, Java, HaskellErlang
gyengeC, PHPassembly

Adattípus

Adattípus szerepe

Adattípusok csoportosítása

Adattípusok csoportosítása

Felhasználói típusok: a típus értékeinek szerkezetét a felhasználó határozza meg

Beépített típusok: a nyelv által bevezetett típusok

Void

Skalár típusok műveletei

Skalár típusok műveletei

Skalár típusok műveletei

A bitműveletek igazságtáblái

x & y01
000
101
x | y01
001
111
x ^ y01
001
110

Skalár típusok műveletei

Példák a bonyolultabb műveletekre

100 /  333
100 % 31
1 << 532
100 >> 312
12 & 108
12 | 1014
12 ^ 106
  1100          1100          1100
  1010          1010          1010
& ----        | ----        ^ ----
  1000 ⇒ 8      1110 ⇒ 14     0110 ⇒ 6

Skalár típusok műveletei

++i     // i változó értéke megnő eggyel
// a művelet értéke: i + 1
i++     // i változó értéke megnő eggyel
// a művelet értéke: i

Egész (integer)

int i;

unsigned u;
unsigned int ui;
// ugyanaz a típus

Logikai típus (Boolean)

1 + (2 && 3)    // sok nyelven hibás, C++ nyelven nem

Karakter (character)

Lebegőpontos (floating point)

float f = -1.34f;

Felsorolási típus (enumeration)

enum { A, B, C, D, E };
enum Abece { A, B = 3, C, D, E };
enum Abece { A, B = 3, C, D = 2, E };
int i = D;

Mutató (pointer)

Mutató (pointer)

int*

Mutató (pointer)

int i = 3;
int j;
int* pi;

pi = &i; // objektum címének képzése
// most: pi i-re mutat

j = *pi; // mutató feloldása
// most: j felveszi i értékét

Konstans mutató

int i, j;

const int* pi1 = &i;
// a mutatott érték a konstans:
// *pi1 nem állítható

int*const pi2 = &i;
// a mutató a konstans: pi2 nem állítható át

*pi1 = 3; // helytelen
*pi2 = 3;

pi1 = &j;
pi2 = &j; // helytelen

Tömb (array)

int ai[3] = { 1, 2, 3 };
int bi[] = { 4, 5, 6, 7 };
// bi hossza: 4
// automatikusan állapítódik meg
int c = ai[2];
// ai tömb harmadik eleme, 3

Tömb (array)

int aa[3];
aa = { 1, 2, 3 }; // helytelen
int a1[6] = { -1, -2, -3 };
int a2[6] = { -1, -2, -3, 0, 0, 0 };
// megegyezik a tartalmuk

Tömb (array)

int ai[3] = { 1, 2, 3 };
int bi[] = { 4, 5, 6, 7 };
bi[5] = 8;
// futás közben nem biztos, hogy kiderül
// lehet, hogy ai első elemét módosítja

Tömb (array)

char ai[] = { 'a', 'b', 'c' };
char* b = ai; // ai[0]-ra mutat
char ai[] = { 'a', 'b', 'c' };
char bi[] = { 'a', 'b', 'c' };

ai == bi ⇒ false

Tömb (array)

int ai[3][2] = { { 1, 2 }, {3, 4}, {5, 6} };
int a0[] = {1,2};
int a1[] = {3,4,5};
int* a[2] = { a0, a1 };
// elérhető elemek:
// a[0][0], a[0][1]
// a[1][0], a[1][1], a[1][2]

Tömb (array)

C sztringek

char s[] = "abc";

Tömb (array)

char s1[] = "abc";
char s2[] = { 'a', 'b', 'c', 0 };
char s3[] = { 'a', 'b', 'c', '\0' };
// mindegyik tömb tartalma azonos
// mindegyik hossza 4

char s4[] = { 'a', 'b', 'c', 0, 'd', 'e' };
// C sztringként értemezve azonos az előzőekkel
// hossza 6

char* s5 = "abc";
// megengedett, de a tartalma nem módosítható

char ures[1] = "";

Tömb (array)

Tömbök és mutatók deklarációjának értelmezése

int **a[2][3][4];
int** (((a[2])[3])[4]);
// kételemű tömb,
// amely három elemű tömböket tartalmaz,
// amelyek négyelemű tömböket tartalmaznak,
// amelyek kétszeres indirekción keresztül
// egész számokra mutatnak
int b[][3] = { {0,1,2}, {10,11,12} };

Tömb (array)

Mutató-aritmetika

Tömb (array)

Mutató-aritmetika

Tömb (array)

Hasznos típusok a tömb kiváltására a sztenderd könyvtárból

Tulajdonságaik

Hivatkozás (referencia)

int i;
int& ri = i;

Hivatkozás (referencia)

Típus mérete

1 == sizeof(char)
1 <= sizeof(FelsorolásiTípus) <= sizeof(int)
2 <= sizeof(short) <= sizeof(int) <= sizeof(long)
4 <= sizeof(long)
sizeof(float) <= sizeof(double) <= sizeof(long double)

Áltípus (typedef)

typedef int suly;
typedef const char* szovegtomb[100];

Típuskonverzió (cast, type conversion)

Típuskonverzió (cast, type conversion)

double d = 13;
int i = 13.6;

Deklaráció

Deklaráció láthatósága

void f(int, int);
void f(double, double);

Deklaráció láthatósága

Névelfedés: azonosító bevezetése vele azonos nevű deklaráció hatókörében

::x = 1;

Deklaráció láthatósága

{
int x; // x hatókörének kezdete
{
x = 1; // az első x változik
int x; // hatókör kezdete
x = 2; // a második x változik
// a blokk végéig az első x nem látható
} // a második x hatókörének vége
} // az első x hatókörének vége

Deklaráció láthatósága

int f(int x)
{
{
int x = 1;
}

return x; // az eredeti x az eredmény
}

Deklarációk és szerkesztés

Szerkesztési osztály (linkage): meghatározza, hogy melyik fordítási egységekre terjed ki a deklaráció hatóköre

Deklarációk és szerkesztés

Szerkesztési osztály (linkage)

Objektum élettartama

Élettartam (extent, lifetime): az objektum lefoglalása és felszabadítása közötti időtartam

Objektum élettartama

Élettartam

Deklaráció szerkezete

deklarátor-operátorszerkezet
mutató*név
konstans mutató*const név
referencia&név
tömbnév[]
függvénynév(paraméterek)

Deklaráció szerkezete

const int i = 3;
int const j = 6;
const extern int*const bonyolult[3];

Deklaráció szerkezete

int i = 1, j = 2;
int j, *p, **pp;
int j;
int* p;
int** pp;

Deklaráció szerkezete

const int* pi1 = ...;
// pi átállítható
// *pi nem kaphat értéket
int*const pi2;
// pi mindig ugyanoda mutat
// *pi értékét meg lehet változtatni
const int*const pi3 = ...;
// pi nem állítható, és *pi értéke sem