- Vezetékes FEJhallgatók
- Milyen egeret válasszak?
- Hivatalosan is elkészült az NVIDIA App
- AMD Ryzen 9 / 7 / 5 9***(X) "Zen 5" (AM5)
- AMD Ryzen 9 / 7 / 5 7***(X) "Zen 4" (AM5)
- Házimozi belépő szinten
- AMD K6-III, és minden ami RETRO - Oldschool tuning
- Hogy is néznek ki a gépeink?
- Vezetékes FÜLhallgatók
- Milyen TV-t vegyek?
Új hozzászólás Aktív témák
-
bpx
őstag
válasz Vasinger! #1400 üzenetére
mit értesz az alatt hogy újraindul?
elindítod és rögtön eltűnik az ablak? akkor indítsd debug nélkül (ctrl+f5) vagy írd be a végére hogy Console.Readkey(); és akkor még vár egy gombnyomásra mielőtt kilépnesorok számozása: tools / options / text editor / all languages / line numbers pipa be
-
Sk8erPeter
nagyúr
válasz Sk8erPeter #1399 üzenetére
Most akkor itt megállt a tudomány? Mert a kérdésre még akkor mindig nem tudom a választ a dinamikus memóriafoglalással kapcsolatban.
Mármint hogy tömb-nem tömb, futásidőben történő méretnövelés, stb... Amiről korábban szó volt, hogy állítólag nem lehet tömbnek futásidőben változtatni a méretét. Most akkor mi van? Fogalmi képzavar?(#1403) Karma: OK, köszi, nem sürgetésképpen írtam, csak azt hittem, hogy akkor skippeltétek a hsz.-t, mert túl hosszúra sikerült a példák miatt.
[ Szerkesztve ]
Sk8erPeter
-
Karma
félisten
válasz Sk8erPeter #1402 üzenetére
Van aki dolgozni is jár Mindjárt nézem...
Megnéztem... Mi is a kérdés?
[ Szerkesztve ]
“All nothings are not equal.”
-
Vasinger!
nagyúr
Köszi a segítséget, így már megy. De mi suliban is csak arra a zöld nyílra mentünk és nem indult újra. Miért is van ez? Valamit mit ha be kéne írni vagy törölni kellene.
Meg ha elindítom simán saját gépen, ott is egyből újraindul.
Közben kipróbáltam amit írtál, az segített. Console.Readkey();
[ Szerkesztve ]
-
Sk8erPeter
nagyúr
A kolléga itt azt mondja, nem lehet futásidőben növelni a tömb méretét. De most akkor itt nem éppen az történik? Itt tulajdonképpen pointerrel és/vagy tömbbel játszik, de a kettő bizonyos szempontból hasonló, mégis más a kettő, és most már akkor kezdem azt sem érteni, amit azt hittem, eddig értettem Tehát itt a mutatott példában pl. egy új tömbnek már futásidőben foglal akkora memóriát, amekkora számára szükséges. A másikban meg még bővíti annyival, amennyi kell, mivel csak egyszer olvashatjuk be az állományt. Ugyanúgy kezeli, mint egy tömböt. De akkor most mi is az igazság?
Sk8erPeter
-
Karma
félisten
válasz Sk8erPeter #1405 üzenetére
Félreértelmezted a második példát, ott sincs szó átméretezésről, egyszerűen egy tömbök tömbje szerkezetben foglalgat memóriát. Az első példára is igaz az viszont, hogy átméretezni pusztán malloc-kal nem lehet egy már lefoglalt tömböt. A realloc-kal hamarabb (realloc = malloc + memcpy + free egyben).
Az eredeti üzenet meg a fix szélességű stack/globális tömbökről szólt, nem a heapen lévőkről. Azokat tényleg nem tudod változtatni, se dinamikusan kiszabni, erre elég jó volt a kétsoros példakód.
“All nothings are not equal.”
-
Vasinger!
nagyúr
Mért nem müxik a tabulátor, ha így írom be?:
System.Console.WriteLine("\t\n\aszöveg");
Elvileg új sorba, bekezdéssel és pittyogással kéne kiírnia azt, hogy szöveg. Ebből a bekezdés nem működik.
Ha már itt vagyok, hogy lehet több sorral lejjebb menni nem csak egyel és középre zárni a szöveget?[ Szerkesztve ]
-
Karma
félisten
válasz Vasinger! #1407 üzenetére
Középre zárni úgy kell, hogy fogod a szöveged hosszát, elosztod kettővel, kivonod a képernyő szélességéből, és a kapott számszor kiírsz egy szóközt. De most ezzel asszem lelőttem a poént.
Egyébként meg egyszerű: a \t\n\a nem az, mint amit Te az előbb leírtál
Ez most egy tab, utána egy sortörés, végül csilingelés. Hasonlítsd össze“All nothings are not equal.”
-
shev7
veterán
válasz Sk8erPeter #1399 üzenetére
de pont errol beszeltem. Az ujtomb valtozo nem egy "statikus" tomb. Az egy pointer. Amirol mit is irtam? Ja tenyleg, azt hogy futasi idoben lehet neki memoriat foglalni.
Tehat megegszer, mert ugy tunik nem jon at
ha egy valtozot igy deklaralsz
int *tomb
az egy pointer lesz. Ponternek futasi idoben foglasz meretet, ujra foglalod stb...
ha egy valtozot igy deklaralsz:
int tomb[100]
az egy tomb, array, nevezzuk akarminek, lesz. A pointernek foglalt terulettel ellentetben ennek a memoriaigenye mar forditaskor eldol, es a stack-en fog csucsulni megvaltoztathatatlanul, es nem a heap-en ahogy a pointer altal foglalt terulet, amivel azt csinalsz amit akarsz, lefoglalod, felszabaditod, ujrafoglalod.
Ertem?
[ Szerkesztve ]
''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''
-
Sk8erPeter
nagyúr
Huhh. No, akkor valóban vannak homályos foltok.
Megpróbálom értelmezni akkor a lényegi kérdést, kérlek javíts, ha valamit rosszul gondolok:
A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen". Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát. Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb...
A második feladatban már megint ez a fogalmi zavar a bajom. (pointer, tömb, pointertömb...)
Ráadásul - bocsi az értetlenkedésért, csak vannak ilyen homályos pontok - akkor a memóriafoglalással ezek szerint nem "méretezünk", hanem nem tudom, mit csinálunkÉs még egy pluszkérdés: a main()-ben free-vel felszabadítjuk a memóriát, de ekkor nem "szabadulunk meg" egyben az adatszerkezet már korábban eltárolt értékeitől is?
Bocs a sok kérdésért, és köszönöm az eddigi és további segítséget.
(#1411) shev7: pont most küldtem a hsz.-t. köszi, rögtön végiggondolom, hogy leülepedjen. És igen, jól látod, még nem jött át, kicsit zavar van most az agyamban. De már dereng valami!
[ Szerkesztve ]
Sk8erPeter
-
shev7
veterán
válasz Sk8erPeter #1412 üzenetére
bar nem nekem szol a kerdes probalok valaszolni, ha mar itt vagyok:
"A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen"."
Lenyegeben igen.
Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát.
Inkabb nevezzuk memoriateruletnek, de igen.
Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb...
Na itt kezdodik a fogalomzavar. Eloszor is ne hivd pointertombnek mert az nem az. A pointertom az szamomra a pointerek tombjet jelenti, es itt nem errol van szo. Hogy mi is tortenik ahhoz egy kis magyarazat.
Vegyunk eloszor egy egyszeru byte pointert: byte *p;
a p valtozo tartalma egy memoria cim. A *p ahogy a deklaraciobol is olvashato egy byteot jelent (vagyis a p pointer altal mutatott erteket). Ha tovabbmegyunk a *(p+1) - a p memoriaterulet utani byte-on levo byte-ot jelenti. Na es most jon a turpissag, maradjatok meg velem hogy ne legyen olyan bonyolult az elet, behoztak ezt a tomb pointer megfeleltetest. (illetve nem behoztak, eddig is igy mukodott, csak mivel korabban nem voltak pointerek, nem foglalkoztunk a problemaval) Azaz a p[5] az megegyezik azzal mintha azt irnad hogy *(p+5).de ugye ez csak byteoknal mukodne ilyen egyszeuen. Int-nel mar bonyolultabb a tema. Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)
Namost mivel ez alapbol igy mukodott tomboknel, ( ha deklaralsz egy olyat hogy
int tomb[100]; akkor a tomb igy magaban egy pointer, es a hatterben pont egy ilyen konverzio zajlik le) akkor a pointerek bevezetesevel csak annyi tortent, hogy ez "mukodik a masik iranyba is"MOD: ja es ezert indexeljuk 0-tol a tomboket C-ben
[ Szerkesztve ]
''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''
-
Karma
félisten
válasz Sk8erPeter #1412 üzenetére
"A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen"."
Igen. Bár ha nagyon szőrözni akarnék, ahogy egyszer már tettem, a megfogalmazás nem tökéletes: magát a pointert sikeresen definiáltuk, 4 byte-ot kapott a stacken (vagy globálisan), mint egy átlagos változó. De ezt most felejtsük el egy pillanatra, mert irreleváns.
"Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát. Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb... "
Nem, mi csak és kizárólag pointerként használtuk, nincs külön olyan, hogy "tömbként" használni. Ez a szép a C-ben (konkrét és ironikus értelemben is), hogy ilyen egyszerű Mint írtam korábban, a p[n] subscript operátor az ekvivalens a *(p+n) művelettel.
A pointertömb egy teljesen más fogalom. Pl. int **valami; egy int pointerre mutató pointer, amivel (hasonlóan a második példakódhoz) tömbök tömbjét lehet megvalósítani. Ugyanezt lehet fix méretben is: int valami[5][2];.
"Ráadásul - bocsi az értetlenkedésért, csak vannak ilyen homályos pontok - akkor a memóriafoglalással ezek szerint nem "méretezünk", hanem nem tudom, mit csinálunk "
A memóriafoglalással memóriát foglalunk
"És még egy pluszkérdés: a main()-ben free-vel felszabadítjuk a memóriát, de ekkor nem "szabadulunk meg" egyben az adatszerkezet már korábban eltárolt értékeitől is?"
Dehogynem. Amire meghívod a free-t, az felszabadul, az értékei érvénytelenné és elérhetetlenné válnak. (Legalábbis így kell bánni vele, ha nem akarsz bugzani.)
Fontos megjegyezni, hogy egy dinamikus pointertömbnél az alstruktúrákat egyesével fel kell szabadítani, a fordító nem fogja kibogozni!
“All nothings are not equal.”
-
Sk8erPeter
nagyúr
Szóval akkor pl. az általam mutatott példában az ujtomb nevű tömb nem tömb, hanem pointer. De a tömb olyan, mint egy pointer, mert pl. függvénynek már eleve a címet adjuk át, ha tömböt adunk át. De a pointernek mások a tulajdonságai, szabadon, futásidőben változtatható a memóriaigénye, ide-oda állítgatható, stb., míg a tömbnek már fordításkor meghatározott a memóriaigénye, akármilyen adatot pakolászunk is bele (persze a megadott típus szerinti méretkorlátokon belül). Tehát a tömbnek ha megszakadunk, sem tudunk változtatni futásidőben a memóriaszükségletén.
Az eddigiek helytállóak? És "csupán" ilyen szempontból van eltérés?Szerk.: jól "egyszerre" írtuk a hsz.-eket, olvasom is a válaszaitokat.
[ Szerkesztve ]
Sk8erPeter
-
Karma
félisten
"de ugye ez csak byteoknal mukodne ilyen egyszeuen. Int-nel mar bonyolultabb a tema. Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)"
Nem igaz!
Ha a p ebben a példában egy int*, akkor automatikusan egy egész értéknyit lép előre, nem kell és nem szabad a sizeoffal varázsolni benne! Tehát 32 biten "p+1" az 32 bittel előrébb mutat, nem csak egy bájttal!
[ Szerkesztve ]
“All nothings are not equal.”
-
Sk8erPeter
nagyúr
Köszi a válaszokat, Karma és shev7, azt hiszem, már nagyjából értem.
"magát a pointert sikeresen definiáltuk, 4 byte-ot kapott a stacken (vagy globálisan), mint egy átlagos változó. De ezt most felejtsük el egy pillanatra, mert irreleváns." És hogy is van tovább?
"Dehogynem. Amire meghívod a free-t, az felszabadul, az értékei érvénytelenné és elérhetetlenné válnak."
Mondjuk jelen esetben a példaprogramnál ez nem volt világos, hogy minek foglaltunk akkor helyet az adatoknak, ha utána rögtön az eltárolás után meg is szabadultunk tőle. Igaz, erre lehetne azt mondani, hogy mivel nem volt része a feladatnak az, hogy tovább tárolgassuk, és még csináljunk vele valamit, csak a szavakra darabolás.(#1413) shev7: "Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)" Ettől egy kicsit megijedtem, mivel pont nem ezt tanultuk, hanem azt, hogy azzal egyenlő, hogy *(p+5). De látom később megbeszéltétek, hogy valóban az utóbbi a jó.
Itt viszont nem értettem az összefüggést: "ja es ezert indexeljuk 0-tol a tomboket C-ben" azzal, amit ezelőtt írtál.
Egyébként számomra az is újdonság volt, hogy lehet deklarálni úgy egy változót, hogy byte *p; . Ez mire jó ebben a formában? Még konkrét programban kevésszer láttam így deklarálva egy változót, de valamilyen szempontból nyilván hasznos lehet.Köszi nektek a türelmes válaszokat!
Sk8erPeter
-
shev7
veterán
válasz Sk8erPeter #1420 üzenetére
mert ha egytol indexelnenk, akkor
p[1] = *p
p[2]= *(p+1)
.
.
.0-s indexelesnel mindket oldalon ugyan az a szam van
"hogy lehet deklarálni úgy egy változót, hogy byte *p; . Ez mire jó ebben a formában? "
Na most ennek utananeztem, hogy ne irjak hulyeseget. A lenyege, hogy egyertelmu legyen. A * operator ugyanis jobbra kot. Barmennyire is irod kozel a tipushoz
Szoval ha irsz egy ilyet:
long* first, second;
akkor deklaraltal egy long pointert (first) es egy long valtozot (second). De akkor mar miert nem irnad le egyertelmuen:
long *first, second; es igy senki nem fogja azt gondolni hogy ket pointert deklaraltal.
''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''
-
Karma
félisten
válasz Sk8erPeter #1420 üzenetére
"És hogy is van tovább? "
Igazából nincs itt sok már, csak azért tereltem el a szót, hogy ne legyen kavar.
A pointer a háttérben mindig egy 32/64 bites int szám, egyszerű változó, és úgy is viselkedik, mintha egy sima int változód lenne."Mondjuk jelen esetben a példaprogramnál ez nem volt világos, hogy minek foglaltunk akkor helyet az adatoknak, ha utána rögtön az eltárolás után meg is szabadultunk tőle. Igaz, erre lehetne azt mondani, hogy mivel nem volt része a feladatnak az, hogy tovább tárolgassuk, és még csináljunk vele valamit, csak a szavakra darabolás."
Pontosan ez történt Felépíti, és el is tünteti. Szerintem durva pontlevonás járna érte, ha nem tenné a hallgató. Viszont cserébe jól bemutatja, hogy egy fésűs adatszerkezetet hogy kell felszabadítani.
“All nothings are not equal.”
-
Karma
félisten
Pfff, az előbb a fórummotor kidobta a szerkesztésemet a kukába...
Szóval az általad említett problémának van egy alternatív megoldása, ha az adott környezet úgy kívánja meg (szerencsére a legtöbbet ilyenben dolgozok, én a típushoz szeretem kötni a *-ot és a &-et ):
int* first;
int* second;“All nothings are not equal.”
-
Sk8erPeter
nagyúr
Nem a * operátor sorrendjén voltam meglepődve, hanem magán a "byte" típuson. Eddig nem használtam, és nem is igazán láttam gyakorlati feladatokban konkrétan ezt a típust. Szóval erre kérdeztem, hogy mire jó.
Egyébként jó, hogy felhívtad a figyelmem, hogy attól még, hogy a csillagot a típus mögé rakom közvetlenül, nem lesz a következő változó is automatikusan pointer (mondjuk ez viszonylag egyértelműnek látszik, de nehogy elcsesszem valamikor - most már nem fogom)
Köszi a választ ismét!(#1422) Karma: neked is köszi! Ez mitől lesz egyébként "fésűs adatszerkezet"?
[ Szerkesztve ]
Sk8erPeter
-
m0h0senator
őstag
Sziasztok,
adott egy feladat: bekérünk egy számot a felhasználótól, a szám tulajdonságai: számjegyei 0-7 ig lehetnek és max 5 jegyű lehet. ezt a számot egy karakter tömbben tároljuk el. Az lenne a kérdésem,hogy hogy döntöm el a számról, hogy hány jegyű? És a karakter tömbnek milyen szintaktikái vannak?
előre is köszönöm
An odyssey through the realm of consciousness.
-
bpx
őstag
válasz m0h0senator #1425 üzenetére
egy számról sokféleképpen meg lehet állapítani hogy hány jegyű, de a feladat szövege sugallja (karaktertömb), hogy érdemes karakterenként bekérni a számot
ekkor legfeljebb 5 karaktert kell egyenként bekérni, amit rögtön lehet ellenőrizni is, hogy beleesik-e a 0..7 tartománybaszintaktika: a legegyszerűbbet amit csak lehet (dinamikus memóriafoglalás itt felesleges)
char tomb[5];
char c;
....
c = getch();
....
tomb[0] = c; -
Karma
félisten
válasz Sk8erPeter #1424 üzenetére
Ezért fésűs (a nyilak a pointereket jelölik):
Egy kicsit elrontottam a képet, minden szó végén ott van még egy 0 is, lezárva a szavakat. A függőleges oszlopban meg csak akkor vannak 0-k, ha calloc-kal lett lefoglalva, vagy kézzel ki lett előre nullázva. De sajnos Excelben rajzoltam, és becsuktam a doksit
[ Szerkesztve ]
“All nothings are not equal.”
-
3man
csendes tag
Ha mar igy kiveseztetek a tomboket, erdemes megemliteni, hogy a legeldugodtabb bugokat a tombok tulindexelesevel lehet krealni.
Ugyanis az tortenik, hogy ha letrehozok egy int tomb[100] meretu tombot, es utanna beleirok mondjuk a tomb[234]=1 elemebe ezzel a sorral, akkor az a memoriaban utanna levo valamelyik valtozoba fog belebarmolni. Ez azutan vagy lathato hibat okoz, vagy lopakodo uzemmodban egyszercsak ertelmetlen dolgokat fog a program csinalni teljesen mashol, olyan helyen, aminek semmi koze a tomb[] hoz.
Erre mar jol kezelheto array osztalyok vannak, erdemes szetnezni es valogatni ezek kozt. A legegyszerubb, ha az ember egy sajat array osztalyt hoz letre, es minden tipusu tombot ezzel definial.
Ebben letre lehet hozni egy []-operatort, ahol az indexelesnel ellenorizni lehet, hogy az index a tomb merete alatt van-e. A tomb letrehozasanal pedig el lehet tarolni a meretet. Ezzel az apro dologgal rengeteg fejfajastol lehet megszabadulni.Ehhez kapcsolodik a memoria kezeles. Ha az ember meg kezdo, nem mindig tudja ugy felepiteni a programot, hogy minden lefoglalt memoria mindig jo helyen es jo idoben szabaduljon fel.
Minden new utasitast erdemes sajatra cserelni. Ez akar egy egyszeru makroval is megteheto. Egy mutato-listat letrehozva le kell tarolni minden lefoglalt cimet.
Amikor uj cimet hozok letre, erdemes vegignezni a listat, hogy nem esik bele valamelyik mar letrehozott memoria reszbe az uj kezdocim. Igy kiszurheto olyan rejtett memoria hiba, ami akkor keletkezik ha lemasolok egy pointert, de az eredetit felszabaditom. Ez kezdo hiba, de barki tevedhet. A program viszont eszre fogja venni a tevedest. Termeszetesen a delete-nel a a listabol torolni kell a mutatot.
Ezt a modszert kiegeszitve azzal, hogy minden sajat new hivasnak nevet adok, a nem felszabaditott memoriat barmikor ki lehet listazni.
Nevadas helyett lehet hasznalni a __line__ __file__ __function__ makrokat, amikkel a felszabaditatlanul maradt new utasitas pontos helyet vissza lehet kovetni.Ezzel az ket egyszeru modszerrel szinte az osszes memoria bug kiirthato egy akarmilyen bonyolult programbol.
-
3man
csendes tag
"Igy kiszurheto olyan rejtett memoria hiba, ami akkor keletkezik ha lemasolok egy pointert, de az eredetit felszabaditom. "
Az kifelejtettem, hogy ennek a kiszuresehez minden [] operatornal ellenorizni kell, hogy az adott pointer benne van-e meg a listaban. Ez nagyon lelassitja a programot, de ezt eleg csak akkor futtatni, ha valamilyen bug van a programban.
Egy rutinos programozo mondhatna erre, hogy ilyen hibak nala nem fordulhatnak elo. En erre csak azt mondom, sose lehet tudni.
-
Karma
félisten
Nem azért mondom (nem is tudom, van külön C++ topik is?), mindössze az, hogy ez tényleg sokkal körülményesebb C-ben. Egyébként én meg (Symbian) a HookLoggert szoktam használni, ha memory leakre vadászom: a saját kódom módosítása nélkül végzi el ugyanezt, amit Te az előbb manuális módszerként leírtál. (Rendszerszinten áll rá az Alloc/Free-re).
Linuxon és tsa. másik alternatíva lehet még a Valgrind is.
“All nothings are not equal.”
-
Sk8erPeter
nagyúr
Értem, köszi!
(#1428) 3man: még C++-hoz nem konyítok, de csak érdeklődésképp kérdezem, hogy miért nem egyszerűbb a túlindexelés elkerülésére osztály létrehozása helyett mindig "kényszerűen" átadni a tömbméretet is mondjuk függvénynek, vagy végigszaladni a tömbelemeken a lezáró nulláig, hogy megtudjuk, hány eleme van, és utána ezzel dolgozzunk?
Sk8erPeter
-
Karma
félisten
válasz Sk8erPeter #1433 üzenetére
Nem nekem szól a kérdés, de azért van pár ötletem:
1) Méretet átadni stack/statikus tömböknél redundáns információ (sizeof() megmondja).
2) Egyébként is, ezt a "belső" információt kívülről átadni csak még egy hibaforrás.
3) A \0 karaktertömböknél elmegy (bár nem 100%-os biztonság), pointertömböknél már körülményesebb (mi van, ha nincs tele a tömb? Mivel töltöd fel?), egyéb tömböknél meg teljesen megvalósíthatatlan önmagában.Az igazi megoldás tényleg a tömbosztályok használata, de osztályok (szintaktikailag) csak a C++-ban vannak. Szemantikailag viszont megoldható C-ben is egy kis gondolkodással: struktúrával és az azt manipuláló függvényekkel - bár szerintem nem találom fel a spanyolviaszt, biztosan más már írt ilyet.
“All nothings are not equal.”
-
Sk8erPeter
nagyúr
Abból indultam ki, hogy nekünk azt erőltették, hogy ha akár statikus tömbökkel is dolgozunk (persze, nem a pointertömbökre gondoltam ), és azokat adjuk át a függvényeknek, akkor lehetőleg adjuk át a méretét is, mert így könnyebb kezelni (pl. ha iterátorral rohangászol végig a tömbelemeken, akkor mittomén, for ciklusban a feltétel lehet az, hogy i<meret, stb. - persze úgy is lehetne, hogy tomb[i] != '\0' ), nem kell a függvényen belül is sizeof()-fal p×csölni, és így esetleg pl. main()-ben mondjuk elég egyszer sizeof-olni (talán ez gyorsaság szempontjából is érdekes lehet, fene tudja). Ez nem lehet elfogadható szempont? A 2-3. pont mondjuk teljesen igaz.
[ Szerkesztve ]
Sk8erPeter
-
Badb0y
addikt
Valaki hozzáértő ezt össze tudja dobni ?
Készítsen olyan FARM-ot leíró osztályt, melyben három fajta állatot tartanak nyilván.
A FARM-on végezhető műveletek:- AddMarha (név, kor, tejhozam) új marha felvétele
- AddLo (név, fogszám) új ló felvétele
- AddTyuk (név, tojáspernap) új tyúk felvétele
- Kill(név) Egy, a megadott nevű állat lemészárlása
- List () a még élő állatok attribútumainak listázásaÉletmentő lenne
[ Szerkesztve ]
Minőségi laptopok https://notebookokhu.business.site/
-
doc
nagyúr
ezt milyen megfontolasbol irtad a 'C' topicba? az osztaly ismeretlen fogalom a C-ben
ezzel inkabb a programozas totyikba menj, meg nem art leirni hogy milyen nyelvrol van szo, plusz az altalad eddig megalkotott kodot berakni, azt ne vard hogy valaki csak ugy megirja helyetted a hazidat -
3man
csendes tag
válasz Sk8erPeter #1435 üzenetére
Ha az osztaly tartalmazza a tomb meretet, akkor egy gonddal kevesebb, nem kell ra figyelni.
De ez ugyan az, mint amikor atadod kezzel. -
3man
csendes tag
válasz Sk8erPeter #1435 üzenetére
Minel kevesebb dologra kell figyelni kodolaskor, annal kisebb az eselye a tevedesnek.
-
Karma
félisten
válasz Sk8erPeter #1435 üzenetére
Hát nem tudom, oktatnak érdekes dolgokat Mondjuk production kódot még nem írtam/láttam sima C-ben, lehet hogy tényleg van ilyen konvenció.
De nem esküdnék meg rá. Nemrég láttam, hogy valahol a BME-n is goto-val tanítják a Pascalt! Akkora lett a fejem hogy csak na...
Egyébként az, hogy végigiterálsz a tömbön, még nem jelenti azt, hogy iterátorral dolgoznál. Az iterátor egy objektum-orientált minta. Röviden: ahelyett, hogy ismerned kéne a tömb/lista/stream/kismacska belső szerkezetét, és ezt figyelembe véve temérdek kódot generálnál, kérsz a kollekciótól egy iterátort, egy általános interfészt megvalósító objektumot, aminek ilyen műveletei vannak tipikusan: hasNext(), next(), removeCurrent(), satöbbi. Így szerkezettől független kódot tudsz írni
A szempontod egyébként jogos, de most hogy leírtam az előző blokkot leesett, hogy igazából miért is jobb kézzel átadni a hosszt kívülről: ezzel egységesen lehet kezelni a fix méretű és a heapen lévő tömböket is!
“All nothings are not equal.”
-
3man
csendes tag
Termeszetesen debuggerekkel es tarsaikkal helyettesitheto a modszerem.
De amikor 10 netalan 100 kulso tesztelod van, akkor nem biztos, hogy ez kenyelmes modszer.
Mi a legegyszerubb megoldas?
Az AddVectoredExceptionHandler() -el elkapsz minden nem tervezett esemenyt, es logolsz minden fontos dolgot. A lefoglalt teruletek mutatolistaihoz rendelt nev alapjan barmilyen memoria hiba pontosan lokalizalhato akar ugy, hogy nem is debug modban fut a program. Egy callstack-hez hasonlo kovetes is beepitheto ebbe a logba.
Ugyan a debug mod azert van, hogy ezt elvegezze, de megeshet, hogy igy tul lassu a program. Ha a programot a vegleges formajaban kell tesztelni, akkor a debug mod mar kiesik, de a hiba megis egyszeruen detektalhato.[ Szerkesztve ]
-
bama
csendes tag
Hi 3man!!!
Segitesz a progiba???
void isPrim(int number){
if (number <<4){
return number;
for(int i=4, i*i<number,i++);
if(number % i=0)
return 0;
return 1;
}Thanx
-
Sk8erPeter
nagyúr
Nem, BME-n kifejezetten és erősen tiltják a goto utasítás használatát! Ezt a tanárok "halálfejes hibának" nevezik, ha ilyet teszel a ZH-dba, akkor rárajzolnak egy halálfejet (egyébként tényleg rárajzolják, ZH-megtekintésnél pár papíron láttam is ), és arra a feladatra - akármilyen szép is a többi része - eleve 0 pontot adnak. (olyan esetekben is kapsz ilyet, ha nem szabadítod fel a dinamikusan lefoglalt memóriát, amikor kellene, vagy inicializálatlan változóval dolgozol, stb.)
Elképzelhető, hogy régebben volt olyan tanár, akinek nem verték a fejébe, hogy goto-t nem használunk, de szerintem most már selejtezik az ilyeneket.
Pascalt nem is tudom, tanítanak-e még egyáltalán... Villamosmérnöki és Informatikai Karon biztos, hogy nem, ott C-vel kezdenek. De én úgy tudom, hogy még az építészek is alap C-t tanulnak. Pascalról mostanában egyáltalán nem hallottam, hogy valahol tanítanának még BME-n.A lényegre térve nem igazán értem, miért olyan nagyon hibás az elképzelés, hogy kívülről adjuk meg a függvénynek a méretet. Jahh, de az utolsó bekezdésben azt írod, hogy végül is van elfogadható érvelés erre is: akkor tehát mégis jó úgy?
Az "iterátor" szót lehet, hogy rosszul használtam, de arra az elemre gondoltam, amivel bejárod a tömböt.A goto utasításra visszatérve: tudom, hogy a használata egy undormány-hányadék hiba, és soha nem is tettem, mert direkt meg se néztem, hogy kell azt egyáltalán De érdekelne, konkrétan milyen szempontból oltári baromság a goto használata. Úgy emlékszem, hogy futásidejű összeomlásokat eredményezhet, meg hasonlókat, de a pontos érveket már elfelejtettem.
(#1442) 3man: értem, köszi. Tehát akkor érdemes mégis kézzel átadni (ha sima C-ben programozol) a tömbméretet, ugye?
(#1446) bama: most mi a kérdés? Egyébként ha ez egy prímtesztelő függvény, akkor szvsz elég furcsa, minek kell 4-gyel shiftelni a számot...
[ Szerkesztve ]
Sk8erPeter
-
kovsol
titán
válasz Sk8erPeter #1447 üzenetére
goto val ugyan az a helyzet itt nálunk is
persze mikor assembly óra van ott ugrások nélkül kivitelezhetetlen a dolog de ugye ez itt a C topicMay the Force be with you!
-
dabadab
titán
válasz Sk8erPeter #1447 üzenetére
A goto azert nem jo, mert tonkrevagja a program strukturajat, ami nehezebbe teszi a hibakeresest, a kod karbantarsat es megerteset is.
Azt mondjuk nem art nem elfelejteni, hogy Dijsktra '68-ban irta "Go To Statement Considered Harmful" cimmel megjelent levelet, amikor a strukturalt programozas meg nem volt igazan mainstream es teljesen hetkoznapi volt a spagettikod, amiben gotoval ugraltak ossze-vissza. Bizonyos helyzetekben azon a goto hasznos lehet, mert eppen pont az adja a leghatekonyabb vagy a legattekinthetobb kodot - annak idejen a Kandon is belefutottam abba, hogy gyakorlaton instantegyes volt a goto, eloadason meg a quicksortbol egy gotos verziot prezentalt a tanar, mert az volt a legegyszerubb.
Mindent osszefoglalva, a goto elleni liheges mara nagyreszt okafogyotta valt (ma mar senki nem hasznalja ugy, ahogy a hatvanas evekben), az ellene valo horges mogott pedig ritkan talalni ertelmes okokat.DRM is theft
-
Karma
félisten
válasz Sk8erPeter #1447 üzenetére
Tudom hogy VIK-en mi a helyzet, én is informatikus-hallgató vagyok (félig) Viszont egy másik fórumozónak segítettem Pascalban, és ő másolt be órai kódot, ami hemzsegett tőle. Nem mondta el, melyik szak, én részemről GTK-ra tippelnék, vagy TTK-ra.
Nem hibás elképzelés! Sőt, mint írtam az üzenetem végén, ha egységesen akarod kezelni a stacken, globálisan és a heapen lévő tömböket, akkor nincs is nagyon más lehetőséged rá. Hacsak nem varázsolsz struktúrákkal, és írsz OO kódot nyers C-ben. Good stuff. Szóval teljesen jó.
Egyszerűen, ahogy 3man is mondta, amit nem Neked kell karbantartanod, az nem lesz hibalehetőség később. A KISS ("Keep It Simple, Stupid!") filozófia általában jó eredményeket hoz.
Értettem mire gondolsz az iterátor szóval , csak belejavítottam.
Apropó goto. Igazából a dolog kettős. Van olyan helyzet (főleg C-ben, meg ahogy kovsol is írja, assemblyben végképp), amikor előnyös a használata. Például hibakezelésre kivételek helyett, vagy brutálisan mély feltételeket szétbontani (Linux kernelben láttam most rá egy példát, amikor az előbb rákerestem). Viszont nem arra való, hogy a program teljes logikáját ezzel írja meg az ember, mint amit az említett órán csináltak ("ha a user 1-et ír be, kezdjük elölről a programot" jellegű varázs). Itt van róla egy hosszú, de annál érdekesebb leírás.
“All nothings are not equal.”
Új hozzászólás Aktív témák
Hirdetés
● olvasd el a téma összefoglalót!
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
Állásajánlatok
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest