Hirdetés

2024. május 7., kedd

Gyorskeresés

Hozzászólások

(#6001) kovisoft válasza elistvan (#6000) üzenetére


kovisoft
őstag

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));

(#6002) elistvan válasza kovisoft (#6001) üzenetére


elistvan
senior tag

Szia!

Köszi a segítséget. Ezt az átláthatóbb kódos felületet hol érem el?

[ Szerkesztve ]

Minőségi angol humor magyar felirattal: http://goo.gl/5kvyBr

(#6003) kovisoft válasza elistvan (#6002) üzenetére


kovisoft
őstag

A hozzászólás szerkesztőben a "Programkód formázás" gombot kell kiválasztani, ez az ikonja: </>. Mondjuk nekem néha szétesik a formázás, nem mindig tartja egyben a beleírt szöveget, de lehet, hogy én bénázok el valamit.

(#6004) sztanozs válasza kovisoft (#6003) üzenetére


sztanozs
veterán

Csak a régi szerkesztőben működik rendesen, az új nem hajlandó a <p>...</p>-t ...<br />-re cserélni.

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#6005) Domonkos


Domonkos
Ármester

Ha a 0-val valo osztas UB, akkor garantalja-e azt valami, hogy egy ilyen kod eseten az if is biztosan belefordul a gepi kodba (es persze hogy a return 69 is marad)?
int
d(int j)
{
if (j != 0)
return 100/j;
return 69;
}

Gender of electrical connectors is defined by the pins.

(#6006) dabadab válasza Domonkos (#6005) üzenetére


dabadab
titán

Mi az az UB?

DRM is theft

(#6007) Domonkos válasza dabadab (#6006) üzenetére


Domonkos
Ármester

undefined behavior

Gender of electrical connectors is defined by the pins.

(#6008) sztanozs válasza Domonkos (#6005) üzenetére


sztanozs
veterán

miért ne fordulna ez be?

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#6009) Domonkos válasza sztanozs (#6008) üzenetére


Domonkos
Ármester

Mert a 0-val valo osztas UB, igy ezzel a lehetoseggel nem is kell a forditonak szamolnia. Mivel ezzel nem kell szamolnia, igy feltetelezheto, hogy j nem 0; am ekkor a feltetel mindig igaz, ezert az NOP-olhato. Ekkor viszont a masik return elerhetetlen, igy az is elhagyhato.

[ Szerkesztve ]

Gender of electrical connectors is defined by the pins.

(#6010) sztanozs válasza Domonkos (#6009) üzenetére


sztanozs
veterán

Nem, mivel 100/j UB, amennyiben nincs ellenőrizve, hogy a j egyenlő-e 0-val.
Tehát, ha az if-et kioptimalizálná, akkor az egész függvényt ki kell, mert a 100/j UB...

Szerintem a fordító inkább "beoptimalizál" egy if j !=0-t a kódba, ha nincs ott, hogy ne legyen HW interrupt, csak szoftveres.

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#6011) Domonkos válasza sztanozs (#6010) üzenetére


Domonkos
Ármester

Nem optimalizalhatna az egeszet ki, mert a nem UB esetekre ugyanannak kell lennie a mellekhatasnak.
Egyebkent tobb architecturan nem is triggerel semmifele interruptot egy 0-val valo osztas - ezert is lett ez UB C-ben.

Gender of electrical connectors is defined by the pins.

(#6012) Domonkos válasza Domonkos (#6005) üzenetére


Domonkos
Ármester

Hopp!
Azt hiszem, hogy tulegyszerusitettem az IRL esetet. Ez a kod tenyleg nem tud "tuloptimalizalodni" :)

[ Szerkesztve ]

Gender of electrical connectors is defined by the pins.

(#6013) buherton válasza sztanozs (#6010) üzenetére


buherton
őstag

Nem biztos, hogy bármilyen interrupt is lesz belőle ;) . Láttam már olyan architektúrát, ahol kiszámolta a proci :DDD .

tely, baly, fojó, mennyél, mingyárt, telyföl, tolyás, malyd, kapú, egyenlőre, ejsd, jáccani, ahoz, fúj, hüje, muszály, alat, álok, lasan, fojtatás, ál, fontós, költsön, eggyüt, lyob (jobb?), mek, mongyak, milyért - !!! Tanúlyunk már meghejjessen irni... !!!

(#6014) sztanozs válasza buherton (#6013) üzenetére


sztanozs
veterán

int-ben biztos nem számolja ki, de float lehet INF vagy NAN is. :DDD

JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

(#6015) kunzoltan77


kunzoltan77
friss újonc

Sziasztok, egy kéréssel fordulnék felétek. Adott a következő feladat:
https://progcont.hu/progcont/100041/?pid=200534

A kód amit írtam rá:
[link]

A problémám az lenne, hogy a feladatnak ezt a részét nem tudom leprogramozni és módosítani a kódot:

"Kettőspont kizárólag az eredményt leíró részben fordulhat elő a sztringben, a két csapat eredményét választja el egymástól, szóköz karakterek nélkül."

A program lefut és megkapom a jó eredményt, de a progcont hiba miatt, ami feltehetően a fentebbi, nem fogadja.

Nagyon szépen megköszönöm nektek ha tudnátok segíteni.

Zoltán

(#6016) kovisoft válasza kunzoltan77 (#6015) üzenetére


kovisoft
őstag

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.

(#6017) kunzoltan77 válasza kovisoft (#6016) üzenetére


kunzoltan77
friss újonc

Értem, valóban ebben lehet a hiba, köszönöm szépen választod, megpróbálom ezek szerint megírni a kódot. Köszönöm mégegyszer!

(#6018) elistvan


elistvan
senior tag

Sziasztok!

Ebben az I 504-es megoldásának,. hogy kellene nekiállni? Egyetemen ez a beadandó 1/4-e az egyik tárgyhoz, de lövésem sincs, hogy kéne megoldani. Előre is köszi.

[ Szerkesztve ]

Minőségi angol humor magyar felirattal: http://goo.gl/5kvyBr

(#6019) kovisoft válasza elistvan (#6018) üzenetére


kovisoft
őstag

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.

(#6020) elistvan válasza kovisoft (#6019) üzenetére


elistvan
senior tag

Köszi. :R

Minőségi angol humor magyar felirattal: http://goo.gl/5kvyBr

(#6021) jattila48


jattila48
aktív tag

Tudnátok a tömbre mutató pointernek valami értelmes alkalmazását mondani?
int ia[2];
int (*pia)[2];
pia=&ia;

pia az ia tömbre mutató pointer, értéke az ia tömb címe. Nade mire jó?

[ Szerkesztve ]

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6022) Domonkos válasza jattila48 (#6021) üzenetére


Domonkos
Ármester

argv, getopt es tarsai.

[ Szerkesztve ]

Gender of electrical connectors is defined by the pins.

(#6023) jattila48 válasza Domonkos (#6022) üzenetére


jattila48
aktív tag

Vagyis? Bővebben? Az argv char *[] típusú, azaz char * típusú címeket tartalmazó tömb. Nem ugyanaz, mint a (char *)[], char tömbre mutató pointer típus, amit én kérdezek

[ Szerkesztve ]

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6024) Domonkos válasza jattila48 (#6023) üzenetére


Domonkos
Ármester

Ha nem egy erteket szeretnel atpasszolni egy masik fuggvenynek, hanem mondjuk egy egesz listanyit, akkor parameterkent egy listara mutato pointert fogsz varni - ahogy ezt a getopt is teszi.

Gender of electrical connectors is defined by the pins.

(#6025) jattila48 válasza Domonkos (#6024) üzenetére


jattila48
aktív tag

Ha megnézed, a getopt paramétere char *[] típusú, nem pedig (char *)[] típusú. A két típus különböző. Én az utóbbit kérdezem. Az első címeket tartalmazó tömb, vagyis az elemei pointerek. A második pedig tömbre mutató pointer, aminek értéke a tömb címe. Régóta programozok C-ben, tudom mire való az argv, getopt és társai. De ez más.

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6026) kovisoft válasza jattila48 (#6021) üzenetére


kovisoft
őstag

Ha bármilyen okból kifolyólag szükséged van a *pia sizeof-jára. Pl. mert memset-elni akarod. Vagy mondjuk használni akarod egy olyan makróban, ami a tömb elemeinek a számát a sizeof(arr)/sizeof(arr[0]) módszerrel határozza meg.

(#6027) jattila48 válasza kovisoft (#6026) üzenetére


jattila48
aktív tag

A makródban nem használsz tömbre mutató pointert.

[ Szerkesztve ]

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6028) kovisoft válasza jattila48 (#6027) üzenetére


kovisoft
őstag

Zárójellel megfelel?

sizeof(arr)/sizeof((arr)[0])

(#6029) jattila48 válasza kovisoft (#6028) üzenetére


jattila48
aktív tag

Nem felel meg, mert az arr nálad csak egy tömb, nem pedig tömbre mutató pointer. Az én példámban sizeof(pia)==4 (vagy 8), azaz pointer méret. Nálad sizeof(arr) az arr tömb mérete. A tömb nem ugyanaz, mint a tömbre mutató pointer.

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6030) kovisoft válasza jattila48 (#6029) üzenetére


kovisoft
őstag

#define ARRSIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
int ia[10];
int (*pia)[10];
pia=&ia;
printf("%lu\n", ARRSIZE(*pia));

-> 10

(#6031) jattila48 válasza kovisoft (#6030) üzenetére


jattila48
aktív tag

E helyett az ARRSIZE(ia) sokkal egyszerűbb lenne. Továbbra is az a kérdésem, hogy mira jó a tömbre mutató pointer?

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6032) kovisoft válasza jattila48 (#6031) üzenetére


kovisoft
őstag

Pl. több ia tömböd van, amiket egységesen akarsz kezelni egy pia pointeren keresztül.

(#6033) jattila48 válasza kovisoft (#6032) üzenetére


jattila48
aktív tag

Ha több ugyanolyan típusú tömböt egységesen akarok kezelni, akkor:
int ia1[5],ia2[5];
int *pia;
pia=ia1;
//valamit csinálok a pia pointeren keresztül
pia=ia2;
//stb...

Ha a méretükre van szükségem, akkor ARRAYSIZE(ia1),
de még egyszerűbb, ha
#define ASIZE 5
int ia1[ASIZE],ia2[ASIZE];
...

[ Szerkesztve ]

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6034) kovisoft válasza jattila48 (#6033) üzenetére


kovisoft
őstag

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.

(#6035) jattila48 válasza kovisoft (#6034) üzenetére


jattila48
aktív tag

A baj csak az, hogy a tömbre mutató pointerhez hozzá van kötve a tömb mérete. Tehát, ha a tömbre mutató ponter egy fv. argumentuma, akkor annak semmilyen más méretű tömböt nem lehet átadni. Így aztán a tömb méretét lekérdezni nem sok értelme van, hiszen ez a fv. csak ilyen méretű tömböt képes fogadni.
Nem vitatkozni akarok, csupán érdekel, hogy miért létezik ez a konstrukció a C nyelvben. Akkor lenne értelme, ha nem lehetne elkerülni a használatát, vagy az elkerülése bonyolultabb lenne. Ehelyett mindig el lehet kerülni, és egyszerűbben, mint használni. Pointereket leggyakrabban azért haználunk, hogy az általuk mutatott memória címen megváltoztassuk a memória tartalmát (vagy mert a stack-en nem lehet nagyméretű objektumokat átadni). Ehhez képest a tömbre mutató pointeren keresztül nem változtatjuk meg a tömböt (ami itt a tömb címét jelenti), hiszen az nem is balérték. Úgy tűnik, hogy igazából semmi értelme nincs, mindössze a C típusdefiníciós szintaxisának egy csökevénye.

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6036) jattila48 válasza jattila48 (#6035) üzenetére


jattila48
aktív tag

Közben rájöttem, mikor van értelme a tömbre mutató pointer használatának.
int iia[10][5];
int (*piia)[5];
piia=iia;

Az iia kétdimenziós tömb neve önmagában leírva nem int ** típusú, hanem int (*)[5] típusú. Ezért ha ezt a kétdimenziós tömböt akarjuk átadni az f fv.-nek, akkor
void f(int (*x)[5]);
prototípusúnak kell lennie.

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6037) jattila48 válasza jattila48 (#6036) üzenetére


jattila48
aktív tag

Az f fv. prototipusa lehet ez is:
void f(int x[][5]);

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6038) elistvan válasza kovisoft (#6019) üzenetére


elistvan
senior tag

Ez okés de a kódolás része akkor hogy zajlik?

6. A felcserélt karakterekből álló szöveget rejtjelezzük a megadott Cardano-rács alkalmazásával, és az eredményt 6×66×6-os rácsban – a minta szerint – írassuk ki a sandormatyas.txt fájlba.

Minőségi angol humor magyar felirattal: http://goo.gl/5kvyBr

(#6039) kovisoft válasza elistvan (#6038) üzenetére


kovisoft
őstag

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).

(#6040) elistvan válasza kovisoft (#6039) üzenetére


elistvan
senior tag

ismét köszönöm szépen. :R

Minőségi angol humor magyar felirattal: http://goo.gl/5kvyBr

(#6041) jattila48 válasza elistvan (#6040) üzenetére


jattila48
aktív tag

Csakúgy mellesleg egy érdekes kérdés: hányféle Cardano rács van?

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6042) kovisoft válasza jattila48 (#6041) üzenetére


kovisoft
őstag

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... :D

(#6043) jattila48 válasza kovisoft (#6042) üzenetére


jattila48
aktív tag

Bármelyik kivágott lyuk a forgatások miatt 4 pozíciót határoz meg, amelyek közül csak ezt az egyet lehet kivágni. Hogy egy, forgatások által meghatározott négyes melyik elemét választod ki, az 4-féleképpen lehetséges. Összesen 9 db. négyes van, amelyek mindegyikéből csak egy-egy elemet lehet kiválasztani, ezt pedig összesen 4^9 féleképpen lehet megtenni. Szerintem az én megoldásom a jó! :K
Egyébként ilyen módon a Cardano rácsot a (rejtjelezés kulcsát) egy 9 hosszú sorozattal lehet reprezentálni, amelynek minden eleme pl. 1,2,3, vagy 4 (pl. 1,3,2,1,2,4,3,2,4), és meg lehetne állapodni, hogy a sorozat elemei rendre az (sor,oszlop)=(1,1),(1,2)(1,3)(1,4),(1,5)(2,2),(2,3),(2,4),(3,3) elemek által reprezentált 4-esek valamelyik elemét jelentik. A fenti példából az (1,1),(6,5),(3,6),(1,4),(5,6),(5,2),(5,4),(4,5),(4,3) Cardano rács adódik, méghozzá úgy, hogy a reprezentáló elemeket helyben hagyjuk (a kulcsban ezt 1 jelöli), vagy 90 fokkal jobbra (2 jelöli), 180 fokkal jobbra (3 jelöli), 270 fokkal jobbra (4 jelöli) forgatjuk.
Lehetne bonyolítani a programot, hogy a kulcsot ilyen tömörebb módon adjuk meg.
Érdemes lenne elgondolkozni azon, hogy hogy lehet egy elég hosszú szöveget a kulcs ismerete nélkül megfejteni. A maga idejében ez elég reménytelen feladatnak látszott, azonban számítógép segítségével ma már nem az.

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6044) kovisoft válasza jattila48 (#6043) üzenetére


kovisoft
őstag

Ne zavarjon, hogy 4^9 az szintén 262144. :P

(#6045) jattila48 válasza kovisoft (#6044) üzenetére


jattila48
aktív tag

Lehet nem jó smiley-t tettem a mondat végére? Reméltem, hogy érteni fogod a viccet. :CDirekt nem írtam oda kiszámolva, hogy szemmel láthatóan különbözőnek tűnjön. Na persze, ha valaki kiszámolja,... úgy nem ér!

[ Szerkesztve ]

„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár

(#6046) kovisoft válasza jattila48 (#6045) üzenetére


kovisoft
őstag

Sorry, de nekem tényleg nem esett le. Nálam lehet a probléma, eléggé lefárasztott ez a nap. :R

(#6047) #90088192


#90088192
törölt tag

Hello Mindenkinek :)

Igen kezdő vagyok minden szinten, ezert nagyon alap kérdésem, lenne amit nehéz megfogalmazni, számomra, így nem is egyszerű megtalálni a szagirodalomban.

MPLAB-ban készítettem egy működő kódot ami egy kijelzőt vezérel, eddig jó, van két .h fajlom az egyik a hardware deklaráció, a másik maga a font.
Maga a source file screen.c neven futott és tartalmazott egy void main bejegyzést, amit alá írtam az lefutott.

Amit csinálni szeretnek, létrehozni egy main.c nevű fájlt, és abba meghívni a screen.c ben összedobott szubrutinokat. Ezt így megpróbáltam, és többszörös definícióra hivatkozik folyamatosan.
Valaki el tudna mondani mit csinálok rosszul? :R

Maga a main.c

#include <stdlib.h>
#include "screen.c"

/*
*
*/
int main()
{

unsigned int x;

InitalizePorts_display();

//Wait for Vcc to settle
delay(100);
// Turn on display
dsp_on();
lcd_select(2);
clr_scr(0x00);


//*************************************************************************
// Test
//*************************************************************************


for(x=0;x<2000;x++)
{
float a=(73.00/5);


string_out("Spotty:", x ,1,0);
delay(10000);

}


return (EXIT_SUCCESS);
}

es ez lenne a kijelző vezérlő

#include "hardware.h"
#include "font6x8.h"



void delay(unsigned int usec)
{
_delay_us(usec);
}

void lcd_select(int s)
{
if(s==0)
{
DISPLAY_CS1 = 1; //Selects Left side of the screen
DISPLAY_CS2 = 0; //Deselects Right side of the screen
delay(10);
}else if(s==1)
{
DISPLAY_CS1 = 0; //Deselects Left side of the screen
DISPLAY_CS2 = 1; //Selects Right side of the screen
delay(10);
}else{
DISPLAY_CS1 = 1; //Selects Left side of the screen
DISPLAY_CS2 = 1; //Selects Right side of the screen
delay(10);
}
}

void strobe_E(void) //Turns enabling line off/on
{
DISPLAY_EN = 0;
delay(10);
DISPLAY_EN = 1;
delay(10);
}

void set_y(int y) //Set Y coordinate 0-63 on the active side of the screen
{
//Y address
DISPLAY_RS = 0;
S_DATA_OUT = (0b01000000+y);
strobe_E();
}


void dsp_on(void)
{
DISPLAY_RS = 0; //Instruction mode
S_DATA_OUT = 0b00111111; //Turns display on
//DISPLAY_RS = 1; //Data Mode
delay(10);
strobe_E();
}

void clr_scr (int t)
{
int x; int y;
//line_0();
DISPLAY_RS = 0;
S_DATA_OUT = 0b11111111;
for(y=0b10111111;y>=0b10111000;y--)
{
set_y(0);
DISPLAY_RS = 0;
S_DATA_OUT = y;
strobe_E();
for(x=0; x<64; x++)
{
dsp_on();
DISPLAY_EN = 1;
DISPLAY_RS = 1;
S_DATA_OUT = t;
strobe_E();
};
};


}

void write_char(int line_select, int y_offset, int c)

{ int x; int t;
if(y_offset>63 && y_offset<122) //Check which side of the screen need to be activated
{lcd_select(1); //if the offset is bigger than 63 than the right side

t=(y_offset-64); //correction of the offset for the right side
set_y(t);

DISPLAY_RS = 0;
S_DATA_OUT = 0b10111000+line_select; //select line
strobe_E();

for(x=(c-32)*6; x<((c-32)*6)+6; x++) //Decodes the character code and make sure the data is sent by 8 bits
{
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x];
strobe_E();
}
}else if(y_offset<64 && y_offset>=0)
{

lcd_select(0); //selects the left side of the screen

t=(y_offset);
set_y(t);

DISPLAY_RS = 0;
delay(10);
S_DATA_OUT = 0b10111000+line_select;
strobe_E();

for(x=(c-32)*6; x<((c-32)*6)+6; x++) //Decodes the character code and make sure the data is sent by 8 bits
{if(t+(x-(c-32)*6)==63) //checks if the character has reached the border of the 2 sides of the screen
{lcd_select(1); //If yes selects the the right side
delay(10);
DISPLAY_RS = 0;
S_DATA_OUT = 0b10111000+line_select; // Select the relevant line
strobe_E();
set_y(0); // Resets the offset
delay(2);
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x]; //send out the data what belongs to the right side of the screen
strobe_E();
}else{ //If the Character is belong to the left side
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x]; //Sends the data to the screen
strobe_E();
}
}
}
else
{
lcd_select(2);
clr_scr(0xff);
}

}

void string_out(char* message, float variable, char line, char y_offset)
{
char test[21],i=0,j;
char a[21];
sprintf(a, "%s%f", message, variable);
while(a[i]!='\0') {test[i]=a[i]; i++;}
for(j=0;j<=i-1;j++) write_char(line,y_offset+j*6,test[j]);

}

(#6048) buherton válasza #90088192 (#6047) üzenetére


buherton
őstag

C fájlt nem illik includolni. Erre való a header fájl, amiben leírod a függvény deklarációkkal, hogy a hozzátartozó C fájl mit is tartalmaz.

A C-ben nincsenek szubrutinok.

tely, baly, fojó, mennyél, mingyárt, telyföl, tolyás, malyd, kapú, egyenlőre, ejsd, jáccani, ahoz, fúj, hüje, muszály, alat, álok, lasan, fojtatás, ál, fontós, költsön, eggyüt, lyob (jobb?), mek, mongyak, milyért - !!! Tanúlyunk már meghejjessen irni... !!!

(#6049) #90088192 válasza buherton (#6048) üzenetére


#90088192
törölt tag

Köszönöm :)

Akkor természetesen jönnek az újabb kérdések, ha nem baj

Akkor a különböző részegységek funkcióit hogyan tudnám szeparálni.
Vagyis a mostani screen.c bol csináltam screen.h, így működik, de ha újabb .h-t hívok meg amiben egy előzőleg meghívott hardware.h benne van akkor megint ugyan az a probléma.
Tudom hülye kérdés, ilyen alap struktúra probléma, de fogalmam sincs ezekre hogyan keressek rá.
Amit el akarok erni: reszegysegenkent kulon fuggveny konyvtar vagy mi a fitty fene.(Nem tudom minek nevezzem)
Azt hogyan kellene strukturalni?
:R

Közben kutakodtam, ezt találtam.

ez a hardware.h

#include "stdio.h"
#include <string.h>
#include <math.h>
#include <p32xxxx.h>
#include <D:\Program Files (x86)\Microchip\xc32\v2.30\pic32mx\include\peripheral\legacy\i2c_legacy.h>


#define SYS_FREQ 80000000L
#define FCY SYS_FREQ
#define F_CPU SYS_FREQ
#define DLY_COUNT (F_CPU/4000000)
#define _delay_us( dly ) {unsigned int x=0,y=dly; while(y--){x=DLY_COUNT;while(x--);}}

// DEVCFG3
// USERID = No Setting
#pragma config FSRSSEL = PRIORITY_1 // SRS Select (SRS Priority 1)
#pragma config FCANIO = OFF // CAN I/O Pin Select (Alternate CAN I/O)
#pragma config FUSBIDIO = OFF // USB USID Selection (Controlled by Port Function)
#pragma config FVBUSONIO = OFF // USB VBUS ON Selection (Controlled by Port Function)

// DEVCFG2
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_20 // PLL Multiplier (20x Multiplier)
#pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider (2x Divider)
#pragma config UPLLEN = ON // USB PLL Enable (Enabled)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)

// DEVCFG1
#pragma config FNOSC = FRCPLL // Oscillator Selection Bits (Fast RC Osc with PLL)
#pragma config FSOSCEN = ON // Secondary Oscillator Enable (Enabled)
#pragma config IESO = ON // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_2 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/2)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))

// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF // Code Protect (Protection Disabled)

//I/O Digital analog selection
#define Analog_digital AD1PCFG

//Screen Hardware Setup
#define DISPLAY_Dir TRISE
#define S_DATA_OUT LATE
#define S_DATA_IN PORTE
#define DISPLAY_CS1 LATGbits.LATG6
#define DISPLAY_CS2 LATDbits.LATD8
#define DISPLAY_RS LATGbits.LATG9
#define DISPLAY_RW LATDbits.LATD7
#define DISPLAY_EN LATDbits.LATD11
#define DISPLAY_CS1_Direction TRISGbits.TRISG6
#define DISPLAY_CS2_Direction TRISDbits.TRISD8
#define DISPLAY_RS_Direction TRISGbits.TRISG9
#define DISPLAY_RW_Direction TRISDbits.TRISD7
#define DISPLAY_EN_Direction TRISDbits.TRISD11

//Membrane
#define JTAGEN DDPCONbits.JTAGEN
#define MEMBRANE_MUTE LATBbits.LATB13
#define MEMBRANE_MAINS LATBbits.LATB14
#define MEMBRANE_ALARM LATBbits.LATB15
#define MEMBRANE_MUTE_Direction TRISBbits.TRISB13
#define MEMBRANE_MAINS_Direction TRISBbits.TRISB14
#define MEMBRANE_ALARM_Direction TRISBbits.TRISB15


//Analog inputs

#define REF2_5 PORTBbits.RB0
#define MUX PORTBbits.RB1
#define BAT1_CURRENT PORTBbits.RB2
#define BAT2_CURRENT PORTBbits.RB3
#define CHARGER_CURRENT PORTBbits.RB4
#define CHARGER_VOLTAGE PORTBbits.RB5
#define LOAD_VOLTAGE PORTBbits.RB8
#define BRIDGE_VOLTAGE PORTBbits.RB9
#define VREQ PORTBbits.RB10
#define IREQ PORTBbits.RB11

#define REF2_5_DIRECTION TRISBbits.TRISB0
#define MUX_DIRECTION TRISBbits.TRISB1
#define BAT1_CURRENT_DIRECTION TRISBbits.TRISB2
#define BAT2_CURRENT_DIRECTION TRISBbits.TRISB3
#define CHARGER_CURRENT_DIRECTION TRISBbits.TRISB4
#define CHARGER_VOLTAGE_DIRECTION TRISBbits.TRISB5
#define LOAD_VOLTAGE_DIRECTION TRISBbits.TRISB8
#define BRIDGE_VOLTAGE_DIRECTION TRISBbits.TRISB9
#define VREQ_DIRECTION TRISBbits.TRISB10
#define IREQ_DIRECTION TRISBbits.TRISB11

void InitalizePorts_membrane()
{
JTAGEN=0;
MEMBRANE_MUTE=1;
MEMBRANE_MAINS=1;
MEMBRANE_ALARM=1;
MEMBRANE_MUTE_Direction =0 ;
MEMBRANE_MAINS_Direction =0 ;
MEMBRANE_ALARM_Direction =0 ;

};

void InitalizePorts_display()
{
S_DATA_OUT=0;
S_DATA_IN=0;
DISPLAY_Dir=0;
DISPLAY_CS1=1;
DISPLAY_CS2=1;
DISPLAY_RS=1;
DISPLAY_RW=0;
DISPLAY_EN=1;

/* Command port direction settings */
DISPLAY_CS1_Direction =0 ;
DISPLAY_CS2_Direction =0 ;
DISPLAY_RS_Direction =0 ;
DISPLAY_RW_Direction =0 ;
DISPLAY_EN_Direction =0 ;




};

void InitalizePorts_ADC()
{
Analog_digital= 0x10C0;
AD1CON2 = 0x0000;
AD1CON3 = 0x0000; // Configure ADC conversion clock
AD1CSSL = 0x0000; // No inputs are scanned. Note: Contents of AD1CSSL are ignored when CSCNA = 0
IFS1CLR = 2; //Clear ADC conversion interrupt
IEC1SET = 2; //Enable ADC conversion interrupt
AD1CON1 = 0x00E0; // SSRC bit = 111 internal counter ends sampling and starts converting
AD1CHS = 0b1111110011110000; // Connect RB2/AN2 as CH0 input in this example RB2/AN2 is the input
AD1CSSL = 0;
AD1CON3 = 0x0F00; // Sample time = 15Tad
AD1CON2 = 0x0004; // Interrupt after every 2 samples

//Analog PORT directions

REF2_5_DIRECTION =1;
MUX_DIRECTION =1;
BAT1_CURRENT_DIRECTION =1;
BAT2_CURRENT_DIRECTION =1;
CHARGER_CURRENT_DIRECTION =1;
CHARGER_VOLTAGE_DIRECTION =1;
LOAD_VOLTAGE_DIRECTION =1;
BRIDGE_VOLTAGE_DIRECTION =1;
VREQ_DIRECTION =1;
IREQ_DIRECTION =1;

};
void I2C1_Init()
{
//***** I2C1 Hardware Init *****/
//-----Set pin drive modes-----
//I2C - drive outputs so we can manually clear lines
LATDbits.LATD9 = 1; //Start with bus in idle mode - both lines high
LATDbits.LATD10 = 1;
ODCDbits.ODCD9 = 1; //Open drain mode
ODCDbits.ODCD10 = 1;
TRISDbits.TRISD9 = 0; //SCL1 output
TRISDbits.TRISD10 = 0; //SDA1 output

/***** I2C1 Module start *****/
I2C1CON = 0x1000; //Set all bits to known state
I2C1CONbits.I2CEN = 0; //Disable until everything set up. Pins will be std IO.
I2C1BRG = 0x00C6; //set up baud rate generator
I2C1CONbits.DISSLW = 0; //Enable slew rate control for 400kHz operation
//IFS1bits.MI2C1IF = 0; //Clear I2C master int flag
I2C1CONbits.I2CEN = 1; //Enable I2C

} ;

[ Szerkesztve ]

(#6050) buherton válasza #90088192 (#6049) üzenetére


buherton
őstag

screen.h
void delay(unsigned int usec);    
void lcd_select(int s);
void strobe_E(void);
void set_y(int y);
void dsp_on(void);
void clr_scr (int t);
void write_char(int line_select, int y_offset, int c);
void string_out(char* message, float variable, char line, char y_offset);

A hardware.h-ban pedig függvény definíciók vannak a deklarációk helyett. Nem illik ilyet csinálni. De ha nagyon muszáj, akkor az inline kulcsszót kell elétenni.

Kerüld a fölösleges pontosvesszőket. Nem illik ilyet csinálni.

Ha pedig void a függvény paramétere, akkor írd ki, mert így variadikus lesz.

A register map-re struktúrát és uniont szoktak ráhúzni és akkor nagyon frankón végigkövetehető, hogy ez melyik regiszter. A macro mágiát érdemes elkerülni.

Az include pathért legyen a build környezet felelős és ne hardcode-ld bele a kódba.

tely, baly, fojó, mennyél, mingyárt, telyföl, tolyás, malyd, kapú, egyenlőre, ejsd, jáccani, ahoz, fúj, hüje, muszály, alat, álok, lasan, fojtatás, ál, fontós, költsön, eggyüt, lyob (jobb?), mek, mongyak, milyért - !!! Tanúlyunk már meghejjessen irni... !!!

Copyright © 2000-2024 PROHARDVER Informatikai Kft.