Kihagyás

4. gyakorlat

A gyakorlat anyaga

Parancssori paraméterek

Parancssori paraméterek használata parancssorból, java-val való futtatásnál:

java ProgramNeve param1 param2 param3...

Parancssori paraméterek beállítása különböző fejlesztőkörnyezetekben:

  • Eclipseben: A fordítás és futtatást jelző zöld háromszög (Play) ikon melletti lenyíló menüben Run Configurations, majd pedig itt az Arguments fül alatt adhatjuk meg a parancssori paramétereket.
  • IntelliJ IDEA: Először is létre kell hozni egy konfigurációt, amit a legegyszerűbben úgy tudunk megtenni, hogy a main függvény sorában jobb klikk, és Run 'Fájlnév.main()'. Ezt követően valahol jobb felül lesz a zöld háromszög (Play) ikon, ami mellett található a konfiguráció (ez egy lenyitható választó). Erre kattintva Edit configurations, majd pedig a Program arguments részen írhatjuk be a parancssori paramétereket.

Tömb bejárása a tömb length (hossz, vagyis elemszám) tulajdonságát felhasználva: (Természetesen nem csak a parancssori paraméterek tömbjének, hanem bármely tömbnek lekérhetjük az elemszámát a length tulajdonsággal.)

1
2
3
4
// parameterek bejarasa
for (int i=0; i<args.length; i++) {
    System.out.println("" + (i + 1) + ". parameter: " + args[i]);
}

Paraméterek összege

A main függvény egy String tömböt kap, ezt semmilyen módon sem lehet felülírni. Ha számokként akarjuk kezelni a kapott paramétereket, akkor a tömb egyes elemeit először át kell konvertálnunk számmá, amihez az Integer.parseInt() függvényt kell használnunk.

1
2
3
4
5
6
7
// parameterek osszege
int osszeg = 0;
for (int i = 0; i < args.length; i++) {
    osszeg += Integer.parseInt(args[i]);
}

System.out.println("A parameterek osszege: " + osszeg);

Adattípusok

Egyszerű (primitív) adattípusok: boolean, char, byte, short, int, long, float, double, ezek nagy része ismerős lehet C-ből. A C-vel ellentétben Javaban nyelvi szinten támogatva van a logikai adattípus, amelyet boolean típusnak nevezünk, és értéke csak true vagy false lehet. További eltérés a C-hez képest, hogy Javaban nincs előjeltelen típus, tehát nem használhatjuk az unsigned kulcsszót, csak és kizárólag előjeles típusokat hozhatunk létre. Bővebben ezen a linken olvashatsz a primitív adattípusokról. Egy érdekes cikk a lebegőpontos számokról, számábrázolásról.

Megjegyzés

Ha valami miatt azonban mégis szükség lenne egy előjeltelen egészre, akkor Java 8 (vagy újabb verzió) esetén használhatjuk az Integer osztály néhány erre a célra létrehozott metódusát, mint például a compareUnsigned, divideUnsigned metódusokat.

Az alábbiak hasznát csak később fogjuk megérteni. Alapvetően minden Java-beli primitív típusnak létezik egy csomagoló osztálya, amellyel egy primitív típusú adatból objektumot készíthetünk, "becsomagolhatjuk" azt. A csomagoló (wrapper) osztályok a következők (sorrendjük megegyezik a primitív típusoknál történt felsorolás sorrendjével): Boolean, Character, Integer, Long, Float, Double. Egy összefoglaló táblázat a beépített típusokról:

Típus neve Érték Default érték Méret Értéktartomány
boolean 1 bitet reprezentál false nincs precíz definíció true/false
char 16 bites unicode karakter \u0000 2 byte 0 - 65535
byte 8 bites egész 0 1 byte -128 - 127
short 16 bites egész 0 2 byte -32768 - 32767
int 32 bites egész 0 4 byte -2147483648 - 2147483647
long 64 bites egész 0L 8 byte -9223372036854775808 -,9223372036854775807
float 32 bites lebegőpontos (IEEE 754) 0.0f 4 byte 1.40129846432481707e-45 - 3.40282346638528860e38 (pozitív vagy negatív), +/- végtelen, +/- 0, NaN
double 64 bites lebegőpontos (IEEE 754) 0.0d 8 byte 4.94065645841246544e-324d - 1.79769313486231570e+308d (pozitív vagy negatív), +/- végtelen, +/- 0, NaN
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class PrimitivTipusok {

    public static void main(String[] args) {
    boolean bo = true; // logikai tipus
    char c1 = 'a'; // karakter tipus
    char c2 = '\u0054'; // ket bajtos, unicode karaktereket tarol!
    byte b1 = 127; // 8 bites egesz tipus
    byte b2 = -128; // minden egesz tipus elojeles!
    short s = 1024; // 16 bites egesz
    int i = 0x7fffffff; // 32 bites egesz
    long l = 0x7fffffffffffffffL; // 64 bites egesz
    float f = 123.123f; // 32 bites lebegopontos tipus
    double d = 5.0; // 64 bites lebegopontos

    // kiiras konzolra
    System.out.println(bo);
    System.out.println(c1);
    System.out.println(c2);
    System.out.println(b1);
    System.out.println(b2);
    System.out.println(s);
    System.out.println(i);
    System.out.println(l);
    System.out.println(f);
    System.out.println(d);
    }
}

A lebegőpontos számokkal azonban óvatosan kell bánni. Erre egy tökéletes példa a Süti program. A történet a következő: ellátogatunk az Egyesült Államokba, de sajnos hamarosan indulunk is tovább, így csak a reptéri cukrászdában vásárolhatunk sütit. A sietségünket azonban kihasználja a reptéri cukrász: elcsábít minket a konkurencia elől a 0.1 dolláros sütivel, azonban minden egyes következő sütiért 0.1 dollárral többet kér, mint amennyibe az előző került. Vajon hány sütit ehetünk a maradék 1 dollárunkból? Írjunk rá egy programot, mentsük el Suti.java néven.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class Suti {

    public static void main(String[] args) {
        double penzunk = 1.00;
        int megvettSutik = 0;
        for (double ar = 0.1; penzunk >= ar; ar += 0.1) {
            penzunk -= ar;
            ++megvettSutik;
        }
        System.out.println("Megvett sütik: " + megvettSutik);
        System.out.println("Megmaradt pénz: " + penzunk);
    }
}

Hm... valami nem stimmel. Számoljuk ki kézzel is, egy egyszerű táblázat segítségével:

Pénzünk Következő süti ára Megevett sütik száma
1.0 $ 0.1 $ 0
0.9 $ 0.2 $ 1
0.7 $ 0.3 $ 2
0.4 $ 0.4 $ 3
0.0 $ lényegtelen 4

A fenti példa alapján beláthatjuk, hogy például valuta tárolására sosem érdemes float vagy double típust választani. Bővebben erről a problémáról ezen és ezen linken.

String (szöveges) típus

String típus. A sztringeket az eddigiekkel szemben itt már szeretjük, kezelésük könnyű. Ezt a típust mindig nagy kezdőbetűvel írjuk, mivel ez igaziból nem primitív típus, ám sok esetben tudjuk úgy használni, mintha az lenne.

Operátorok

+, -, *, /, % operátorok és használatuk ugyanaz, mint C-ben.

A + jel sztringekre konkatenációt (összefűzést) jelöl. Használata nagyon intuitív. Például "kutya" + "mutya" -> "kutyamutya"

A C-beli pointereknél használt * (dereferencia) és & (címképzés) operátor itt nem létezik.

>> - aritmetikai eltolás: megőrzi az előjelbitet.

>>> - logikai eltolás: az előjelbitet is tolja. (Magyarán nem őrzi meg a szám negativitását)

Az operátorokról bővebben olvashatsz az alábbi linkeken: Summary of Operators, Java Operators Tutorial.

Gyors kiértékelés

A logikai && (és) és a || (vagy) operátorok gyors kiértékeléssel értékelődnek ki (short circuit evaluation). Ez annyit jelent, hogy a logikai kifejezés pontosan addig értékelődik ki, amíg egyértelműen el nem dől az értéke.

1
2
3
4
if (false && true) {}
if (false || true) {}
if (true && false) {}
if (true || false) {}

Az 1. sorban mivel az && (és) bal oldalán hamis érték áll, ezért a jobb oldali értéket felesleges megnézni, hiszen egy és értéke csak akkor igaz, ha a bal oldala és a jobb oldala is igaz. A 2. sorban lévő || (vagy) bal oldalán hamis érték áll, vagyis itt meg kell nézni a jobb oldalt is, hiszen egy vagy akkor igaz, ha vagy a bal, vagy a jobb oldala igaz. Ezzel szemben a 3. sorban lévő && esetén az és jobb oldalát is meg kell nézni, hiszen egy és értéke csak akkor igaz, ha mindkét oldala igaz. A 4. sorban viszont csak a || bal oldala alapján egyértelműen tudjuk, hogy az adott vagy kifejezés értéke igaz lesz, így felesleges a jobb oldalát is megnézni a vagy operátornak.

Ezek természetesen ugyanígy igazak több részkifejezés esetén is. Talán elsőre nem tűnik fontos dolognak, azonban a való életben sokszor optimalizálhatunk a kódunkon, ha jó sorrendben írjuk meg a logikai kifejezéseinket (például, ha egy és kifejezésünk van, akkor célszerű a bal oldalra tenni a gyorsabban kiértékelhető dolgokat, míg a jobb oldalra tenni az olyan kódot, ami kiértékelése időigényesebb lehet; konkrét példa: az és bal oldalán célszerűbb egy felhasználói inputot ellenőrizni, a kifejezés jobb oldalára pedig kerülhet mondjuk az a kód, ami interneten néz valaminek utána, vagy mondjuk egy adatbázisból olvas be adatot). Arról nem is beszélve, hogy futásidejű hibákat is megelőzhetünk, ha az if-en belüli logikai kifejezésünket jól írjuk meg.

Azonban figyelni kell, hiszen a && és & operátorok nem ugyanazok! Az első a logikai és, a másik pedig a bitenkénti. Természetesen boolean értékek esetén a két operátor ugyanúgy működik, kivéve a gyors kiértékelést! A bináris operátorok esetében mindig kiértékelődik mindkét oldala a bináris operátornak!

1
2
3
4
5
6
7
public static boolean hosszabMint(String input, int hossz) {
    return input != null && input.length() > hossz;
}

public static boolean hosszabMint2(String input, int hossz) {
    return input != null & input.length() > hossz;
}

A hosszabMint függvényben logikai és hajtódik végre, vagyis ha az input null, az és bal oldala kiértékelődik hamisra, és a jobb oldalt lefutásra sem kerül. Ezzel szemben a hosszabbMint2 függvény bináris műveletet hajt végre, azaz mindkét oldalt megvizsgálja, tehát ha az input null, akkor az és bal oldala hamisra értékelődik ki, majd megpróbálja a jobb oldali kifejezést is kiértékelni, de mivel az input változó null, ezért futásidejű hibát fogunk kapni.

Vezérlési szerkezetek

Majdnem minden működik, ami C-ben is működött, szóval aki idáig eljutott, ezeket már jól ismeri. A relációs operátorok is ugyanúgy működnek, mint C-ben, illetve a ++ és -- operátorok is ugyanúgy használhatóak.

Létezik tehát a már megszokott módon az if() és a ?: operátor is. Az if komplexebb feltételek megadására is alkalmas. Például ha azt szeretnénk, hogy egy x változó 3 és 7 között legyen, vagy 13, vagy negatív és nem -9, akkor ezt a következő kóddal adhatjuk meg:

1
2
3
if ((x >= 3 && x <= 7) || x == 13 || (x < 0 && x != -9)) {
    System.out.println("A feltétel teljesül.");
}

Logikai kifejezéseket összefűzhetünk az && (és) és a || (vagy) operátorok használatával. A zárójelezés ilyenkor kritikus fontosságú lehet.

Javaban minden logikai kifejezés egy boolean értékké értékelődik ki (vagyis vagy igaz, vagy hamis). Ha csak egy boolean értékünk/változónk van, az természetesen önmagában is igazságértéket jelképez, szükségtelen kiírni az == true részt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
boolean pozitiv = true;
if (pozitiv) {
    System.out.println("A szám pozitív.");
}
if (!pozitiv) {
    System.out.println("A szám nem pozitív.");
}
if (pozitiv == true) {
    // Szuksegtelen az == true resz, ugyanazt jelenti, mint a 2. sorban levo kod
}

A ?: operátor használata például a kiíráson belül lehet indokolt. Az előző kódot például jelentősen egyszerűsíti:

1
2
boolean pozitiv = true;
System.out.println("A szám " + ((pozitiv) ? "" : "nem ") + "pozitív.");

Viszont, C-vel ellentétben itt nincs implicit konverzió int és boolean között, a Java megköveteli az összehasonlító operátorok használatát ebben az esetben:

1
2
3
4
5
6
7
8
9
int x = 1;
if (x) { //Javaban ez így nem működik!
  System.out.println("Minden rendben!");
}

//A helyes feltétel az alábbi:
if (x > 0) {
  System.out.println("Minden rendben!");
}

A while, do-while és switch utasítás megegyezik a C-ben tanultakkal. A for utasításnál itt is kényelmesen deklarálható ciklusváltozó a for-on belül, ahogy azt C-ben is láttuk már (a ciklusváltozó deklarációja C-ben a C99 szabvány óta lehetséges ezen a módon). Ebben az esetben a cikluson kívül már nem látjuk a ciklusváltozót!

1
2
3
for (int i = 0; i < 5; i++) {
    //ciklus tartalma
}

Néhány dolog létezik azonban, amely nem működik Java-ban, de a C-ben igen, ezek egyike a goto utasítás. A program egyes részeit ugyanúgy címkézhetjük, azonban a goto parancsot nem használhatjuk. Ez Javaban ugyan foglalt kulcsszó, de implementáció nem tartozik hozzá. Ennek oka az, hogy az eredeti, első JVM-ben létezett a goto utasítás, és működött is (ezt James Gosling nyilatkozta, aki a JVM-et készítette). Azonban ezt nem sokkal utána ki is vették, mert nem igazán volt használva Javaban, és a nyelv készítői úgy látták, hogy C-ben is a legtöbben rosszul használják ezt az utasítást. Így a funkcionalitását kivették a goto utasításnak, de meghagyták foglalt kulcsszónak (reserved keyword), hiszen létezhetett olyan kód, amiben ez benne volt, illetve nem zárták ki annak sem a lehetőségét, hogy a jövőben szükség lehet rá, így azóta is foglalt kulcsszó a goto, de semmilyen mögöttes működése nincs. Hasonlóan foglalt kulcszó a C-beli const, aminek ugyanúgy nincs semmilyen működése.

Memóriaterületek

A következőkben röviden bemutatjuk a stacket, illetve a heapet, azonban ezek a témakörök az előadáson ennél jóval részletesebben be lettek mutatva. Bővebben olvashatunk a témáról a következő linkeken: JVM specifikáció ide vonatkozó részei

Stack

A stacken tároljuk a primitív típusú adatokat. Ez a memóriaterület nagyon gyors elérésű, általában lokális változókat, rövid életű adatokat tárolunk benne. A stacken létrehozott változók élettartalma a létrehozó blokkra korlátozódik, azaz pl.: ha van egy lokális változónk egy függvényben, akkor az a változó addig él, és addig lesz a memóriában tárolva, ameddig a függvény futása be nem fejeződik. Ezt követően a foglalt memóriaterület automatikusan felszabadul. Hátránya a heap memóriával szemben az, hogy a stack jóval kisebb. Javaban csak és kizárólag primitív típusú adatokat tárolhatunk a stacken (szám, bájt, karakter vagy logikai érték).

A gyakorlatban, ha egy változó értékét stacken tároljuk (pl.: int x = 42;), akkor akármikor hivatkozunk a változóra, a változó neve gyakorlatilag egyet jelent az értékkel, érték szerint tárolódik.

Heap

A heap memórián tároljuk az objektumokat, tömböket (ezeket referencia típusúaknak hívjuk). Ez a stackkel ellentétben egy lassabb, dinamikus memóriaterület, cserébe viszont jóval nagyobb terület áll rendelkezésre. Az itt létrehozott adatokat hosszabb távon tároljuk, globálisan léteznek, nem csak egy-egy függvény belsejében, lokálisan.

Amikor létrehozunk egy objektumot a heapen, akkor az adott változó az gyakorlatilag csak egy referencia, mutató lesz a heap-beli memóriaterületre, ahol ténylegesen az objektum tárolódik, a változó maga csak ezt a referenciát tárolja (a stacken). Ez ismerős lehet, a pointer fogalma hasonló. Tehát a referencia típusú változó nem közvetlenül tárolja az értéket, csak egy referenciát tárol, és a heapen tárolt értéket közvetetten, ezen a referencián keresztül érjük el.

