- Samsung Galaxy Watch (Tizen és Wear OS) ingyenes számlapok, kupon kódok
- Samsung Galaxy S24 Ultra - ha működik, ne változtass!
- Android alkalmazások - szoftver kibeszélő topik
- VoLTE/VoWiFi
- Samsung Galaxy S23 és S23+ - ami belül van, az számít igazán
- Szívós, szép és kitartó az új OnePlus óra
- CMF Phone 2 Pro - a százezer forintos kérdés
- Egyszerre legnagyobb és legkisebb is a Garmin Venu X1
- Mobil flották
- Samsung Galaxy A52s 5G - jó S-tehetség
Új hozzászólás Aktív témák
-
Karma
félisten
válasz
Sk8erPeter #1490 üzenetére
Pedig ha azok a fogalmak megvannak, az első kérdésre is könnyebb válaszolni. Persze mindkettő C++ minta (sőt, a második csak és kizárólag Symbian C++-ban van), ezért C-nél még nem kavar be.
Auto pointer: egy olyan objektum, ami ha megsemmisül a stacken, magával ránt egy hozzárendelt heapen lévő objektumot is, így amikor az auto_ptr scope-on kívülre kerül, a másik objektum biztosan megsemmisül. Ez egy egyszerűsítés, így biztosan nem maradhat meg a heapen lévő objektum pl. azért, mert valahova berakott az ember még egy returnt, és elfelejtette felszabadítani ott is a memóriát
Valahogy így néz ki:
int valami()
{
int *valami_int = new int; // heapen hoztam letre, mint a malloc C-ben
auto_ptr<int> valami_ptr(valami_int); // az auto pointerre bizom a felszabaditast
...
// ugy hasznalom, mint egy pointert
*valami_ptr = 5; // a valtozo erteket valtoztatom itt
...
return 0; // valami_ptr megsemmisul -> valami_int is torlodik
...
return 1; // valahol mashol ugyanez lezajlik
}Ha nem lenne ez az auto_ptr, akkor mindkét return elé oda kéne írni explicite a következő sort (ez a free C++-os megfelelője), amit könnyen kifelejthet az ember, ha utólag hackelget bele a függvénybe, memory leaket okozva.
delete valami_int;
Cleanup Stack: Amikor a Symbiant írták, még nagyon fejletlenek voltak a C++ fordítók, kivételdobáskor a stacken lévő objektumokra nem hívódott meg a destruktor, ami mindenféle vicces hibához vezethetett, többek között "csak" memory leakhez. Ezért a nagyokosok kitalálták, hogy "csináljunk saját kivételkezelést!", megalkották a Leave-eket és a Cleanup Stacket.
Minden heapen lefoglalt objektumot, ami nem tagváltozó, fel kell kézzel rakni a CleanupStackre, és persze le is kell venni onnan, ha olyan műveletek jönnek, amik kivételt (konkrétan leave-et) dobhatnak. Tehát mindig figyelni kell a programozónak arra, hogy mikor mi van rajta, mikor melyik objektum kinek a felelősségébe tartozik, és ennek megfelelően variálni.
Na itt jön be, hogy ha több return utasítás van, akkor kitörhet a káosz, a függvény különböző részein más lehet a CleanupStack állapota, minden returnnél megfelelően adminisztrálni kell, és ha bármit változtatni kell, mindenhol át kell írni...
Példakód:
TInt CSomething::DoSomethingL()
{
TInt result = 0;
CSomethingBig *big = CSomethingBig::NewL();
CleanupStack::PushL(big);
RSomethingResource res;
CleanupClosePushL(res);
result = res->DoSomethingDangerousL(big); // ha ez dob egy leave-et, res bezarodik, big megsemmisul
CleanupStack::PopAndDestroy(2, big); // mindket elemet megsemmisiti
return result;
}Ezt a kódot nem magyaráznám túl, ha nem baj, hiszen csak random firkáltam. A lényeg az, hogy a PopAndDestroy hívást minden return előtt meg kell hívni, pontosan.
-
Karma
félisten
válasz
Sk8erPeter #1486 üzenetére
Eh, mondtam, hogy naív megoldás, azt nem, hogy jó is
Meg egyébként is csak firkáltam. -
Karma
félisten
válasz
Sk8erPeter #1478 üzenetére
Egy prímtesztelőnél vannak bonyolultabb függvények is
De ezt is meg lehet oldani egy returnnel.Itt egy nagyon naív példa:
int isPrime(int aNumber)
{
int result = 1; // T.F.H. igaz
int i;
int max = aNumber / 2;
for (i = 2; i <= max && result; i++) // kilépünk a ciklusból, ha a feltevés sérül
{
result = aNumber % i;
}
return result;
} -
Karma
félisten
válasz
Sk8erPeter #1476 üzenetére
Az exit tényleg durva. De ha már ott tartunk, számomra bevált az a gyakorlat, és egyébként is rengeteg konvenció azt is mondja, hogy a függvényeknek csak egyetlen returnje legyen, pont az átláthatóság miatt.
Egyszerűbb, ha az ember felelősségekkel tervez. Egy számot ellenörző függvénynek köze sincs a teljes program futásához (jó esetben, retardált feladatokat leszámítva), így oda értelemszerűen nem kerülhet exit. Igazából az alkalmazáslogikának 99%-ának semmi köze hozzá.
Ő "tanított", de nem programozni, hanem csak ledarálta a C nyelv alapjait. Szerencsémre az elv már korábban megvolt, Pascalban elég sokat versenyeztem, így a C nem volt nagy falat. Elővizsgával simán lenyomtam elsőre, meg általában a többi programozási tárgyat is.
-
dabadab
titán
válasz
Sk8erPeter #1454 üzenetére
"miért használsz mindenhol exit(0)-t?"
Mert kezdő
(Mondjuk a voidra definiált main()-re azért sikoltoznia kellene a fordítónak.)
Az exit() használata tulajdonképpen ugyanannyira problémás, mint a goto, ugyanazon okok miatt. -
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.
-
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. -
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 dologde ugye ez itt a C topic
-
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!
-
3man
csendes tag
válasz
Sk8erPeter #1435 üzenetére
Minel kevesebb dologra kell figyelni kodolaskor, annal kisebb az eselye a tevedesnek.
-
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. -
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.
-
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
-
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.
-
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.
-
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!
-
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 velemhogy 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
-
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?
-
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.
-
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?
-
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.
-
shev7
veterán
válasz
Sk8erPeter #1384 üzenetére
"ezt sem értem, mert dinamikusan is, futásidőben is lehet memóriát foglalni tömbnek, attól függően, hogy mondjuk mekkora egy másik tömb, aminek az elemeit át szeretnénk másolni egy új tömbbe, attól függően módosítjuk a foglalt memóriaméretet."
En ugy tudom, hogy tombre ilyet nem lehet. Ha azt mondom, hogy int x[5] akkor az elete vegeig 5 elemu tomb lesz. Sot en ugy tudom standard C-ben olyan sincs hogy
f(int x){
int array[x];
}Ellenben ha fogsz egy pointert akkor a pointerrel akkora teruletet foglalsz le amekkorat akarsz, es futasi idoben ugy varialod ahogy akarod.
Es a memoriakezelesrol:
Ha a tombodet nem globalis valtozokent deklaralod, akkor a tombnek a helyet a stack-en foglalja le. Ugyan ez igaz a pointer-re is, tehat a pointer altal mutatott cim is a stack-en lesz. Ellenben, ha a pointer-hez allokalsz memoriateruletet, azt mar a heap-en fogja lefoglalni. -
cellpeti
nagyúr
válasz
Sk8erPeter #1384 üzenetére
Az elején muzály választani,mert különben nem enged tovább!
-
Karma
félisten
válasz
Sk8erPeter #1384 üzenetére
A tömbváltozó alatt én az "array"-t értettem, ami gyakorlatilag egy pointer az első elemre. Ez a konstans, nem lehet elállítani onnan, ellentétben egy pointerrel.
Tehát nem lehet olyat mondani, hogy
array = pointer + 1; -
shev7
veterán
válasz
Sk8erPeter #1377 üzenetére
tomb merete fix
-
Jester01
veterán
válasz
Sk8erPeter #1133 üzenetére
1. azért mert unicode (akár utf8 akár utf16/ucs2) esetén nem 1 byte 1 karakter. Utf16 esetén továbbá sok 0 byte is előfordul ami C-ben sajnos a string végét jelzi.
2. nem fontos, de ha egyszer konstans, akkor miért ne
3-4. lásd a kollega válaszát fentebb
5. jó -
skylaner
senior tag
válasz
Sk8erPeter #1133 üzenetére
3-4
Mert a C automatikusan a string végére tesz egy '\0'-t, így tudja, h vége annak a stringnek.
Így n hosszú strignek n+1 nagyságú tömb kell.
Amikor pl te ezt írod,hogy: char a[]="abc" akkor a fordító automatikusan lefoglal +1 helyet még a \0-nak.char a[]="abc";
char b[]={'a','b','c','\0'};
printf("%d\n",sizeof(a)); // 4byte
printf("%d\n",sizeof(b)); // 4byte -
Jester01
veterán
válasz
Sk8erPeter #1107 üzenetére
Na itt az én verzióm, hogy ti is kötözködhessetek. Amit még én magamba belekötök, hogy lehetne még:
1. függvényekre szétszedni
2. a hosszú fájlneveket is (láncolt listával) kezelni
3. a tab-okat kezelni
4. locale beállításokat figyelembe venni
5. a kimenő fájlnevet szebben előállítani
6. parancssori argumentumokat kezelni -
Jester01
veterán
válasz
Sk8erPeter #1107 üzenetére
Szerintem a fájlod esetleg unicode lehet, az bekavarhat.
-
Benmartin
senior tag
válasz
Sk8erPeter #1107 üzenetére
Mert különbözik a compilerünk, kipróbáltam mielőtt elküldtem neked.
-
doc
nagyúr
válasz
Sk8erPeter #1100 üzenetére
ezt kimondottan C-ben akarod megirni, vagy csak a megoldas a fontos?
Linux alatt ez igy nez ki:cat *txt | cut -c 5-
vagy ha kulon txt-kbe kell a vegeredmeny is:
for i in *txt; do cat $i | cut -c 5- >vagott-$i ; done
-
Benmartin
senior tag
válasz
Sk8erPeter #1100 üzenetére
Elég általános kérdéseket teszel fel: "Hogyan születik meg a javított kimeneti fájl?" Hát úgy, hogy létrehozod a fájlt, erre mit lehet mondani?
1.) fgets
2.) Egyébként én úgy csinálnám, hogy magát a fájlneveket is kigyűjteném egy fájlba és abból olvasnám be, majd nyitnám meg a fájlokat.
3.) fopen("javitott.txt","w") -
Jester01
veterán
válasz
Sk8erPeter #975 üzenetére
Azért növelgetük egy tetszőleges számig, mert annyi darab pontot teszünk ki. Vagyis a kört 100 részre osztjuk. A teljes kör ugye 2*PI radián, ezért lesz a fi annyi amennyi.
A P futó pont koordinátái nyilvánvalóan azok, amik a setpixel hívásban szerepelnek.
Ha a képpont rajzolás már megvan (a setpixel, vagy bármi ami azzal ekvivalens) akkor a fenti for ciklus kirajzolja a kört, semmi egyebet nem kell csinálni.
-
Jester01
veterán
válasz
Sk8erPeter #973 üzenetére
Hát mert elírtam!
Nyilván nem az r megy 0-tól 2PI-ig, mert az állandó, hanem a fi. Uppsz.
Annyi lépésben amennyi pontra szükséged van. Ez is a kör egyenlete, ha behelyettesíted a tiedbe, akkor látszik (a sin^2 fi + cos^2 fi = 1 azonosság alapján)
Tehát pl. így lehetne ezzel kört rajzolni:for(i = 0; i < 100; i++)
{
double fi = i / 100.0 * 2 * M_PI;
setpixel(r * cos(fi) + u, r * sin(fi) + v);
}Ez a lépésszám függvényében lehet, hogy lukacsos lesz kicsit.
Van persze másik módszer is, de az szerintem macerásabb. -
doc
nagyúr
válasz
Sk8erPeter #961 üzenetére
tulajdonkeppen nem is kell kulon fuggveny, ha van egy ketdimenzios tombod, mondjuk char screen[80][25]; akkor ebbe irogathatsz, mondjuk screen[5][9]='X' az (5;9) koordinatan "kigyujt egy pixelt"
ha a rajzolas elott feltoltod sima space-ekkel, akkor mas dolgod nem is lesz, mint megcsinalni a "rajzolo" fuggvenyeket, amik a screen[x][y] elemet irva 'rajzolnak'
a vegen meg egy ciklussal siman kiiratni a tombot -
Jester01
veterán
válasz
Sk8erPeter #959 üzenetére
Persze, hogy nem tanultál a setpixel függvényről, azt neked kellene megírni
Induláshoz: a setpixelnek semmi más dolga nincs, mint a megfelelő tömbelembe egy X-et tenni. Kört legegyszerűbb az x = r cos fi, y = r sin fi, r=0..2 PI paraméteres egyenletből csinálni, téglalapot meg simán a négy egyenesből.
Az egészet nem fogom megírni helyetted, de ha elakadsz valahol akkor segítek.
MOD: de lassú vagyok
-
doc
nagyúr
válasz
Sk8erPeter #959 üzenetére
Jester pont errol beszelt
tehat a setpixel fv-t neked kell megcsinalni, ez annyit tesz majd hogy a megfelelo tombelemet pl. space-rol X-re allitja
kezdd a teglalappal, az egyszeru -
Jester01
veterán
válasz
Sk8erPeter #957 üzenetére
A platformfüggetlen megoldás az lenne, hogy csinálsz egy tömböt a memóriában ami a rajzfelületed. Implementálsz egy csoda setpixel függvényt ami kitesz egy képpontot ebben a tömbben. A rajzolás végén pedig sorban végigmész a tömbön és kiteszed a képernyőre. Azért kell ilyen körülményesen, hogy elkerüljük a kurzorpozícionálás problémáját.
Innentől kezdve a kör és a téglalapok rajzolása már triviális.
Ú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!
- LG 48GQ900-B - 48" OLED - 4K 3840x2160 - 138Hz & 0.1ms - G-Sync - FreeSync - HDMI 2.1
- Kaspersky, McAfee, Norton, Avast és egyéb vírusírtó licencek a legolcsóbban, egyenesen a gyártóktól!
- Telefon felvásárlás!! iPhone X/iPhone Xs/iPhone XR/iPhone Xs Max
- Bomba ár! HP ProBook 430 G5 - i5-8GEN I 8GB I 256GB SSD I HDMI I 13,3" I Cam I W11 I Garancia!
- Bomba ár! HP Elitebook 850 G8 - i5-11GEN I 16GB I 256GB SSD I 15,6" FULLHD I Cam I W11 I Gari!
Állásajánlatok
Cég: CAMERA-PRO Hungary Kft
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged