Hirdetés

2024. május 1., szerda

Gyorskeresés

Hozzászólások

(#2301) Korcsii válasza [pod]Diablo (#2300) üzenetére


Korcsii
őstag

if (t[i] < t[i+1]) printf("az i+1 nagyobb");

kétlem, hogy ennyire egyszerű lenne a kérdés, de amit kérdeztél, az így valósítható meg... csak épp vigyázni kell, hogy az i, i-1 és/vagy i+1 is létezzen, különben szépen elszáll a program... ha mindez esetleg egy ciklusba kerül, akkor meg főleg....

[ Szerkesztve ]

(#2302) kingabo válasza Korcsii (#2301) üzenetére


kingabo
őstag

"i, i-1 és/vagy i+1 is létezzen"
Jobban mondva ezek az indexek is a tömbön belül legyenek: legalább 0 és legfeljebb n-1, ha n elemű a tömb.

"különben szépen elszáll a program..."
Miért szállna el? Nagy valószínűséggel csak memória szemetet hasonlítgatna, ha dinamikusan lett lefoglalva a tömb, ha nem akkor a veremben elötte/utána lévő dolgokat. A c, c++ nem figyeli, hogy tömbön belül indexeltél-e. (pl a pascal-lal/ada-val ellentétben) Esetleg, ha nagyon rossz helyre menne, az oprendszer nem hagyja. c++-ban acces vialation kivételt dob ha jól rémlik, c alatt passz

[ Szerkesztve ]

(#2303) Korcsii válasza kingabo (#2302) üzenetére


Korcsii
őstag

"Esetleg, ha nagyon rossz helyre menne, az oprendszer nem hagyja. c++-ban acces vialation kivételt dob ha jól rémlik, c alatt passz"

No én erre gondoltam :) c alatt ugyanez

(#2304) Cicero válasza kingabo (#2299) üzenetére


Cicero
őstag

Várom a szájbarágós szöveget :DD Amióta a bme-re járok rájöttem hogy nagyon lassú a felfogásom :)

(#2305) kingabo válasza Cicero (#2297) üzenetére


kingabo
őstag

Hát ez "picit hosszú lett. Remélem érthető. Ha kérdésed van kérdezz nyugodtan, ha a többiek valami hibát találnak szóljanak és modikkal javíttatom.
A pointer az egy mutató a memória egy pontjára, vagyis egy memória címet tárol (egy int-et). Minden pointernek meg kell mondani, hogy milyen típusra mutat, hogy a fordító tudja, mi van ott: pl char vs float, mekkora (1byte vs 4byte). A pointert minden esetben használat elött inicializálni kell! (egyszerűbben: értéket kell neki adni), mivel a pointer "kezdeti értéke" nem NULL (==megegyezés szerint nem mutat sehova sem /semmire sem), hanem valamilyen memória szemét, ha ezt a szemetet akarod felhasználni arra, hogy elérd a pointer által mutatot memória helyet elég csúnya dolgok történhetnek ("jobb esetben" az oprendszer nem hagyja, "rosszabb esetben" felhasználhatják a program eltérítésére). Pointer deklarálása: a "mutatandó" érték típusa és a változó neve elé egy *:
int * p;

Érték adás:
- NULL:
int *p = NULL;
- Egy másik pointer(1), vagy pl tömb esetén annak egy tetszőleges eleme(2) (részletesen lentebb)
int *pt,*pt1,t2[]={1,2,3,5};
pt = t2; //(2)
pt1 = pt; //(1)
pt = pt1 + 3; //(2) a t2 4. elemére mutat (1+3)

- Egy változó címe: a váltózó elé a '&' jelet kell írni
int *p, i = 5;
p = &i;

- Dinamikusan foglalunk le memóriát (ld. késöbb)

Pointer értéke vs pointer ÁLTAL MUTATOTT memória hely értéke: ezek keverése miatt lehet igen csúnya dolgokat (==hibákat) művelni. A pointer értéke egy memória cím, ami (jó esetben) egy megfelelő értékre mutat. A pointer által mutatott hely értéke az elején részletezett, a pointer deklarácójakor megadott típusú érték. Ezt elérni a pointer neve elé tett *-al lehet. Pl az előző részből az utolsó példában a 'p' pointer értéke az 'i' változó CÍME a memóriában. Az általa mutatott ÉRTÉK, vagyis a *p értéke 5 (*p = i = 5).
A gondot az okozhatja, hogy "véletlenül" lemarad a 'p' elől a *, így a pointer kap értéket, nem az általa mutatott memória cím. Vagyis ha az 'i'-nek értéket akarunk adni a 'p' pointeren keresztül akkor így kell *p = 6; // ==i;. A következő kód hibás, csak szemléltető ellenpélda: p = 6;, ekkor az 'i' értéke nem változik, a 'p' értéke egy, a programunktól független (nem a program egy változójára, vagy általa dinamikusan lefoglalt memória területre mutat), a 6-os memória címre fog mutatni, ahol biztosan semmi keresni valónk nincs és valószínűleg az oprendszer adatai vannak, vagyis semmi jóra ne számítsunk. (akit érdekel picit részletesebben itt az utolsó 2 sor)

Egy dimenziós tömb: avagy a vektor. Egy 'n' elemű vektor, n db a memóriában egymás után lévő érték. (mint linalgból) Szemléletesen pl 3 elemű tömb (az '_' helyére kerülnek az értékek: |_|_|_|
Pl: int t[]={1,2,3,5};
A dolog szépsége az, hogy a 't' is egy pointer lesz, mely a tömb első elemének memóriabeli címére fog mutani.
A tömb elemeinek elérése
- a pointer eltolása, vagyis a pointer értékéhez hozzáadva, vagy levonva belőle. Fontos: nincs semmilyen védelem, hogy a pointer ne tudjon a tömbről "lemenni". Célszerűbb (főleg az elején), inkább a másik megoldást alkalmazni, kisebb a hiba lehetősége.
pl (a fenti t-t felhasználva): int *masodikElem = t+1; // a t 2. elemére mutat (1+1)
int harmadikElemErteke = *(t+2); //t eltolva 2-vel, vagyis a 3
. elem címére mutat és vesszük a címen lévő értéket

- a [] operátort használva. a változó után írva, a zárójelek közé egész számot, vagy egész típusú változót írva.Fontos: a megszokottól eltérően, c-ben az indexelés 0-tól n-1-ig történik! Vagyis pl, a zárójelek közé 0-át írva az általunk megszokott első elemet, n-1-et írva az általunk megszokott utolsó elemet kapjuk. További megjegyzendő tény, hogy nincs semmi védelem az ellen, hogy ne "menjünk le" a tombről. Más szóval ha a c-s indexeléssel nézve a -1-edik vagy az n-edik elemét akarjuk elérni a tömbnek (ami nem létezik), akkor a memóriában a tömb elött és utána lévő értékeket fogjuk elérni, amiről már a legelején megemlítettem, hogy mindent csak jót nem jelent! (Érdekesség: a fordító ezesetben átfordítja az előző változatra. pl t[2]-ből *(t+2) lesz)

Dinamikus helyfoglalás: adott a probléma: fordítási időben meg kell adnunk, hogy mekkora lesz a tömbünk mérete. Viszont, ha ez az érték csak futási időben derül ki, mert pl a felhasználó fogja megadni, akkor dinamikusan, azaz futási időben kell a tömböt lefoglalni. Módja 1 dimes tömb esetén:
- 1 deklarálni egy megfelelő típusú pointert, ami majd a tömb első (azaz 0.) elemére fog mutatni
- malloc-kal lefoglani n db, a fenti pointer által mutatott típusnak megfelelő méretű, folytonos memória területet
- a pointer típusára konvertálni a malloc által visszaadott pointert (ha valakit érdekel miért kédezzen rá, de nem igazán ez a szint, szerintem)
pl:int *p, n = 0;
//... n értéket kap
p = (int*) malloc (sor * sizeof (int));

Ha pl int helyett float kell, akkor 3 (azaz három) helyen kell cserélni a típust: a pointer deklarációjánál, a sizeof paraméterében (ez adja meg, hogy mekkora helyet foglal 1 adott típusú változó), illetve a malloc elött.
Esetleg célszerű egy if ágban lekezelni, hogy sikeres volt-e a hely lefoglalása:
if ( (ppt = (int*) malloc (oszlop * sizeof (int)) ) == NULL)
{ printf ("nincshely");
exit (1);
}//if

A fenti kód megpróbál oszlopnyi int-et lefoglalni, ennek első elemre mutató pointerét értékül kapja a ppt. Ezt utána megvizsgálunk, hogy NULL-e (ez az ami nem mutat sehova, vagyis nem sikerült lefoglalni), ha NULL, akkor a hibáról értesítjük a felhasználót és 1-es hibakóddal termináljuk (befejezzük) a program futását.
Memória felszabadítása: az általunk malloc-kal lefoglalt memóriát senki sem fogja felszabadítani, így ha már nincs rá szükségünk, vagy ugyanazt a pointert akarjuk használni egy újabb terület lefoglalásához, akkor elötte kötelező felszabadítani a memória területet, illetve célszerű a pointernek a NULL értéket adni. Ha az elöbbit elfelejtjük a programunk elszívárogtatja a memóriát (memoryleak). A felhasználó ebből azt veszi észre, hogy minnél többször futtatja a programunkat, annál több szabad hely fogy el, amit a program lefutása után nem kap vissza. A második inkább csak biztosági szempontok miatt szükséges, nehogy valaki véletlenül (esetleg rossz akaratúak direkt) a már felszabadított memória területről próbáljanak olvasni, esetleg írni (amivel más adatai írodnak felül) Fontos: NE felejtsük el felszabadítani a lefoglalt területet!
Felszabadítás: free(pointer); //ahol a pointer egy dinamukusan lefoglalt
memória terület kezdőcíme

Tényleg ne maradjon le az a free! Nem lehet elég sokszor hangsúlyozni.

Több dimenziós tömbök: az egyszerűség kedvéért csak 2 dimes tömb, de ez alapján könnyen megoldható magasabb dimszámra is. (ugyanazt kell elvégezni még annyiszor, amíg el nem érjük a kívánt dim-et, ami alább következik)
Megvalósítás(elmélet): 2 dimes tömböt c-ben csak úgy tudunk megvalósítani, hogy létrehozunk egy tömböt, amely minden eleme a 2 dimes tömb egy sorára mutat.
Pl: 3x4-es tömb: van egy 3 elemű tömbünk, amelynek minden eleme egy-egy 4 elemű tömb első elemére mutat. Szemléletesen (a mutatást a -> jelőli)
_
|_| --------------> |_|_|_|_| első sor
|_| --------------> |_|_|_|_| második sor
|_| --------------> |_|_|_|_| harmadik sor

Tömbben lévő értékek elérése: mesélve: először (a fenti 3x4-es pl-nél maradva) a 3 elemű tömbben kell megkeresni a kiválaszotott sort tartalmazó tömb címét. Ezután elugrani erre a címre és a megadott oszlop elemének címét meghatározni.
Konkrét pl-en: próbáljuk meghatározni a fenti tömb (szokásos indexeléssel) a 3. sor 2. oszlopában lévő elemet. Ekkor először meg kell tudnunk a 3. sort tartalmazó vektor címét, vagyis t[2]-t (==t[3-1]). Ezután már csak a 2. oszlop elemét kell venni, vagyis t[2][1] (ld. előbb). Megvalósítás a pointer eltolásos technikával, inkább csak érdekesség képpen: a 3. sor címe: *(t + 2), az így megkapott vektor a 2. elemének értéke: *( *(t + 2) + 1)
2 dimes tömb lefoglalása: a fenti szemléltető ábrán is (remélhetőleg) jól látszik, hogy 4 (azaz négy) darab tömböt kell lefoglalnunk, melyek a memóriában "bárhol" lehetnek (az össz megkötés annyi, hogy a tömb elemei egymás után jönnek):
- 3db 4 elemű tömböt (vagyis lesz 3db pointerünk)
- 1db 3 elemű pointereket tartalmazó tömböt (vagyis ennek típusa pointereket tartalmató tömb, ami viszont szintén egy pointer, vagyis 2db csillag kell deklarációnál)
Pl:
//2 dimes tömb lefoglalása
int **ppt, sor, oszlop, i,j;
//.. értékadás a sor-nak és az oszlop-nak
//első rész lefoglaljuk az oszlop vektort, ami majd tárolja a
sorok címeit
if ( (ppt = (int**) malloc (sor * sizeof (int*)) ) == NULL)
{ printf("nincshely");
exit(1);
}//if

//második rész lefoglaljuk egyesével a sorokat
for (i = 0; i < sor; i++)
if ((ppt[i] = (int*) malloc (oszlop * sizeof (int)) ) == NULL)
{ printf ("nincshely");
exit (1);
}//if
//for

//2 dimes tömb bejárása:
for(i=0;i<sor;i++)
{
for(j=0;j<oszlop;j++)
{
ppt[i][j]=j; //itt tetszüleges int állhat; értékadás
printf("%d ",ppt[i][j]); //érték "lekérése"
}//forj
printf("\n");
} //fori

//2dimes tömb felszabadítása:
for(i = 0; i < sor; i++)
free(ppt[i]);
free(ppt);

Pont úgy ahogy a fenti pl-nél maradva 4 tömböt kell lefoglalni 4-et is kell felszabadítani!
2 dimes tömb megvalósítása 1 dimes tömbbel: a 2 dimes tömb felfogható úgy is, hogy egymás után írjuk a sorait, így egy 1 dimes tömböt kapunk. A korábbi 3x4-es pl, így egy 1x12-es vektorra módosul. Egyetlen "probléma", hogy hogyan lehet kiszámolni a harmadik sor második elemének indexét. A megoldás nagyon egyszerű, csak végig kell gondolni mi történt az eredeti tömbbel (a szokásos indexelést használva): leírtunk egymás után 2 sort (2 * 4 elemet), majd a 3. sort megkezdve leírtunk még 2 elemet, vagyis meg is lett a 3.sor 2. eleme. (persze a többit is leírtuk, de az index kiszámításához nincs rájuk szükség) Vagyis mostmár általánosan: az x-edik sorhoz elötte el kell mennünk x-1 sor elemein, majd az x. sor elemei közül még az y-adikig. Legyen mondjuk minden sorban n db elem, ekkor az x-edik sor y-adik eleme: (x - 1) * n + y. Már csak azt kell végig gondolni, hogy a c féle 0-tól való indexelés változtat-e valamit vagy sem. Vagyis, ha a (innentől már a c-s indexelés) 0. sor 1. (ami nálunk az 1 sor 2. eleme) elemének az indexét kell meghatároznunk, akkor az 0 * n + 1 indexű lesz, ha az 1. sor 3. eleme 1 * n + 3, vagyis általánosan x-edik sor y-adik eleme: x * n + y.
Magasabb szinten, esetleg optimalizáláskor jöhet jól, ugyanis ezzel a módszerrel a tömb tetszőleges eleme 1 lépésben megkapható, míg a korábban leírt változattal csak 2 lépésben
Több dimenziós tömbök: csak vázlatosan: vizuális típusú embereknek: téglapból (XxY) úgy lehet téglát(XxYxZ) készíteni, hogy az (x,y) koordináta "fölé is teszünk 1 vektort(magasság)". Ezesetben ugyanúgy lesz 1 tömbünk, ami a sorokra mutató pointereket fog tartalmazni, viszont a sorok most szintén pointereket fognak tartalmazni, ezek lesznek az (x,y) helyen a fölé tett vektorra mutató pointerek. Vagyis lesz 1db X elemű tömb(int***), amiben lesznek a sorokra mutató pointerek (int**), lesz Xdb Y elemű vektor(int**), amik a magasság vektorokra mutató pointereket (int*) tartalmaznak és lesz X*Ydb Z elemű vektor (int*), ami tartalmazza a magasság adatokat (int).
Másként lehet úgy is nézni, hogy van egy vektorunk, aminek minden elem 1-1 két dimes tömbre mutat. Magasabb dim-ek ezzel a rekurzióval előállíthatók, vagy alkalmazható a fenti dim csökkentő módszer, bonyolultabb képlettel.

Láncolt listák: mese: aki érti a 2 dimes tömböknél történteket, annak ez sem jelenthet gondot. A láncolt lista azt az ötletet használja fel, amit a sorok címének meghatározására használtunk fel. Viszont itt azt szeretnénk, hogy tárolhassunk a pointer mellett még adato(ka)t, illetve ne egy sorra mutasson a pointer, hanem egy másik ugyanilyen elemre. Ilyen adatszerkezetet használnak, akkor ha pl nem tudjuk előre, hogy mennyi adat lesz és a felhasználó sem tudja előre. Béna példa: mennyi madarfajt tudsz felsorolni? Ezt a példát tovább víve, a listában tárolandó adat a madárfaj neve, a pointer értéke kezdetben NULL, aztán ha a felhasználó megad egy újabb madárfajt, akkor dinamikusan létrehozunk még egy ilyen lista elemet, és ennek címét állítjuk be az előbb említett pointernek. Célszerű egy külön pointerben eltárolni a lista első elemét (fej/fej elem), és bejáráskor egy másik pointerrel (akt) végig menni rajtuk. (így nem veszik el az eleje)
Megvalósítás: szükséges hozzá tudni mi az a struct! A lista típusa egy struct lesz, ami lehetővé teszi, hogy adatokat is tárolhassunk és mutathassunk egy másik azonos típusú struct-ra.
Saját structunk létrehozása, illetve a fej deklarálása:
typedef struct madarFaj
{
char nev[30];
struct madarFaj *kov; // kov pointer madarFaj típusú
struktúrára
}MADARFAJ; //létrehoztuk a MADARFAJ nevű típust
MADARFAJ *fej, *akt;
char madarFajNeve[30];

Új létrehozása és értékadások:
//ciklusban madárfaj bekérése
MADARFAJ p = (MADARFAJ*) malloc (sizeof (MADARFAJ) );
//új listaelem lefoglalása
p->nev = madarFajNeve; //elmentjük a faj nevét
p->kov = NULL; //még nincs következő lista elem, ezért nem mutat sehova sem
akt->kov = p; //hozzá fűzzük a listához az új elemet.

Fontos: mivel a lista elemei is dinamikusan lefoglalt memória terültetek, ezért egyesével végig kell menni minden lista elemen és fölszabadítani!
akt = fej;
while (akt != NULL) //amíg van elem a listában
{
MADARFAJ *p = akt; //elmentjük az aktuális listaelem címét
akt = p->kov; //az aktot a következő elemre állítjuk
(felszabadítás után nehéz lenne)
free(p);
}

[ Szerkesztve ]

(#2306) kingabo válasza Cicero (#2304) üzenetére


kingabo
őstag

Remélem elhiszed, hogy a fenti hsz-t nem 2 sec alatt írtam meg. :U
Sztem nem a felfogásoddal van a gond, hanem hogy egyetemen b@sznak magyarázni. Nem véletlenül van középsuliban tanár, egyetemen előadó :U

szerk: kár, hogy itt a ph!-n nem lehet olyat csinálni mint egyes másik oldalakon, hogy a kódot autómatikusan színezni, esetleg hosszabb soroktól nem zuhanna szét az oldal. (amit tudtam javítottam, van pár komment sor ami nem fért ki egy részét átküldtem új sorba, de oda meg elfelejtettem //-t tenni, 1 még maradt benn)

[ Szerkesztve ]

(#2307) RexpecT


RexpecT
addikt

Üdv!
Srácok lenne egy kérdésem:Mit ír ki az alábbi kódrészlet?:
int i;
for(i=2;i<19;i+=i/2)
{
printf("%d",i);
}
Hiába írom be dev c++-ba hülyeséget ad ki, elvileg 13-at kellene kiírnia nem?
:R

(#2308) doc válasza RexpecT (#2307) üzenetére


doc
nagyúr

szerintem 2346913, de nem probaltam ki

(#2309) Korcsii válasza RexpecT (#2307) üzenetére


Korcsii
őstag

2, 3, 4, 6, 9, 13

persze végeredményben így írja ki (elvileg, nem próbáltam): 2346913

szerk: hehe, doc megelőzött...

szerk2: 13-at ez írna ki:

for(i=2;i<19;i+=i/2);
printf("%d",i);

[ Szerkesztve ]

(#2310) RexpecT válasza doc (#2308) üzenetére


RexpecT
addikt

Nekem is ezt adja ki de nem értem hogy hogy:
2-vel indul az kisebb mint 19 kiírja a 2-t majd i=2+1
3 az kisebb mint 19 kiírja a 3-t majd i=3+1,5 mivel int ezért vágás történik ezért i=4
4 az kisebb mint 19 kiírja a 4-t majd i=4+2
6 az kisebb mint 19 kiírja a 6-t majd i=6+3
9 az kisebb mint 19 kiírja a 9-t majd i=9+4,5 de megint vágás lesz ezért i=13
13 az kisebb mint 19 kiírja a 13-t majd i=13+6,5 de megint vágás lesz ezért i=19
19 nem kisebb mint 19 ezért nem fog lefutni a ciklus mag.

LOL hülye vagyok :W :R csak egy \n-et kellett volna írni és akkor világos :DDD .

[ Szerkesztve ]

(#2311) Korcsii válasza RexpecT (#2310) üzenetére


Korcsii
őstag

szerk:
kellett nekem belekezdeni, aztán nem tudom félreérthetetlenül megfogalmazni...

i=3+1, maradjunk ennyiben... egészet osztasz egésszel, ezért az operátor az egész osztást valósítja meg (amennyiszer pontosan megvan benne), tárolni utána tárolhatnád másban is... csak mivel a tároló, és az osztandó itt ugyanaz, mégse teheted, mert ha doble lenne, akkor már engedné :)

[ Szerkesztve ]

(#2312) RexpecT válasza Korcsii (#2311) üzenetére


RexpecT
addikt

Igaz :R .

(#2313) Cicero válasza kingabo (#2306) üzenetére


Cicero
őstag

Köszönöm szépen!

(#2314) RexpecT


RexpecT
addikt

Lenne itt egy feladatocskám:
Adott a következő multihalmaz={3,3,3,1,1,1}.Tárolása az int h[5] tömbben történik.
Írja fel a tömb elemeinek értékét: _ _ _ _ _
Melyik a legnagyobb elem, ami ezen reprezentáció mellett a multihalmazban tárolható?

A multihalmazról csak annyit tudok, hogy egy elem többször is szerepelhet. :B

(#2315) kingabo válasza RexpecT (#2314) üzenetére


kingabo
őstag

Tudom ez Neked nem segít, de az elemeket (érték, multiplicitás) formában szokás tárolni. Ez alapján (nekem!) az tűnik logikusnak, hogy egy indexre beírod az értéket utána a multiplicitását. vagyis: 3 3 1 3, hogy az 5. elem mi a fene lehet nem tudom.
A másik kérdést nem igazán értem, hogy mire akar célozni. A tömb egy elemének maximális értékét a típusa határozza meg, pl 32 bites gépen, int esetén 2^31-1; unsigned int esetén 2^32-1. Hogy erre gondoltak-e nemtom.

szerk: elöbb nem vettem észre, hogy int típusú a tömböd. Ezeseben szerintem a max a 2^31-1. A többiek majd vagy megerősítik vagy kijavítanak.

[ Szerkesztve ]

(#2316) Jester01 válasza RexpecT (#2314) üzenetére


Jester01
veterán

Ez egy elég tökkelütött feladat :U
Az adott tömbben elég sokféleképpen lehet tárolni a halmazt, az egyik módot kingabo fentebb említette. Én most egy másikat mondok, ami valószínűleg közelebb áll a kérdésfeltevő korlátolt elképzeléséhez ;]
Használjuk az x -> h[x] leképezést a számosság tárolására. Vagyis h[0] a 0 számossága, h[1] az 1 számossága, stb.
Ez alapján az adott halmaz leképezése {0, 3, 0, 3, 0} a legnagyobb tárolható elem pedig a 4.

Kicsit általánosítva x -> h[f(x)] leképezés lehet, ahol a fenti példában természetesen f(x)=x. Vegyük észre, hogy ennek a leképezésnek igazából az alaphalmaz számosságára illetve az egyes elemek előfordulására van korlátja, nem pedig az elemek nagyságára. Magyarul 5 különböző elemet használhatunk, de azok bármik lehetnek. Például ha f(x)=x-1 akkor máris az {1, 2, 3, 4, 5} alaphalmazzal dolgozunk és a legnagyobb tárolható elem az 5. Mivel a példában csak 2 különböző elem van, ezért a fennmaradó 3 elemet tetszés szerint választhatjuk meg, így bármekkora elemet is tárolhatunk.

Jester

(#2317) kingabo válasza Jester01 (#2316) üzenetére


kingabo
őstag

Ba+. :W :DDD Nyertél! :R

(#2318) RexpecT válasza Jester01 (#2316) üzenetére


RexpecT
addikt

Köszönöm a válaszokat, este megataláltam egy kinyomtatott jegyzetben és tényleg úgy van ahogy Te mondod.
Tehát a helyes válasz:
Ez alapján az adott halmaz leképezése {0, 3, 0, 3, 0} a legnagyobb tárolható elem pedig a 4.
:R

(#2319) RexpecT


RexpecT
addikt

Valaki eltudná mondani hogy ez a logikai kifejezés miért igaz?
x=14 y=20
x % y == 14
:R

(#2320) doc válasza RexpecT (#2319) üzenetére


doc
nagyúr

tisztaban vagy azzal hogy a % mit jelent?
ha elosztod a 14-et husszal, az megvan benne nullaszor, a maradek 14

[ Szerkesztve ]

(#2321) RexpecT válasza doc (#2320) üzenetére


RexpecT
addikt

Köszönöm így világos :R .

(#2322) artiny


artiny
őstag

Megszeretném tanulni a C programozást. Olvasom ezt:
http://kr-c.freeweb.hu/
(KERNIGHAN - RITCHIE A C programozási nyelv)

Fejezet végén van olyan,hogy probald meg te is pl.:
Hello world kiírást. Ezeket a feladatokat amik vannak gyakorlás képpen a könyvben - ezeket szeretném kipróbálni.Melyik programban kell beírni? (mint pl.pascal nyelvnel a pascal programba)

(#2323) kltz válasza artiny (#2322) üzenetére


kltz
tag

Hello!

pl. Turbo C

Üdv KLtz

(#2324) kingabo válasza artiny (#2322) üzenetére


kingabo
őstag

Dev cpp, Visual C++ Express, van valami CodeBlocks is (ezzel nincs tapasztalatom).

(#2325) Cicero


Cicero
őstag

olyat szeretnék csinálni, hogy amikor elindítom a programot kirajzol egy táblázatot amibe számjegyeket vár, enter lenyomásával pedig vízszintesen ugrik a következő cellára a táblázatban. 3x3-as lenne, a sor utolsó cellája után ugrana a következő sor első cellájára. Ezeket pedig mind egy 3x3-as tömbbe természetesen beírná.
Tulajdonképpen egy 3x3-as mátrixot akarok, ami kiszámolná az x1,x2,x3-at az eredményvektorok és rendsz.m. ismeretében. A számolási algoritmus megvan, csak a grafikai ficsőr érdekelne.
Mintha lenne C-ben egy képernyő-törlés parancs, ezt kihasználva minden bevitel után kirajzolná a táblázatot a megfelelő tömb értékekkel. Kettő egymásba ágyazott for ciklus lenne, i=0-tól, i=3-ig (az első a sor, a második az oszlopokat számolná), a nem definiált tömb értéke 0-a lenne (szal rajzolás előtt le kéne foglalni egy tömböt és máris nullázni).
Valakinek valami ötlet? Előttem van részekben a dolog, csak ez a grafikus megoldás, ugrálás stb nem áll össze, olyat még nem csináltam.

(#2326) kltz válasza Cicero (#2325) üzenetére


kltz
tag

Teljesen jó az elgondolásod anno én is csináltam ilyet. A képernyő törlő parancs clrscr() amihez meg kell hívni a conio.h -t. Én úgy oldottam meg ,hogy volt 2 különböző mátrixom az egyikben tároltam a számokat adatokat a másikat "kép"-nek neveztem el és abban pedig tároltam a táblázatot. Majd írtam egy egyszerű függvényt amivel egybe másoltam a 2 mátrixot.

Meg egy kis egyéb ,hogy lehet színezni is. Van egy olyan ,hogy textcolor() és a zárójelen belülre adod meg a szín a számát pl. textcolor(12) az a piros és ha így íratsz ki,hogy cprintf("valami") akkor az egészet pirosan fogja kiírni. Na a lényeg ,hogy a táblázatot nagyon szépen feltudod dobni vele.

Üdv KLtz

(#2327) Korcsii válasza kltz (#2326) üzenetére


Korcsii
őstag

tudtommal szabványos képernyőtörlő függvény nincs...
(conio.h-t meg nem szeretjük)

[ Szerkesztve ]

(#2328) kltz válasza Korcsii (#2327) üzenetére


kltz
tag

Miért mi a gondod a conio.h-val?

Üdv KLtz

(#2329) doc válasza kltz (#2328) üzenetére


doc
nagyúr

azon kivul hogy csak egyetlen egy ceg egy olyan termekeben letezik, ami mar tizenot evvel ezelott is boven idejetmult volt, raadasul az is csak egy platformon megy?

(#2330) Cicero


Cicero
őstag

Hehe jó tudni! Nem baj, azért a feladatot megoldja még ha korlátosan is! Léteznek más képernyőtörlő függvények amúgy? Mi történik ha a conio.h-ból bemásolom a programomba a képernyőtörlős részt, és úgy hívom meg? Úgy se lesz platformfüggetlen?

(#2331) doc válasza Cicero (#2330) üzenetére


doc
nagyúr

a .h-ban nincs semmifele 'kepernyotorlos resz', az egy kozonseges header file

(#2332) Cicero válasza doc (#2331) üzenetére


Cicero
őstag

Ennyire nem értek hozzá, nekünk csak annyit mondtak előadáson hogy előre definiált függvényeket tartalmaznak a header-ök és a fordító ha ezeket látja, automatikusan a programhoz fűzi őket.

(#2333) doc válasza Cicero (#2332) üzenetére


doc
nagyúr

ha tenyleg ezt mondtak, akkor alaposan atvertek
a header file-okban csak a fuggvenydeklaraciok vannak, vagyis ha tudod a fuggveny nevet, tipusat es a parameterek tipusait, deklaralhatod te magad is, es elhagyhatod a headert
maga a fuggvenydefinicio, vagyis a fuggveny torzse a library file-okban van

(#2334) kingabo válasza doc (#2329) üzenetére


kingabo
őstag

Gyanus volt nekem, hogy ilyet én csak a turbo pascal/c-ben láttam és sehol máshol.

(#2335) doc válasza kingabo (#2334) üzenetére


doc
nagyúr

pont ezt mondm, ez a Borland sajat ganyolmanya, sehol mashol nem letezik (illetve valami kezdetleges portot csinalt valaki Linuxra, de szerencsere nem terjedt el, bar tekintve hogy Linuxra ott a nagyon jo ncurses, ez nem is meglepo :D)

(#2336) Muton


Muton
addikt

Hello!

Lámáskodom C-ből :B

Be szeretnék kérni egy nem negatív doublet, de nem megy. Ezt gondoltam ki, de csak akkor működik nálam a do-while ciklus, ha a nem double, hanem int. egyébként simán beveszi a negatív számokat is. Hol rontottam el?

double a;
do{
printf("Add meg a-t!\n");
scanf("%d", &a);}
while (a<0);

Muton#2316 - $z@r a drop >_<

(#2337) doc válasza Muton (#2336) üzenetére


doc
nagyúr

a "%d" egesz szamot var, lebegopontoshoz hasznald a %f-et ill. %lf-et a double-hoz (de minek neked double?)

[ Szerkesztve ]

(#2338) Muton válasza doc (#2337) üzenetére


Muton
addikt

Köszi! A cél a gyök fv implementálása c és algó gyakorlat cáljából. És ha működik majd egésszel, akkor meg kell oldani törtre is, majd komplex számok halmazára is. mindezt bolond biztosan :)

Ja, a while feltéteében meg lehet adni fv-t?

pl:

while (a<0 && akarmi(a));

Szerk: %fl-el sem működik :(

[ Szerkesztve ]

Muton#2316 - $z@r a drop >_<

(#2339) j0k3r! válasza Muton (#2338) üzenetére


j0k3r!
senior tag

%lf-el nalam jo, ahogy doc irta.

#include <stdio.h>

int main(int argc, char *argv[])
{
double a;
do
{
printf("Add meg a-t!\n");
scanf("%lf", &a);
}
while (a < 0);
return 0;
}

[ Szerkesztve ]

some men just wanna watch the world burn...

(#2340) Jester01 válasza Muton (#2338) üzenetére


Jester01
veterán

Mert az lf nem fl :N
Amúgy a "bolondbiztos" és a scanf nem nagyon fér össze.

Jester

(#2341) doc válasza Jester01 (#2340) üzenetére


doc
nagyúr

jaja, nem veletlenul szokas mindenhol 'getline-olni' helyette :D

(#2342) Muton


Muton
addikt

Köszönöm a válaszokat!
A gond a fl vs.lf volt :))

Jester01: csak a progi kezdetleges voltához képest kell bolondbiztosnak lennie. De majd alakul, ha kész lesz, akkor lehet upgradelni...

Muton#2316 - $z@r a drop >_<

(#2343) Cicero


Cicero
őstag

létezik valami delay függvény ami figyeli a rendszerórát és mondjuk a meghívásától számítva 5 mp múlva hajtja végre a törzsében foglaltakat? welcome screent írnék a szuper mátrixos progimhoz :DDD

(#2344) kingabo válasza Cicero (#2343) üzenetére


kingabo
őstag

//welcome screen
sleep(5); //5sec-ig vár
//mátrixos progirész

(#2345) Pcmagicnet


Pcmagicnet
csendes tag

Üdv mindenkinek!
C-ben kellene egy hisztogramos kiírást csinálnom, amihez egy kis segítség kellene. A lényeg az lenne hogy ki kéne nyomtatni, a bemenetre adott szavak hosszának hisztogramját.
Csináltam egy progit, elég hosszú de azért bemásolom.
#include <stdio.h>
#define KINN 0
#define BENN 1

main()
{
/* deklarálom az összes változót */
int nulla,egy,ketto,harom,negy,ot,hat,het,nyolc,kilenc;
int a,b,ce,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;
int c, szam, nw, nc, mas, nl, numc, allapot;
float a2;

/* definiálom a változókat */
nulla=egy=ketto=harom=negy=ot=hat=het=nyolc=kilenc = 0;
a=b=ce=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z = 0;
allapot = KINN;
nw = nc = mas = nl = numc = 0;

/* program magja */
while((c = getchar()) != EOF){
++nc;
if(c >= '0' && c <= '9'){
++numc; /* ha szám akkor 1-el növeli a numc értékét */
--nc; /* a numerikus kataktereket kivonom az összes karakterből */
}
if(c == ' ' || c == '\t'){
++mas; /* ha szóköz vagy tab */
}
if(c == '\n'){
++nl; /* ha sortörés */
}
if(c == ' ' || c == '\t' || c == '\n'){
allapot = KINN;
--nc; /* szóköz, tab, sortörés kivonása az összes karakterből */
}
else if( allapot == KINN ){
allapot = BENN;
++nw;
}
/* ha az aktuális karakter 0,1,2,3... vagy a,b,c,d.... stb. növelem
a hozzá tartozó változó értékét 1-el */
if(c == '0')++nulla;
if(c == '1')++egy;
if(c == '2')++ketto;
if(c == '3')++harom;
if(c == '4')++negy;
if(c == '5')++ot;
if(c == '6')++hat;
if(c == '7')++het;
if(c == '8')++nyolc;
if(c == '9')++kilenc;
if(c == 'a' || c == 'A')++a;
if(c == 'b' || c == 'B')++b;
if(c == 'c' || c == 'C')++ce;
if(c == 'd' || c == 'D')++d;
if(c == 'e' || c == 'E')++e;
if(c == 'f' || c == 'F')++f;
if(c == 'g' || c == 'G')++g;
if(c == 'h' || c == 'H')++h;
if(c == 'i' || c == 'I')++i;
if(c == 'j' || c == 'J')++j;
if(c == 'k' || c == 'K')++k;
if(c == 'l' || c == 'L')++l;
if(c == 'm' || c == 'M')++m;
if(c == 'n' || c == 'N')++n;
if(c == 'o' || c == 'O')++o;
if(c == 'p' || c == 'P')++p;
if(c == 'q' || c == 'Q')++q;
if(c == 'r' || c == 'R')++r;
if(c == 's' || c == 'S')++s;
if(c == 't' || c == 'T')++t;
if(c == 'u' || c == 'U')++u;
if(c == 'v' || c == 'V')++v;
if(c == 'w' || c == 'W')++w;
if(c == 'x' || c == 'X')++x;
if(c == 'y' || c == 'Y')++y;
if(c == 'z' || c == 'Z')++z;
}

printf("\nKarakterek\na:");
for(szam = 0; szam < a; ++szam){ /* Amennyi az adott karakterhez tartozó változó értéke, */
printf("%s", "*"); /* annyi * -ot íratok ki mellé */
}
printf("(%d)\nb:", a); /* a * sor végére () -jelbe kiíratom a változó értékét,
és a következő sorba kiíratom a következő karaktert */
for(szam = 0; szam < b; ++szam){
printf("%s", "*");
}
printf("(%d)\nc:", b);
for(szam = 0; szam < ce; ++szam){
printf("%s", "*");
}
printf("(%d)\nd:", ce);
for(szam = 0; szam < d; ++szam){
printf("%s", "*");
}
printf("(%d)\ne:", d);
for(szam = 0; szam < e; ++szam){
printf("%s", "*");
}
printf("(%d)\nf:", e);
for(szam = 0; szam < f; ++szam){
printf("%s", "*");
}
printf("(%d)\ng:", f);
for(szam = 0; szam < g; ++szam){
printf("%s", "*");
}
printf("(%d)\nh:", g);
for(szam = 0; szam < h; ++szam){
printf("%s", "*");
}
printf("(%d)\ni:", h);
for(szam = 0; szam < i; ++szam){
printf("%s", "*");
}
printf("(%d)\nj:", i);
for(szam = 0; szam < j; ++szam){
printf("%s", "*");
}
printf("(%d)\nk:", j);
for(szam = 0; szam < k; ++szam){
printf("%s", "*");
}
printf("(%d)\nl:", k);
for(szam = 0; szam < l; ++szam){
printf("%s", "*");
}
printf("(%d)\nm:", l);
for(szam = 0; szam < m; ++szam){
printf("%s", "*");
}
printf("(%d)\nn:", m);
for(szam = 0; szam < n; ++szam){
printf("%s", "*");
}
printf("(%d)\no:", n);
for(szam = 0; szam < o; ++szam){
printf("%s", "*");
}
printf("(%d)\np:", o);
for(szam = 0; szam < p; ++szam){
printf("%s", "*");
}
printf("(%d)\nq:", p);
for(szam = 0; szam < q; ++szam){
printf("%s", "*");
}
printf("(%d)\nr:", q);
for(szam = 0; szam < r; ++szam){
printf("%s", "*");
}
printf("(%d)\ns:", r);
for(szam = 0; szam < s; ++szam){
printf("%s", "*");
}
printf("(%d)\nt:", s);
for(szam = 0; szam < t; ++szam){
printf("%s", "*");
}
printf("(%d)\nu:", t);
for(szam = 0; szam < u; ++szam){
printf("%s", "*");
}
printf("(%d)\nv:", u);
for(szam = 0; szam < v; ++szam){
printf("%s", "*");
}
printf("(%d)\nw:", v);
for(szam = 0; szam < w; ++szam){
printf("%s", "*");
}
printf("(%d)\nx:", w);
for(szam = 0; szam < x; ++szam){
printf("%s", "*");
}
printf("(%d)\ny:", x);
for(szam = 0; szam < y; ++szam){
printf("%s", "*");
}
printf("(%d)\nz:", y);
for(szam = 0; szam < z; ++szam){
printf("%s", "*");
}
printf("(%d)\n0:", z);
for(szam = 0; szam < nulla; ++szam){
printf("%s", "*");
}
printf("(%d)\n1:", nulla);
for(szam = 0; szam < egy; ++szam){
printf("%s", "*");
}
printf("(%d)\n2:", egy);
for(szam = 0; szam < ketto; ++szam){
printf("%s", "*");
}
printf("(%d)\n3:", ketto);
for(szam = 0; szam < harom; ++szam){
printf("%s", "*");
}
printf("(%d)\n4:", harom);
for(szam = 0; szam < negy; ++szam){
printf("%s", "*");
}
printf("(%d)\n5:", negy);
for(szam = 0; szam < ot; ++szam){
printf("%s", "*");
}
printf("(%d)\n6:", ot);
for(szam = 0; szam < hat; ++szam){
printf("%s", "*");
}
printf("(%d)\n7:", hat);
for(szam = 0; szam < het; ++szam){
printf("%s", "*");
}
printf("(%d)\n8:", het);
for(szam = 0; szam < nyolc; ++szam){
printf("%s", "*");
}
printf("(%d)\n9:", nyolc);
for(szam = 0; szam < kilenc; ++szam){
printf("%s", "*");
}
printf("(%d)\n", kilenc);

/* Ha pl: 70 karakter széllességben határozzuk meg a 100% -ot */
if(a != 0){a2 = a / 0.7; /* elosztom az 'a' értékét a 70. 1 % -ával. Ennyi % lesz! */
printf("a:");
for(szam=0; szam <= a; ++szam){
if(szam <= 70){
printf("%s", "*" );
}
}

if(a2 <= 100.0){
printf("(%1.1f%s)", a2,"%");
}
else{
printf("(100.0%s)", "%");
}
}

printf("\nSzavak szama: %d\nKarakterek szama: %d\nMas: %d\nSorok szama: %d\nNumerikus karakterek szama: %d\n", nw, nc, mas, nl, numc );

system("PAUSE");
return 0;
}

Elég kezdetleges, de soha nem csináltam még ilyet. Azt sem tudom hogy kellene kinéznie. Ha valaki tud segítsen egy kicsit. Vagy ha van valami példátok szívesen megnézném.
Előre is köszi a segítséget!!!

(#2346) Pcmagicnet


Pcmagicnet
csendes tag

Az előbb elfelejtettem, hogy a kód amit bemásoltam, egy olyan program, ami kinyomtatja a bemenetre adott különböző karakterek előfordulási gyakoriságának hisztogramját, csak nem tudom hogy jól csináltam-e. Ha valaki tudja nézze meg mert nem tudom hogy ez most jó-e vagy nem. Köszönöm

(#2347) kingabo válasza Pcmagicnet (#2345) üzenetére


kingabo
őstag

Végülis így is megoldható.
5letek: a sok if helyett lehetne egy switch-ben:
switch (c)
{
case 'a': ++a; break;
...
case 'z': ++z; break;
}

A case ágak végére KELL a break.
Esetleg használhatnál tömböket a számokhoz, betükhöz és sokkal rövidebb lenne a kód.

(#2348) RexpecT


RexpecT
addikt

Gazdinfó szakra járok, de megnéztem a PTI-sek házifeladatát.
Itt van a feladat:[link]

Eddig jutottam el:

#include<stdio.h>
#include<stdlib.h>
int main()
{
/*
h=kut magassaga
u=első nap mászása
d=visszacsuszas
f=faradekonysagi tenyezo
*/
float h,u,d,i,f,magassag=0;
printf("Kerem a 'h''u''d''f' parametereket.\n");
scanf("%f%f%f%f",&h,&u,&d,&f);
f=1-(f*0.01);
for(i=1;magassag<=h && magassag>=0;i++)
{
if(i>1)
{
u=u*f;
}
magassag+=u;
magassag-=d;
printf("magassag %f\n",magassag);
}
if(magassag>=h)
printf("Success on day %f\n",i-1);
if(magassag<=0)
printf("Failure on day %f\n",i-1);
system("PAUSE");
return 0;
}

Annyi a baj, hogy mindig az első naphoz képest fárad a csiga, az én kódomban meg mindig az előzőnaphoz.Ezt kellene szerintem kijavítani és akkor jó is lenne.(Konstansnak lehet egy változó értékét adni?,vagy mutatóval kellene?)
Mentségemre legyen, hogy sok mindent nem vettünk még programozásból(ebben a félévben kezdtük el).

[ Szerkesztve ]

(#2349) Pcmagicnet válasza kingabo (#2347) üzenetére


Pcmagicnet
csendes tag

Igazad van, köszi. Csak arra is kíváncsi voltam hogy így kell-e kinéznie egy hisztogramnak, mert még nem csináltam ilyen.Sőt, még azt sem tudom hogy kell kinéznie konzolon.
Köszi még egyszer :R

(#2350) kingabo válasza Pcmagicnet (#2349) üzenetére


kingabo
őstag

Őőő, bocs csak most vettem észre: a hisztogrammban %-os eloszlást szokás mutatni. Tehát a-ból van 5%, e-ből 12%... az összegük meg 100%. VAgyis minden elemre le kell osztani a karakterek számával és megszorozni 100-al. (az osztásnál használj kasztolást, hogy ne int hanem float osztás legyen: int-nél 1/10 = 0 float-nál: 1/10=0.1)

(#2348) RexpecT: majd késöbb átnézem, ha nem jön addig senki sem.

Copyright © 2000-2024 PROHARDVER Informatikai Kft.