Gyakorlati példa: Egy nagyon szemléletes példa, Bruce Eckel Thinking in Java című könyvéből: Képzeljük el, hogy van egy Televízió típusú objektumunk a heapen, melyhez tartozik egy referencia, amelyet letárolunk, és ennek a neve legyen távirányító. Ahogy a való életben is, ülünk a kényelmes fotelünkben, és nézzük a televíziót, de amikor szeretnénk a Televízió objektumunkon bármely módosítást eszközölni (halkítani, hangosítani, csatornát váltani, be-, kikapcsolni), akkor a távirányító segítségével tesszük meg ezt. És ha a szobában sétálva, lefekve bárhol szeretnénk a Televízió objektumon machinálni, akkor a távirányítót visszük magunkkal, nem pedig magát a Televíziót.

Java és C-beli különbségek, hasonlóságok

Az egyes szekciókban tárgyalt és azokon túlmutató hasonlóságokról és különbségekről bővebben olvashatsz itt és itt.

Tömbök

Korábban már volt szó konkrét tömbökről (pl.: parancssori paraméterek tömbje). Az akkor tárgyaltak természetesen általánosságban is igazak a tömbökre. Egy rövid összefoglaló: A tömbök azonos típusú, de egynél több érték tárolására vannak kitalálva. Az elemek száma azonban rögzített, tehát adott számú, azonos típusú elemet tartalmazó adattípusról van szó. Az indexelés 0-val kezdődik, ahogy az ismerős lehet Programozás alapjai tárgyból.

Megjegyzés: Habár Javaban, C-ben 0-tól indexelünk, nem feltétlenül van ez így minden nyelvben. Vannak olyan nyelvek, melyek egytől kezdik az indexelést. Ezen nyelvekről [itt][nyelv_index] találsz egy összefoglaló listát.

Fontos lehet, hogy a C-vel ellentétben itt nagyon szeretjük a tömböket, hiszen a Java (mivel menedzselt nyelvről van szó, azaz a kód nem közvetlenül a hardveren fut, hanem a JVM-en, ahogy ezt korábban tárgyaltuk) teljes körű indexhatár-ellenőrzést végez, kivétellel jelzi, ha alul- vagy túlindexelés történik.

A Java-beli tömböket többféleképpen is létre lehet hozni. Statikusan, ha előre tudjuk a tömb elemeit, vagy pedig dinamikusan, amikor nem feltétlen tudjuk a tömb elemeinek értékét. Mind primitív típusból, mind pedig osztályokból létrejövő objektumok esetén használhatunk tömböket. Tömböket dinamikusan, a new operátorral lehet létrehozni, mérete a már ismert length tulajdonsággal kérdezhető le.

Egydimenziós tömbök

Az egyetlen kiterjedéssel (dimenzióval) rendelkező tömböket szokás vektornak is nevezni, ahogy ez a kifejezés matematikából ismerős lehet. A tömböt deklarálni a következőképp lehet:

1
2
típus tömbnév[];
típus[] tömbnév;

A két deklaráció között semmilyen különbség sincs. Futás közben a már említett new operátorral tudjuk definiálni:

1
tömbnév = new típus[méret];

Egy konkrét példa:

1
int[] x = new int[5];

Ennek a tömbnek az elemei: x[0], x[1], x[2], x[3], x[4]. A tömböt legegyszerűbben egy for ciklussal tölthetjük fel.

A Java lehetővé teszi, hogy a tömböket a definiálás során konstans értékekkel töltsük fel. Ilyenkor a tömböt a fordító hozza létre.

1
2
3
típus[] tömbnév = { konstans1, konstans2 }
// egy konkrét példa:
int[] arr = { 1, 2, 3, 4, 5 };

Adott tömb mérete minden esetben egy nemnegatív egész szám, melynek értéke nem lehet nagyobb, mint a lehetséges legnagyobb index. Ez a JVM-től függ, és mivel az indexelés int értékekkel történik, ezért az elméleti legnagyobb elemszám Integer.MAX_VALUE (ez egy definiált konstans), azonban ez a gyakorlatban egy ettől 5-8 értékkel kisebb szám. Derítsük ki, hogy a saját JVM-ünk esetében mekkora ez a szám: ehhez hozzunk létre egy tömböt, és próbáljuk meg lefordítani, és lefuttatni az elkészült fájlt:

1
String[] tomb = new String[Integer.MAX_VALUE - 4];

Többdimenziós tömbök

Analóg módon az egydimenziós tömbökhöz, illetve a korábban, Programozás alapjain tanultakhoz:

1
2
típus[][]...[] tömbnév;
típus tömbnév[][]...[];

Két dimenziós tömb létrehozására egy példa:

1
2
típus[][] tömb;
tömb = new típus[méret1][méret2];

Egy konkrét példa kétdimenziós tömb létrehozására és feltöltésére. A tömböt legegyszerűbben egy for ciklussal tölthetjük fel.

1
2
3
4
5
6
7
8
int[][] tomb;
tomb = new int[10][9];

for (int i=0; i < tomb.length; i++){
    for (int j = 0; j < tomb[i].length; j++) {
        tomb[i][j] = (i+1)*(j+1)*9;
    }
}

A Java lehetővé teszi, hogy a tömböket a definiálás során konstans értékekkel töltsük fel. Ilyenkor a tömböt a fordító hozza létre

1
int[][] matrix = { { 1, 2 }, { 3, 4 } };

Tömbök másolása

Mivel a tömbök referencia típusúak (előző gyakorlat), ezért egy egyszerű értékadás esetén csak a referenciát (azaz a tömb címét) másoljuk át egy másik változóba, a konkrét, memóriában létező tömböt nem. Tényleges tömbmásolást kézzel is megvalósíthatunk, egyszerű for ciklus segítségével, de létezik egy, a JDK-ban már előre elkészített metódus épp erre a célra: a tényleges másolás a System.arraycopy() metódussal lehetséges. Ennek fejléce ([javadoc][javadoc_arraycopy]):

1
public static void arraycopy(Object forrás, int forrásKezdetiElem, Object cél, int kezdetiPozíció, int hossz)

Egy konkrét példa tömbök másolására:

1
2
3
4
5
6
7
8
9
   int tomb1[] = { 30, 31, 1, 2, 3, 4, 5, 6, 7 };
   int tomb2[] = { 29, 0, 0, 32, 33 };

   System.arraycopy(tomb1, 0, tomb2, 1, 2);

   for (int i=0; i<tomb2.length; i++){
       System.out.print(tomb2[i] + " ");
   }
   System.out.println();

Ennek kimenete: 29 30 31 32 33.

Videók

Feladatok

  1. Írd ki a parancssori paramétereket a konzolra
  2. Írd ki a parancssori paramétereket a konzolra, fordított sorrendben
  3. Írd ki a parancssori paramétereket úgy, hogy az n. sorban az első n darab parancssori paramétert írja ki: első sorba csak az elsőt, a másodikba az első kettőt szóközzel elválasztva, a harmadikba az első hármat, stb..

    java Main egy ketto kutya cica fagyi

    1
    2
    3
    4
    5
    egy
    egy ketto
    egy ketto kutya
    egy ketto kutya cica
    egy ketto kutya cica fagyi
    
  4. Írd ki a parancssori paraméterek közül a legnagyobbat, legkisebbet, valamint az értékek átlagát.

  5. A parancssori paraméterek alapján döntsd el, hogy egy a bemenő számok számtani, mértani sorozatot alkotnak-e, vagy esetleg egyiket sem. Feltehetjük, hogy mindegyik egész szám, és legalább 3 db paraméterünk van. Az összegképletek:

    • számtani: an = a1 + (n – 1) * d
    • mértani: an = a1 * q n – 1
  6. Számítsd ki a parancssoron kapott két időpont (óra perc óra perc) között eltelt időt, és írasd ki a konzolra (óra perc formában). A program elkészítése során ügyelj az adatok helyességére

    • bemenő paraméterek száma
    • az órák 0-23 intervallumba kell, hogy essenek
    • a percek 0-59 intervallumba kell, hogy essenek
  7. Hozzunk létre egy 7*10-es int-eket tartalmazó tömböt, töltsük fel őket, az alábbi séma szerint: tömb[x][y] = x*y; (pl.: tömb[5][8] = 40;)

  8. Hozzunk létre egy karakter tömböt 't' 'e' 'l' 'e' 'f' 'o' 'n' karakterekkel! Másoljuk egy új tömbbe a 'l' 'e' karaktereket!

Kapcsolódó linkek

Learning the Java Language


Utolsó frissítés: 2021-05-04 07:53:32