- Új 2 és 4 nm-es node-ot fejleszt a Samsung
- A GravaStar analóg klaviatúráira nem mondható, hogy konformisták volnának
- GeForce RTX 5050 kártyák az MSI portfóliójából
- Megérkezett a Phanteks új mikrotornya, akár kábeleket rejtő alaplapokhoz is
- Jövőre veti be az FSR 4-et a Sony a PlayStation 5 Pro konzolon
- Milyen asztali (teljes vagy fél-) gépet vegyek?
- DVB-T, DVB-S (2), DVB-C eszközök
- TCL LCD és LED TV-k
- Vélemény: nem úgy tűnik, de Lip-Bu Tan most menti meg az Intelt
- Milyen TV-t vegyek?
- Vezeték nélküli fülhallgatók
- A GravaStar analóg klaviatúráira nem mondható, hogy konformisták volnának
- Amazon Kindle
- Melyik tápegységet vegyem?
- Milyen videókártyát?
Új hozzászólás Aktív témák
-
kovisoft
őstag
válasz
buherton #6372 üzenetére
Az általad korábban linkelt szövegrészben is ez van:
"The result of the postfix ++ operator is the value of the operand. After the result is obtained, the value of the operand is incremented."
Nyilván a -- operátorra ugyanez igaz. Azaz teljesen egyértelmű a dolog: először kiolvassa num értékét (ezt fogja átadni a printf-nek), és csak ezután fogja csökkenteni num-ot. Ezért először 6-ot fog kiírni.
-
kovisoft
őstag
-
kovisoft
őstag
válasz
#90088192 #6278 üzenetére
Igazából processzor típusonként és C fordítónként is változhat, hogy melyik milyen algoritmust használ. De az eléggé általános, hogy valamilyen gyorsan konvergáló iteratív algoritmussal történik, nem pedig táblázatból olvassák ki. Régebben, még az FPU-k előtti időkben volt inkább jellemző pl. játékprogramokban a táblázatok használata, ahol nem volt szükség nagy pontosságra, viszont nagyon gyorsnak kellett lennie.
-
kovisoft
őstag
válasz
#90088192 #6272 üzenetére
A processzorok általában egy speciális iterációs algoritmussal számítják ki a szögfüggvényeket. Ezt úgy hívják, hogy CORDIC, aminek az az alapja, hogy a szöget felbontják olyan kisebb szögek összegére, amiknek a tangense 1/kettőhatvány. Az ilyen szögekkel történő forgatásnál a szorzást shifteléssel lehet helyettesíteni, ezért lesz hatékonyabb ez a módszer a Taylor-sor használatánál.
-
kovisoft
őstag
válasz
pmonitor #6244 üzenetére
Pedig mondott érveket, csak azokat a részeket rendre ignorálod.
És abban is teljesen igaza van, hogy 1 emberes home projektes tapasztalattal a hátad mögött nem látod át, hogy milyen egyéb szempontok merülnek fel egy több millió kódsorból álló, akár 100+ programozó által évtizedek alatt megírt, sok különböző ügyfél újabb és újabb igényeit kielégítő, folyamatosan változó rendszer programozása során. Amikor akkora a rendszer, hogy senki sem látja át részleteiben annak minden elemét, amikor az eredeti kód készítői már rég nincsenek a cégnél, amikor ha nem értesz valamit a kódban, akkor nincs is kitől megkérdezned, hogy mi volt a szerző (majd az eredeti kódot módosító tucatnyi más programozó) eredeti szándéka, stb. Ilyenkor nem az akadémiai szempontok a legfontosabbak, hanem hogy a kód minél olvashatóbb, minél könnyebben értelmezhető és karbantartható legyen.
-
kovisoft
őstag
válasz
pmonitor #6219 üzenetére
Ami részletet idemásoltál, abból nem nyilvánvaló, de itt az okokat jobban meg lehet érteni, ha megnézed a forráskód historyját. Ebből látszik, hogy eredetileg csak a switch volt ott, a goto és az előtte lévő rész hiányzott. Aki hozzáadta a raw függvényparamétert, az gondolom nem akarta, hogy az egyébként változatlan switch kompletten mint módosult kód jelenkezzen a historyban. Illetve (ami szintén nem látszik az idemásolt részleten) mivel a switch már így is elég nagy, eléggé tele van if-ekkel és eléggé be van indentálva, ezért az is lehet, hogy nem akart még egyet növelni az indentálás mértékén. Valószínűleg másképp csinálta volna, ha nulláról most írja meg az egész függvényt.
Szóval ez inkább a "történelmileg így alakult" kódra példa.
-
kovisoft
őstag
Ha karaktereket keresel egyesével stringben, akkor javaslom az strchr() használatát strstr() helyett, mert az strstr()-nek keresőstringet kell megadni, ezért nem fog működni const char restrictions[5] = {'a', 'b', 'c'} formával. Ezt láthatod is pmonitor kódjában, ha majd megnézed.
-
kovisoft
őstag
Azért nem működik így, mert az strstr() egy összefüggő rész-stringet keres meg az adott stringben, te pedig azt szeretnéd, hogy a megadott karaktereket külön-külön nézze meg, hogy benne vannak-e valahol a stringben, nem feltétlenül összefüggően és nem feltétlenül ugyanabban a sorrendben. Pl. ha "abc"-t keresel, azt az strstr() megtalálja az "aabcc"-ben, de nem találja meg az "aabbcc"-ben, mert ez utóbbinak az "abc" nem rész-stringje.
Azt kell csinálnod, hogy egy ciklussal végigmész a restrictions[] karakterein, és mindegyikre megnézed, hogy benne van-e a name-ben az adott karakter.
Szerk: lassú voltam
-
kovisoft
őstag
válasz
DopeBob #6140 üzenetére
Megpróbáltam lefordítani az eredeti kódodat, de nekem (treat warnings as errors beállítással) fordítási hibát dobott a scanf és a printf sorokra. Érthető, mivel az int (*statData)[statDay][OPEN_HOURS] egy kétdimenziós tömbre mutató pointer, nem pedig egy kétdimenziós tömb. A statData[i][j] nem egy int-et, hanem egy pointert jelent. Cast-olással kierőszakoltam, hogy leforduljon, valamint felcseréltem a statData deklarációjában a sorokat és az oszlopokat (int (*statData)[OPEN_HOURS][statDay]), és így már ez a változat is működött.
Ökölszabályként azt tartsd szem előtt, hogy amikor egy pointert deklarálsz, akkor azt tömbként is tudod használni (meg tudod indexelni [i] stílusban), tehát úgy is felfogható a dolog, hogy egy * ugyanúgy hozzáad egy dimenziót a deklarált tömbödhöz, mint egy [SIZE]. Fordítva is igaz a dolog: egy tömb utolsó dimenzióját lehagyva egy pointert kapsz.
Vagyis amikor ezt írod le: int (*statData)[OPEN_HOURS][statDay], akkor ez igazából egy 3 dimenziós tömb, aminek az első két dimenziója a fix [OPEN_HOURS] és [statDay], a harmadik dimenziója dinamikus, és ennek mérete a malloc-ban megadott értékből jön, ami jelen esetben [1] (mivel a teljes allokált méret OPEN_HOURS*statDay*1). Éppen ezért az így deklarált tömb elemeire ezen a módon kell hivatkozni: statData[i][j][0]. Kipróbáltam ezt is, és így is működik. Ezzel együtt nem javaslom ennek a formának a használatát, és nem is értem, hogy a Pluralsight miért így tanítja.
-
kovisoft
őstag
-
kovisoft
őstag
válasz
DopeBob #6138 üzenetére
Amikor egy szimpla 1 dimenziós tömböt allokálsz, akkor azt egy szimpla pointerbe rakod bele:
int *array = malloc(sizeof(int[ARRAY_SIZE]));
És utána array[i]-vel hivatkozol az elemeire. Ha ezt ki akarjuk terjeszteni 2 dimenzióra, akkor hozzáteszünk mindkét oldalhoz +1 dimenziót, de miért tennénk +2 dimenziót a bal oldalhoz?
int (*twod_array)[COLUMNS] = malloc(sizeof(int[ROWS][COLUMNS]));
Így a twod_array egy olyan pointer, ami "COLUMNS db integerből álló tömb" típusú adatra mutat, ilyenekből allokáltunk ROWS db-ot, és twod_array[i][j]-vel hivatkozunk az elemeire. Legalábbis szerintem így kell, de bevallom, nem próbáltam ki.
Viszont mint írtam, csinálhatod azt is, hogy te számolod át a 2 dimenziós indexet 1 dimenziósra, ekkor elég egy nagy 1 dimenziós tömböt allokálni:
int *simulated_twod_array = malloc(sizeof(int)*ROWS*COLUMNS);
Aztán így hivatkozol az i. sor j. oszlopára: simulated_twod_array[i*COLUMNS+j].
-
kovisoft
őstag
válasz
DopeBob #6136 üzenetére
Szerintem a malloc sorral van a gond. Ahogy írtad, úgy eggyel több az indirekció a bal oldalon (pointer egy két dimenziós tömbre, ami így egy három dimenziós tömbbel lesz analóg). Helyette ez kellene:
int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));
Másik lehetőség, hogy egy dimenziós tömböt használsz (szimpla pointert allokálsz) és [i*OPEN_HOURS+j] formában indexeled.
És a free-nél sem kell a csillag, csak simán free(statData).
-
kovisoft
őstag
válasz
Sültbanán #6132 üzenetére
Így van, ez pl. egy lehetséges megoldás. De a config.h a többi olyan include előtt legyen, ami használja a TEST makrót.
A lényeg, hogy amelyik .c-ben (vagy .c-be include-olt .h-ban) használni akarod a makrót, oda előtte már valahogy bekerüljön. Amit közvetlenül a main.c-be írsz be, azt nem látja az elso.c vagy a masodik.c. Tehát vagy mindegyik .c-be beírod a definíciót, vagy egy olyan .h-ba, ami include-olva van mindegyik .c-be. Nyilván ez utóbbi a szebb megoldás. A .c-be olyan esetben célszerű beírni, ha ettől a makrótól függ valami működés, és különböző .c-kben eltérő definícióra van szükség (pl. egyik .c-ben a TEST értéke 0, egy másikban 1).
-
kovisoft
őstag
1/
int sub();
Ez egy forward declaration, arra szolgál, hogy ha majd csak később lesz ténylegesen definiálva a függvény, amit már előtte használni akarsz, akkor ebből tudja a fordító, hogy milyen argumentumai vannak és milyen típusú értéket ad vissza. Mivel te áthelyezted a sub() függvényt a main() elé, így a te változatodban nincs rá szükség.2/ Egy függvény argumentumait deklarálhatod úgy is, hogy rögtön odaírod a nevük elé a típusukat, de úgy is, hogy csak a nevüket írod a zárójelbe, a típusukat ekkor külön meg kell adni a zárójel után és a nyitó kapcsos zárójel előtt. Jelen esetben a fun() függvénynek egy par nevű argumentuma van, aminek a típusa egy int-et visszaadó argumentum nélküli függvénypointer. Ennek lesz majd átadva a sub() itt:
fun(sub)
-
kovisoft
őstag
A linkelt thread safety problémák az 1.0.x openssl verzióra vonatkoznak, de 1.1.0 óta már nem kell locking callbackeket definiálni.
-
kovisoft
őstag
válasz
#90088192 #6106 üzenetére
Arra gondoltam, hogy egy korábbi hozzászólásodban így hívtad meg a write_char-t:
for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);
És ebben a második paraméterben használod a Font_width-et is, ezt lehetne kiiktatni, ha egy struktúrában úgyis átadod a font paramétereket. Ehhez át kellene alakítani egy kicsit a paraméterezést (pl. ahogy javasoltam: kettéválasztani egy y és egy j paraméterre, és a write_char függvényen belül elvégezni az y+j*Font_width számolást).
-
kovisoft
őstag
válasz
#90088192 #6104 üzenetére
Persze, teheted a font paramétereket egy struktúrába, és akkor elég átadni erre a struktúrára mutató pointert a font választáshoz (vagy csúnyább esetben mehet az egész egy globális változóba). Pl:
#include "font1.h"
#include "font2.h"
struct font_type
{
long int *font;
int font_width;
int font_height;
int font_offset;
};
struct font_type myfont[2];
myfont[0].font = Font1;
myfont[0].font_width = Font1_width;
myfont[0].font_height = Font1_height;
myfont[0].font_offset = Font1_offset;
myfont[1].font = Font2;
myfont[1].font_width = Font2_width;
myfont[1].font_height = Font2_height;
myfont[1].font_offset = Font2_offset;
int write_char(int page_select, int y_offset, int character_code,struct font_type *use_font)
{
...
send_data_screen(use_font->font);
...
}
write_char(line,y_offset+j*myfont[0]->font_width,test[j],&myfont[0]);
write_char(line,y_offset+j*myfont[1]->font_width,test[j],&myfont[1]);De lehet, hogy jobb lenne az y_offset paramétert szétszedni egy y és egy j paraméterre, és a font_width-tel való szorzást beletenni a függvénybe, hogy ne kelljen azt is font-tól függően átadni:
int write_char(int page_select, int y, int j, int character_code,struct font_type *use_font)
{
int y_offset = y+j*use_font->font_width;
...
send_data_screen(use_font->font);
...
} -
kovisoft
őstag
válasz
#90088192 #6101 üzenetére
Ha jól értem, paraméterben szeretnéd átadni a write_char() függvényednek azt, hogy milyen betűkészletet használjon. Ehhez össze kell szedned, mi definiálja a betűkészletet. Egyrészt a Font[] tömb, másrészt a Font_width, Font_height, Font_offset (ha nem hagytam ki valamit). Ezeket fel kell venned még plusz paraméterként és átadnod a write_char()-nak, pl:
int write_char(int page_select, int y_offset, int character_code,
long int *font, int font_width, int font_height, int font_offset)És így tudod pl. meghívni:
write_char(line,y_offset+j*Font_width,test[j],Font,Font_width,Font_height,Font_offset);
Mivel az y_offset számolásában is használod a Font_width-et, így szebb lenne ezt a függvényen belül végezni.
Ha pedig mindegyik betűkészlet ugyanolyan méretű, akkor elég csak a font tömböt átadni, nem kellenek a betűméretek.
-
kovisoft
őstag
válasz
#90088192 #6095 üzenetére
Szerintem csak annyi a gond, hogy a data_read() egy függvény, aminek a visszatérési értékét (ill. ehhez hozzácsapva még biteket) akarod átadni a send_data_screen()-nek. Viszont hiányzik a "()", így ténylegesen nem hívod meg a data_read-et, hanem a függvény címét adod át. Próbáld meg így:
send_data_screen(data_read() | (BASE_ADDRESS_PIXEL << x%Display_pages));
-
kovisoft
őstag
válasz
dabadab #6092 üzenetére
Pont hogy akkor még akár jó is lehetne, mert ugyan a külső do...while-ra nincs szükség, de nem is okoz gondot, ha pontosan 1x lefut. És helyes for esetén egy while (i==999) feltétellel csak 1x futna le, mert mire ideér a vezérlés, az i értéke 1000 lesz, tehát kilép a do...while-ból.
Persze nyilván baromság így, írtam is, hogy fölösleges a do...while, csak arra akartam felhívni a figyelmét, hogy keveri az értékadást (=) és az egyenlőségvizsgálatot (==).
-
kovisoft
őstag
válasz
Gabesson #6089 üzenetére
1. A külső do...while-ra nincs szükség (amúgy sem jó, mert a feltételben a szimpla = jel értékadás, nem pedig egyenlőségvizsgálat, ami a dupla == lenne).
2. A belső for feltétele nem jó, mert itt is az i=999 feltételben a szimpla = értékadás. Amúgy sem egyenlőség, hanem <= vizsgálat kellene, és ha 3-jegyű számokat akarsz, akkor nem 0-tól, hanem 100-tól kellene indítani:
for (i=100; i<=999; i++)
3. A for után, de még a nyitó { előtt van egy pontosvessző, ez nem kell ide, emiatt üres a for belseje.
4. A végső feltételvizsgálat és a printf a for ciklus belsejében kellene, hiszen minden egyes i-t meg akarsz vizsgálni.
Szerk.: lassan gépeltem
-
-
kovisoft
őstag
válasz
Gabesson #6085 üzenetére
Egy for ciklussal mész i-vel 100-tól 999-ig. A számjegyeket pl. így kapod meg:
- szazasok = i/100, azaz a szám 100-zal maradékosan osztva
- tizesek = (i%100)/10, ahol i%100 levágja a százasokat, majd ezt osztjuk maradékosan 10-zel
- egyesek = i%10, ami levágja az egyesek fölötti részt -
kovisoft
őstag
válasz
nucso02 #6081 üzenetére
Azt írod, 1 szolga - 1 mesterrel már megy. Elmondod, hogy mi a probléma több szolga esetén? Van hely az osztott memóriában mindegyik szolga pid-jének (pl. tömb)? Beírja ide a saját pid-jét induláskor mindegyik szolga (ill. kiveszi innen kilépéskor)? Szöveg beírása után el van küldve a signal az összes ide beregisztrált szolga pid-nek?
-
kovisoft
őstag
válasz
csoki98 #6069 üzenetére
Úgy látom, nem kaptál erre itt választ, szerintem nem is nagyon fogja senki helyetted megírni (én legalábbis nem
), mert az oktatásnak pont az a lényege, hogy magadtól csináld meg, max ha eladkadsz, akkor szívesen segítünk. Ezért inkább csak gondolatébresztőnek felvázolnám egy lehetséges megoldás menetét:
- Létrehozol egy tömböt, ebbe fogod pakolni a fájlból beolvasott számokat. Itt kapásból gond lehet, ha tetszőlegesen nagy fájlod lehet, ekkor ugyanis dinamikusan kell a tömb méretét kezelni és a tömböt allokálni, de gondolom elfogadják azt is, ha szimplán egy fix és elég nagy méretű tömböt definiálsz (pl. int numbers[10000]).
- Megnyitod olvasásra a fájlt (fopen "r" módban), majd egy ciklussal soronként beolvasod a tartalmát. Minden egyes számot a beolvasás után át kell konvertálni egész típusra (a fájlban szövegesen van tárolva), de olvashatod fscanf-fel is (a "%d" formátumvezérlővel), ami rögtön egészre is konvertál. Olvasási módtól függően ügyelni kellhet a sorvége karakterek "lenyelésére". A számokat egyesével belerakod a tömbödbe a soron követhező pozícióba, ehhez kell egy indexváltozó, ami 0-ról indul és amit minden szám beolvasása után megnövelsz 1-gyel, amíg a fájl végére nem értél (azaz hibára fut az olvasás). A legvégén ez a változó mondja meg a tömbben lévő elemek darabszámát.
- A rendezést végezheted egy könyvtári függvénnyel is (qsort), de magad is írhatsz egy egyszerű buborékos rendezést. Ha kell, részletesen elmagyarázom a buborékos rendezés menetét is.
- A rendezés tehát helyben történt a tömbödben, ezt kell kiírni egy másik fájlba. Megnyitod írásra a kimeneti fájlt (fopen "w" módban), majd egy ciklussal mész a tömbbe került elemek darabszámáig, és fprintf-fel kiírod az aktuális számot a fájlba ("%d\n" formátumvezérlővel, ez egy sortörést is a szám után tesz).
- fclose-szal lezárod a megnyitott fájlokat és kész vagy. -
kovisoft
őstag
válasz
borisz1994 #6061 üzenetére
Csak akkor kell külön deklarálnod a függvényt, ha hamarabb akarod használni, mint ahogy definiálva lenne vagy ha egy másik modulban van a tényleges definíció. Ellenkező esetben a definíció már maga a deklaráció is.
-
kovisoft
őstag
válasz
borisz1994 #6057 üzenetére
A többiek már leírták, hogy alapvetően jól fogalmaztad meg a deklaráció és definíció közötti különbséget, de a változóval kapcsolatos következtetésed nem helyes.A példádban az
int pelda=0;
és azint pelda;
egyaránt definíció, mindkettő lefoglal a változónak memóriát, a különbség köztük annyi, hogy az első ad is egy 0 kezdőértéket a változónak. Ennek a változónak a deklarációja ez lenne:extern int pelda;
Ez nem foglal le memóriát a változónak, csak annyit mond, hogy valahol máshol van definiálva egy pelda nevű változó, aminek int a típusa. A deklaráció tehát ahhoz kell, hogy az adott helyen tudj használni egy változót vagy függvényt, de valahol máshol kell majd definiálnod is azt. -
kovisoft
őstag
válasz
jattila48 #6041 üzenetére
Egy 6x6-os rács esetén 9 db lyuknak kell lennie, amiknek úgy kell elhelyezkedniük, hogy 90 fokokkal elforgatva ne kerüljön egyik lyuk sem fedésbe bármely másikkal. Tehát minden egyes lyuk hozzáadása kizár (saját magával együtt) 4 pozíciót. Az első lyuk 36 helyen lehet, a következők 32, 28, ... stb. helyen, ami összesen 36*32*28*...*4*1. Viszont a lyukasztási sorrend nem számít, ugyanazt a rácsot kapjuk, bármilyen sorrendben lyukasztjuk ki a kiválasztott 9 pozíciót. Tehát az össz kombinációt el kell osztanunk 9!-sal: 36*32*28*...*4*1/9! = 262144.
Már ha jó a gondolatmenetem...
-
kovisoft
őstag
válasz
elistvan #6038 üzenetére
A kódolandó szöveg 3x36 karakterből áll. Mivel egy 6x6-os rács 36 karaktert tartalmaz, így 3 db rács fog keletkezni a kódolás során. A kódolás menete a következő: Megfordítod a kódolandó szöveget (amely tehát így fog kezdődni: HAZRXT...). Veszed a Cardano-rácsot (amiben 0-k és1-esek vannak), ill. veszed sorban a megfordított szöveg karaktereit. Létrehozol egy újabb 6x6-os tömböt, és belerakod sorban a karaktereket arra az [i][j] pozícióra, ahol a Cardano-rácsban 0 van (pl. első sor 2., 4., 6. eleme, második sor 5. eleme, stb, összesen 9 db). Amikor végigértél a Cardano-rácson, elforgatod jobbra 90 fokot, és megismétled az eljárást a következő 9 db karakterre. Ezt megcsinálod négyszer, és elfogyott a megfordított szöveg első 36 karaktere. A maradék 2x36 karakterhez létrehozol egy-egy újabb 6x6-os tömböt, és kitöltöd ugyanezzel a módszerrel. A végén előáll 3 db 6x6-os tömböd, ezeket kell kiírnod a sandormatyas.txt file-ba (tippre soronként).
-
kovisoft
őstag
válasz
jattila48 #6033 üzenetére
Ha pia egy másik függvényben van, akkor ott nem látod az eredeti tömböket. Lehet pl. pia egy függvény paramétere, és fontos, hogy szigorúan egy adott méretű tömb legyen neki átadva.
Egyébként ha ez most már arra megy ki, hogy hogyan lehet elkerülni tömbre mutató pointer használatát, arra én is tudok módszereket mondani, ilyen vitában nem kívánok részt venni. De eredetileg mintha azt kérdezted volna, hogy mire lehet használni. Továbbra is az a válaszom, hogy olyan esetben, amikor számít a megcímzett tömb sizeof-ja.
-
kovisoft
őstag
válasz
elistvan #6018 üzenetére
A 6x6-os kulcsot (cardano.txt) beolvashatod egy 6x6-os tömbbe (pl. char cardano[6][6]). Ugyanígy beolvasod a titkos.txt szöveget egy másik 6x6-os titkos[6][6] tömbbe. A 90 fokkal való forgatás úgy történik, hogy felcseréled a két koordinátát és az egyiket "megfordítod" (azaz 5-ből kivonod). Attól függően lesz jobbra vagy balra forgatás, hogy melyiket vonod ki 5-ből, pl. jobbra forgatás: [i][j] -> [j][5-i]. A dekódolás úgy történik, hogy mész végig sorfolytonosan egyszerre a cardano tömbön és a titkos tömbön, és ahol a cardano-ban 0 van, a titkos-ból ugyanarról a pozícióról kiolvasol egy karaktert. Ha végigértél a tömbön, akkor veszed a 90 fokkal elforgatott kulcsot, és azza újra végigcsinálod ezt, stb.
-
kovisoft
őstag
válasz
kunzoltan77 #6015 üzenetére
Az az alapvető baj a függvényeddel, hogy anélkül vizsgálod az egyes karaktereket, hogy figyelembe vennéd azt, hogy az adott karakterkombináció milyen pozícióban fordulhat vagy nem fordulhat elő. Pl. mi van, ha az 1:1 kétszer is szerepel a sorban? Akkor el fogod fogadni, holott csak egyszer fordulhatna elő eredmény. Vagy mi van, ha az 1:1 a csapatok neve előtt van? Akkor is elfogadod. De ugyanez igaz a szóközös vagy a kötőjeles vizsgálataidra is.
Olyasmit kellene csinálnod, hogy a string elemzése közben nyilvántartod, hogy éppen milyen állapotban vagy, azaz éppen milyen alkotórészt azonosítasz. Legelőször a hazai csapatot kell azonosítani, addig nem is jöhet pl. kettőspont. A szabályos hazai csapatnév után az elválasztó szóköz-kötőjel-szóköznek kell jönnie. Utána a vendég csapatot kell azonosítani, közben sem jöhet pl. kettőspont. Ha megvan a szabályos vendég csapatnév, akkor a hazai eredményt kell azonosítani, amiben viszont csak számjegy lehet. Aztán kettőspont kell jöjjön. Végül a vendég eredményt kell azonosítanod, abban is csak számjegy lehet. Utána meg már nem lehet más.
Tehát mindig attól függ, miket fogadsz el, hogy éppen melyik mező azonosítása közben vagy.
-
kovisoft
őstag
válasz
elistvan #6000 üzenetére
Itt egy példa a nyerőszámok húzásának függvénybe való áthelyezésére:
void nyeroszamok_huzasa(int nyeroszamok[], int darab){
for(int i=0;i<darab;i++){
int num = (rand() % (80 - 1 + 1)) + 1;
if(num >= 1 && num <= 80 && !tartalmazza(nyeroszamok,darab,num)){
nyeroszamok[i] = num;
}else{
i--;
}
}
}És így tudod meghívni onnan, ahol korábban maga ciklus volt:
int nyeroszamok[20] = {0};
nyeroszamok_huzasa(nyeroszamok, 20);Hasonlóan mehet a többi blokk is, de lesz köztük olyan függvény, aminek több tömböt is át kell majd adni, mint pl. a találatok meghatározása, ami 3 tömbbel dolgozik: tippeltszamok, nyeroszamok, talalat.
A rand() használatához még annyit, hogy ez alapból mindig ugyanonnan indítja a generálást, tehát minden futásra ugyanazt a szekvenciát kapod. Ezért célszerű seed-elni az első hívás előtt valami futásonként eltérő számmal, pl. az aktuális idővel, hogy mindig más random szekvenciát kapj:
srand(time(0));
-
kovisoft
őstag
válasz
elistvan #5998 üzenetére
Ebben a programban jelenleg elég sok hiba van. Hirtelen néhány: A tartalmazza() függvényben a tomb címét hasonlítod a szam-hoz, nem a tomb egy elemét, itt tomb[i] kellene. Végig a kódban keverednek az íves (függvényhívás) és a szögletes (tömb eleme) zárójelek, ez így le sem tud fordulni. Mint pl. itt:
tippeltszamok(i) = szam;
vagy itt:
if(tippeltszamok(i) == nyeroszamok[j]){
A nyeroszamok-at fölöslegesen rakod át az emelkedo-be, mert már helyben rendezted azokat (ezért kiírni is fölösleges mindkettőt).
Függvényekkel rövidíteni akkor tudod, ha több ismétlődő feladatot hajt végre a programod. Itt maximum a számok kiírása az ilyen, tehát sok rövidítésre nincs lehetőség, így gondolom inkább arról lenne szó, hogy függvényekkel struktúráld a programod (ettől nem rövidebb, hanem olvashatóbb lesz). Be kell azonosítanod az egyes blokkokat a programodban, amik egy önálló részfeladatot hajtanak végre, és ezeket ki tudod emelni egy-egy önálló függvénybe. Most kb. ezeket csinálja a programod:
- tippek bekérése
- tippek kiírása
- nyerőszámok húzása
- találatok megkeresése
- nyerőszámok rendezése
- nyerőszámok kiírása (elég 1x)
- találatok kiírásaEzekre írhatsz függvényeket, amik megkapják bemenő paraméterben tömbö(ke)t, amivel dolgozniuk kell, hasonlóan a tartalmazza() függvényedhez. De ezek a függvények nem adnak semmilyen értéket vissza, void lesz a visszatérési típusuk és nem lesz bennük return.
-
kovisoft
őstag
válasz
DEV_NULL #5996 üzenetére
Remek! Még annyit lehet egyszerűsíteni, hogy a beolvasásnál egy füst alatt el lehet intézni a rendezést is és az egyező számok kiszűrését is:
Beolvasod a következő számot, megkeresed az első olyan szám indexét a (rendezett) tömbödben, aminél nem nagyobb. Ha megegyezik vele, akkor eldobod, mert van már ilyen szám. Ha pedig kisebb nála, akkor ettől az indextől kezdve eggyel hátrébb pakolod a számokat a tömbben, és beszúrod ide a beolvasott számot.
És ne feledkezz meg az adatok ellenőrzéséről sem, pl. mi van, ha 50-nél nagyobb számot adnak meg méretnek? Ekkor ki fogsz címezni a tömbödből.
-
kovisoft
őstag
válasz
DEV_NULL #5994 üzenetére
Szerintem a gond még azzal a résszel van, ahol kiszűröd az azonos számokat és csak a különbözőket pakolod át a hazi.cim-ből a hazi.cim2-be (ahol az ominózus ++ is van). Nem elég átrakni a ++-t a végére, hanem kicsit át kell alakítani magát a ciklust is, hiszen így most a 0-dik cim2 elembe belerakod a 0-dik és az 1-ső cim elemet is (a legelső elvész). Mivel a hazi.csere=0 elemet már a ciklus előtt átraktad, ezért a ciklust hazi.csere=1 értékről kellene indítani.
Sokat segíthet, ha debug kiíratásokat helyezel el a kódban az egyes lépések után. Pl. kiírod a rendezett elemeket, az azonos elemek kiszűrése után maradtakat, ill. azokat a számnégyeseket, amikre egyeznek a megkívánt összegek. Ezekből látni fogod, hogy melyik lépésnél romlik el valami.
-
kovisoft
őstag
válasz
DEV_NULL #5992 üzenetére
Csak tipp, de szerintem a lenti sorban kicímzel a hazi.cim2 tömbből, ugyanis amikor hazi.csere=hazi.meret2-1, akkor a ++ miatt hazi.cim2[hazi.meret2] lesz felülírva, de az már az allokált tömb után van:
hazi.cim2[++hazi.csere]=hazi.cim[h];
Elképzelhető, hogy elég lenne a ++-t hátulra tenni (hazi.csere++), de mondom ezt úgy, hogy nem értelmeztem, mit csinál pontosan a programod.
-
kovisoft
őstag
válasz
#PeTeY# #5989 üzenetére
Az i=0,1,...,n-1 sorozatot úgy fordítod meg, hogy i helyett n-i-1 -et használsz (i=0 --> n-i-1=n-1, i=n-1 --> n-i-1=0). És akkor mindenhol indulhat minden i-s és j-s ciklusod 0-ról egyesével felfelé, és a sorokat úgy fordítod meg, hogy i helyett n-i-1 -et használsz az indexben azokon a helyeken, ahol a kulcs-csal is indexelsz.
Persze nem muszáj így, csinálhatod azt is, hogy marad az i az indexben, de az i-s ciklusod n-1-ről indul lefelé 0-ig. A végeredmény ugyanaz lesz.
-
kovisoft
őstag
válasz
#PeTeY# #5987 üzenetére
Akkor gondolom sztornó, amit írtam, ha végülis maga a kódolás jó úgy, ahogy csináltad.
A kódolásnál eredeti sorrendben ([i][j]) töltöd fel a tomb tömböt és a kulcs szerint indexelve ([n-i-1][kulcs[j]-1]) olvasod ki.
Dekódolásnál fordítva kellene csinálni: a kulcs szerint indexelve ([n-i-1][kulcs[j]-1]) töltöd fel a tomb tömböt és eredeti sorrendben ([i][j]) olvasod ki.
-
kovisoft
őstag
válasz
#PeTeY# #5985 üzenetére
Ha jól értem, hogy mit szeretnél, akkor szerintem nem a második dupla ciklusban (amikor a ki2-be írsz) kellene alkalmazni a
kulcs[j]-1
-gyel való indexelést, hanem az első dupla ciklusban, amikor kitöltöd atomb
-öt (és persze ekkor oda kell figyelni arra is, hogy a ki file-ba továbbra is a jó karaktert írd ki):for (i=0; i<n; ++i) {
for (j=0; j<kod; ++j) {
tomb[i][kulcs[j]-1]=szoveg[count];
fprintf(ki, "%c ", szoveg[count]);
count=count+1;
}
fprintf(ki, "\n");
}
A ki2-be történő kiírásnál pedig már csak szimplán kiszedni a j-edik oszlopot. Mert így most pont a kulcs inverz permutációját hajtod végre.
-
kovisoft
őstag
válasz
#PeTeY# #5983 üzenetére
Mit jelent, hogy "de nem alulról felfelé"? A sorokat fordított sorrendben kellene kiírni? Ebben az esetben haladj fordított sorrendben a legutolsó i-s ciklusoddal:
for(i=n-1; i>=0; i--) {
A másik lehetőség, hogy a tomb-ből olvasod ki tükrözve a sorokat:kodolt[l] = tomb[n-i-1][kulcs[j]-1];
-
kovisoft
őstag
C-ben nem tudsz így stringeket összehasonlítani, mert a kar != "end" a két stringre mutató pointert hasonlítja össze, nem pedig a stringek tartalmát. Használd az strcmp() függvényt stringek összehasonlítására (vagy strcmpi-t, ha nem számít a kis-nagybetű):
} while (strcmp(kar, "end") != 0);
-
kovisoft
őstag
válasz
elistvan #5963 üzenetére
A szazalek valtozot nem int-nek vetted fel, hanem float-nak. Egy osztás eredménye kerül bele, ezt hasonlítod utána egész számokkal. A konkrét esetben valóban csak egész szám kerülhet bele (mivel az osztást és a szorzást is int-eken végzed), de amúgy ha a képletben már eleve float-okkal dolgoznál, és mondjuk 47 pont lenne a maximum, amiből valaki 28-at ért el, akkor a szazalek értéke 59.57 lenne, ami se nem <=59, se nem >=60, hanem a kettő között van, de arra nincs feltételed. Ezért írtam, hogy jobb lenne csupa int-ekkel dolgozni. Vagy lehet float-okkal is, de akkor át kell írnod a feltételeket (és nem árt arra is gondolni, hogy bizonyos hányadosokat csak kerekítve lehet float-on ábrázolni).
-
-
kovisoft
őstag
válasz
kovisoft #5955 üzenetére
Közben még agyaltam egy általánosabb megoldáson is, ami egyesével olvassa ki a biteket. Triviálisan mindig az alsó bitet lehetne kiolvasni, kiírni, aztán jobbra shiftelni a biteket a számban amíg el nem fogynak a bitek. Viszont így fordított sorrendben írnánk ki a biteket. A lenti kód ehelyett mindig a felső bitet olvassa ki, majd balra shifteli a biteket, de legelőször berak jobbra egy plusz 1-es bitet, hogy tudja, mikor kell abbahagyni a ciklust:
dec=(dec<<1)|1;
while ((dec&255)>0)
{
printf("%d", (dec&256)>>8);
dec=dec<<1;
}
printf("\n");
Szerk: mi a hibaüzenet? -
kovisoft
őstag
válasz
elistvan #5954 üzenetére
Ha csak egy változót lehet használni és az maga a változó, amibe beolvastad a decimális számot, akkor itt egy ocsmány és gagyi megoldás:
printf("%d%d%d%d%d\n", (dec&16)>>4, (dec&8)>>3, (dec&4)>>2, (dec&2)>>1, (dec&1));
Mivel tudjuk, hogy legfeljebb 31 lehet a dec (ezt illik ellenőrizni előtte), ezért szimplán sorban kiolvassuk dec alsó 5 bitjét.
-
kovisoft
őstag
válasz
ub19student #5945 üzenetére
Tegyél be a programod végére egy billentyű nyomásra várakozást, hogy csak azután fejeződjön be a programod. Vagy pedig nyisd meg a command promptot és abból indítsd a programodat, ne pedig rákattintva.
-
kovisoft
őstag
válasz
don_peter #5933 üzenetére
Ja, az eredeti hozzászólásodból az jött le, hogy a "cikkszám;darabszám" össze van téve egyetlen stringbe. Mindegy, ezzel az adatstruktúrával ugyanúgy tud menni a dolog, csak meg kell írni az összehasonlító függvényt a qsort-hoz (de persze más módon is rendezheted a tömbödet).
-
kovisoft
őstag
válasz
don_peter #5931 üzenetére
Egy lehetséges megoldás:
Rendezed a string tömbödet (pl. qsort). Végigmész a rendezett tömb elemein, minden elemre a stringet kettéválasztod a pontosvessző mentén (pl. strchr-rel megkeresed a ';' karaktert, és lecseréled 0-ra). Az első rész lesz a cikkszám, ezt megjegyzed, a második részt atoi-val integerré alakítod, ez a darabszám. Ha a cikkszám ugyanaz, mint az előző, akkor csak szimplán hozzáadod a darabszámot az előzőek összegéhez. Ha új cikkszámhoz értél vagy vége a tömbnek, akkor az előző cikkszámot kiírod egy új tömbbe, mellé az összeadogatott darabszámot. -
kovisoft
őstag
válasz
atkamaly #5893 üzenetére
A második bekérést úgy érted, hogy amikor a J-s ciklusban másodszor (amikor J=1) kerül a vezérlés a scanf-re? Mert ebben az esetben azért írja ki az előző (J=0) lépésben megváltoztatott értékeket, mert nem állítod vissza a cikluson belül a red/yellow/blue tömb eredeti állapotát. Tedd be a cikluson belülre a red/yellow/blue inicializálását.
-
kovisoft
őstag
Nem világos számomra, hogy minek van és minek nincs visszatérési értéke (pl. a cut ad vissza valamit vagy nem, és ha igen, akkor mit?). De ha ettől eltekintünk, akkor mi van, ha eleve 4-nél kevesebb elemű tömbre hívod meg? Akkor a cut végtelen ciklusba kerül, mert folyamatosan a felezős ágba kerül a vezérlés, és egy idő után a 0 méretű intervallumot felezgeti.
-
kovisoft
őstag
Milyen hosszú sorok vannak a file-ban, aminek a sorait olvasod? Mert a char sor[128] tömbbe fgets(sor,255,fajl) utasítással 255 karaktert is beolvashatsz, ami aztán felülírhatja a stacket, és lehet ettől is az elszállás. Ill. hány sorból áll a file, mi van, ha nincs benne a szükséges 4 sor?
Másik megjegyzés: ebben a sorban sizeof(Kerdes*) kellene, mert pointer-tömböt foglalsz le. Persze gondot nem fog okozni, ha fölöslegesen foglalsz több memóriát, csak pazarlás:
Kerdes **tomb=(Kerdes**) malloc(15*sizeof(Kerdes));
Egyebek: nincs felszabadítva a lefoglalt memória, nincs lezárva a megnyitott file, de elszállást ezek sem okoznak, csak ha már túl sok leff foglalva/megnyitva.
Szerk: jól látom, közben megoldódott a probléma?
Ú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!
- Filmvilág
- Milyen asztali (teljes vagy fél-) gépet vegyek?
- DVB-T, DVB-S (2), DVB-C eszközök
- A fociról könnyedén, egy baráti társaságban
- Magas AI-költségek, csökkenő létszám: dolgozók ezreit rúgja ki a Microsoft
- Motoros topic
- Gitáros topic
- TCL LCD és LED TV-k
- Hardcore café
- Itthon is kapható lesz a kerámia Xiaomi Band 10
- További aktív témák...
- ÁRGARANCIA!Épített KomPhone Ryzen 7 5700X 16/32 RAM RTX 5060Ti 16GB GAMER PC termékbeszámítással
- ÁRCSÖKKENTÉS Lenovo ThinkPad T570, T580, P51s, P52s eredeti Lenovo, belső akkumulátor eladó
- ÁRGARANCIA!Épített KomPhone i5 14600KF 16/32/64GB RAM RTX 5070 12GB GAMER PC termékbeszámítással
- ÁRGARANCIA!Épített KomPhone i3 10105F 8/16/32GB RAM RX 6500 XT 4GB GAMER PC termékbeszámítással
- Telefon felvásárlás!! Xiaomi Redmi Note 12, Xiaomi Redmi Note 12 Pro, Xiaomi Redmi Note 12 Pro+
Állásajánlatok
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest
Cég: CAMERA-PRO Hungary Kft
Város: Budapest