Hirdetés

2024. május 4., szombat

Gyorskeresés

Hozzászólások

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


#90088192
törölt tag

Köszönöm megegyszer :R

Ezzel el leszek egy ideig.

Akkor maradhatnak .c ben a fuggvenyek, csak a deklaracio kell .h ban.
Ha ezt megugrottam, akkor jön majd a következő kérdés, elég a relevans .h fájlt include a main.c ben és akkor maris működik?

(#6052) buherton válasza #90088192 (#6051) üzenetére


buherton
őstag

[link]

Minden .c fájlból fordítódik egy .o fájl. A .o fájlokat fogja a linker összeszerkeszteni, aminek a vége egy bináris, amit te is használni fogsz. A .h fájlok, azért kellenek, mert abban vannak deklarálva a .c/.o szempontjából a külső függőségek, amiket a linker old fel a bináris összeállítása során.

Példa: A foo.c-hez kell tartoznia egy foo.h-nak, amiben a foo.c kívülről is elérhető makrók, típusok, változók és függvények vannak felsorolva. A main.c-ben elég a foo.h-t includolni, hogy a main.c leforduljon. Majd a linker összerakja a két .o fájlt.

A fordítást/linkelést az IDE tipikusan megoldja, neked csak a forrás fájlokkal kell bíbelődni.

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

(#6053) #90088192 válasza buherton (#6052) üzenetére


#90088192
törölt tag

Ahaaaaaaaaaaaaaaaaaaaaaa :R

Így mar értem :R

Akkor ennek menten neki esek az újra rendezésnek :K

De majd csak legközelebb.

KÖSZÖNÖM :R

(#6054) jattila48 válasza #90088192 (#6053) üzenetére


jattila48
aktív tag

Alapvetően azzal kell tisztában lenni, hogy az #include-okkal beszúrt fájlok az őket beinklúdoló fájlokkal együtt egy fordítási egységet (translation unit TU) képeznek. Az #include egy direktíva, a C előfordítónak szól, és egyszerűen szöveg-szinten beszúrja az inklúdolt fájlt. Tehát olyam, mintha copy-pastéval bemásolnád a fájlt. Ezért az inklúdokban nem lehet körbe hivatkozás (a.h inklúdolja b.h-t, ami inklúdolja a.h-t), és nem lehet többször inklúdolni ugyanazt a fájlt (mert ekkor keletkezik a többszörös defínició). Az utóbbi elkerülésére az ún. include guard megoldást használjuk:
Pl. egy include file így néz ki:
#ifndef __include_guard_h //itt a nev include fájlonként különböző és a fáj nevére utal
#define __include_guard_h
//ide jön az include file tartalma
#endif

Ezzel azt érjük el, hogy egy TU-ban ne lehessen az include fájlt többször beszúrni. Ugyanis először az __include_guard_h makró még nincs definiálva, tehát a fájl tartalma feldolgozásra kerül, miközben a makró definiálttá válik. Következő eseleges beszúráskor a makró már definiálva lesz, de a #ifndef direktíva hamosra lesz kiértékelve, vagyis a feldolgozás az #endif után folytatódik. A körbe hivatkozások ellen az include guard nem véd, arra neked kell odafigyelni.
C forrás fájlokat tényleg nem szoktunk inklúdolni. Ha több forrás fájlból áll a projected, akkor azokat a project létrehozásakor (project fájlban) kell megadni. Ezek külön-külön fordítási egységet fognak képezni (az általuk beinklúdolt header fájlokkal együtt), amikben már újra inklúdolhatod a másik TU-ban beinklúdolt header fájlt. A külön fordítási egységekben definiált függvények és globális változók egymás közötti elérhetőségét a linkelés (linker) fogja biztosítani.
Esetenként előfordul (pl. template-ek használatakor), hogy header fájlban függvény definícót írnak, amik a különböző TU-kba való inklúdolások után a linker számára valóban többszörös defínicók lesznek, de ezt a legtöbb linker kezeli. Ettől még kerülendő ez a gyakorlat, ha nagyon kell akkor inline-ként megadható, bár azt a fordító dönti el, hogy valóban inline módon fordítja-e.

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

(#6055) #90088192 válasza jattila48 (#6054) üzenetére


#90088192
törölt tag

Köszönöm :)

Remélem, nem akasztok ki senkit a hülyeségeimmel :R

(#6056) jattila48 válasza #90088192 (#6055) üzenetére


jattila48
aktív tag

Dehogy! Ahogy mondani szokták, csak a fel nem tett kérdés a hülye kérdés. Aki válaszol, az segítő szándékkal teszi. Legalábbis remélem.

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

(#6057) borisz1994


borisz1994
csendes tag

Sziasztok. Nemrég kezdtem el olvasni a Benkő Tiborné - Benkő László - Tóth Bertalan : Programozzunk C nyelven! könyvet. A könyv az elején felhívja a figyelmet a deklaráció és a definíció közti különbségre és arra is hogy a kezdők könnyen összekeverik a kettőt (teljesen jogosan :) ) Sajnos nem tudtam teljesen megérteni. Ha jól sejtem a lényegi különbség a memóriafoglalásban van.
Ha jól értem ez definíció:
int pelda=0;
Ez értelemszerűen lefoglal valamekkora (2 byte?) memóriát.
Én a deklarációt úgy értelmeztem hogy ezzel adjuk meg egy név tulajdonságait (típus, láthatóság, tárolási osztály, élettartam) és nem jár memóriafoglalással.
Így kellene kinézzen?
int pelda;
Kérem valaki világosítson fel hogy hol rontom el az értelmezést. Miért fontos a kettő közötti különbség?

(#6058) buherton válasza borisz1994 (#6057) üzenetére


buherton
őstag

Nem egészen. Vagyis hát nem olyan triviális. Főleg a változóknál.

A deklaráció a fordítónak szól, vagyis ez ahhoz kell, hogy a fordító értelmezni tudja a leírtakat, de nincs közvetlen hatása a processzoron futó kódra. Azaz meg lehet írni a programot ezek nélkül, csak olvashatatlan lesz. A definíció a processzornak szól és enélkül nem futna úgy a programunk, ahogy szeretnék.

Kezdjük az egyszerűbbel a függvénnyel.

Ezek deklarációk:
extern void foo(void);
static int foo(int);
void foo(void);
bar(); // ez most nem függvényhívás, és ez most nagyon gonosz dolog tőlem  
A fordítónak ezekkel jelzed, hogy ha talál egy ilyen szignatúrájú függvényhívást, amihez még nem találta meg a definíciót, akkor ne hasaljon el és a keywordnek megfelelően járjon el.

Ezek definíciók:
void foo(void)
{}
static int foo(int)
{
return 0;
}
bar()
{
return 0;
}
Leírod, hogy mit csinál a függvény. Ezzel mondod meg, hogy mit csináljon a programod.

Változók.

Ez deklaráció (nem is tudok többet ennél):
extern int;
Ugyanaz, mint a függvénynél.

Ezek definíciók:
int foo;
static char foo;
Ugyanaz, mint a függvénynél.

Egyébként igen, a deklaráció nem jár memóriafoglalással, a definíció jár. Viszont a deklaráció csak a láthatóságot növeli, semmi más plusz dolgot nem tud, nem befolyásolja a típust, élettartamot és a tárolási osztályt sem.

Az int mérete architektúra függő és a limits.h-ban van meg a "mérete". Tipikusan 4 bájt. Ha jól emlékszem, akkor az AVR8 esetén 2 bájt méretűek.

[ Szerkesztve ]

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

(#6059) dabadab válasza borisz1994 (#6057) üzenetére


dabadab
titán

Benkő Tiborné - Benkő László - Tóth Bertalan : Programozzunk C nyelven! könyvet

Jézusmária :)
Inkább keress egy jó, érthető könyvet. Szerintem a klasszikus Kernighan-Ritchie "A C programozási nyelv" az elég jó (még ha az apád is lehetne :DDD ), én annak idején abból tanultam.

Egyébként alapvetően megéretetted: a definíció az egy valaminek (változónak, függvénynek) a pontos leírása és ennek hatására a fordító meg is csinálja az ahhoz tartozó dolgokat (memóriát foglal a változónak, lefordítja a függvény kódját).
A deklaráció meg elmondja a fordítónak, hogy van itt ez az izé és ez tulajdonképpen ilyen típusú, de valahol máshol van leírva.

Hogy mire jó?

Azt talán már tudod, hogy a C erősen típusos nyelv, vagyis a fordító mindig megnézi, hogy az a függvény vagy változó, amire hivatkozol, milyen típusú, mennyi és milyen típusú paramétere van - ha pedig olyasmire hivatkozol, amiről még nem hallott, akkor hibát dob.

Amíg az egész programod egy file-ban van, ez általában nem jelent áthidalhatatlan problémát, olyan sorrendbe rakod a definícókat, hogy ha B hivatkozik A-ra, akkor A előbb legyen a file-ban, mint B. De már itt is lehet komplikáció, hiszen mi van, ha az A függvény hívja a B-t a B meg az A-t? Ilyenkor jön jól a deklaráció, hogy az ember leírja a fordítónak, hogy "majd találsz egy B függvényt, ami így fog kinézni, hogy". Ettől a fordító megnyugszik és szépen lefordítja a dolgokat, ha az ellenőrzéseken amúgy átmegy (és majd a linker lesz az, aki kétségbeesik, ha a B definíciója nincs sehol :) )

DRM is theft

(#6060) kovisoft válasza borisz1994 (#6057) üzenetére


kovisoft
őstag

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 az
int 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.

[ Szerkesztve ]

(#6061) borisz1994 válasza dabadab (#6059) üzenetére


borisz1994
csendes tag

Köszönöm a válaszokat. Azt hiszem kezdem érteni. Mindenképp beleolvasok az ajánlott könyvbe hátha könnyebb megértenem.
A függvényeket a program elején dekralárni kell? Nekem ez jött még le abból a kevésből amin sikerült átrágnom magam.
Persze csak ha ez függvény deklaráció :)
int pelda(int);

[ Szerkesztve ]

(#6062) dabadab válasza borisz1994 (#6061) üzenetére


dabadab
titán

Igen, az deklaráció és alapvetően nem kell.

DRM is theft

(#6063) kovisoft válasza borisz1994 (#6061) üzenetére


kovisoft
őstag

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.

(#6064) borisz1994 válasza kovisoft (#6063) üzenetére


borisz1994
csendes tag

Mégegyszer is köszönöm a válaszokat. Hosszú és rögös út vár még rám úgy látom :D Főleg mikrovezérlők programozása miatt szeretném megtanulni (amennyire csak képes vagyok rá) a C nyelvet, de ha többre lennék képes a segítségével az sem volna nagy baj :D

(#6065) #90088192 válasza jattila48 (#6056) üzenetére


#90088192
törölt tag

& buherton :R

Köszönöm a segítséget, sikerült átrendeznem az egészet, most mar működik is.
Persze mindig van mit finomítani, de így mar sokkal egyszerűbb :K
Aztán majd jönnek az újabb kérdések :DDD

(#6066) #90088192 válasza borisz1994 (#6064) üzenetére


#90088192
törölt tag

Hello,

Ha PIC32 is érdekel, akkor az alap hülyeségeken mar túl vagyok vele :K

(#6067) jattila48 válasza borisz1994 (#6064) üzenetére


jattila48
aktív tag

Ahogy többen írták, deklarációra akkor van szükség, ha egy változót, függvényt, vagy típust előbb akarsz használni, mint ahogy definiálnád. Lokális változóknál nincs különbség, ott a deklaráció egyben helyfoglalással is jár. Főleg globális változók és körbe hivatkozások használatakor kell külön deklarálni, és defniálni. Globális változó deklarálása az extern kulcsszóval történik.Valamelyik fordítási egységben ennek definiáltnak kell lenni, a többi, rá hivatkozó TU-ban pedig extern-nel deklaráltnak kell lenni. Függény deklarációjánál extern kulcsszóra nincs szükség (bár megadható). C-ben a függvények mindig globálisak (nincs lokális fv. ellentétben néhány más programozási nyelvvel). Az előre deklarálást nem tudod elkerülni (program szöveg átrendezéssel), ha körbe hivatkozás van (pl. f fv. hívja g-t,ami hívja f-et). Ilyenkor valamelyiket mindenképp előre kell deklarálni (ezt hívják fv. prototipusnak), aminek a tényleges definícióját (a fv. kódját) csak a másik fv. definíciója után tudod megadni. Fontos eset még a struktúrák előre deklarálása. Ezt is a körbehivatkozás teszi szükségessé (pl. rekurzív adatszerkezetek), hasonlóan, ahogy fv.-ek esetén is. A struktúra definíciója hivatkozik B stuktúrára, ami szintén hivatkozik A-ra. Ekkor azonban a csak előre deklarált struktúra típus nem teljes értékű (hiszen még nem ismerjük a szerkezetét), ezért csak rá mutató pointer típus deklarálható a hivatkozó struktúrában. Az ilyen típust incomplete type-nak hívják.

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

(#6068) Ereshkigal válasza jattila48 (#6067) üzenetére


Ereshkigal
őstag

C-ben a függvények mindig globálisak (nincs lokális fv. ellentétben néhány más programozási nyelvvel).

És a static függvények? Azokat csak az adott fájlból éred el.

(#6069) csoki98


csoki98
tag

Üdv!
Teljes mértékben vakon vagyok C programozásban(meg ugy alapból is programozásban), viszont az egyik szabadon választható tárgyamban azt kaptuk feladatnak, hogy írjak programot egy fájlban( gondolom sima .txt) megadott számsorozat növekvő sorrendbe rendezésére. A rendezett számsort egy fájlba kell kiíratnom.
Ha esetleg tudna valaki nekem valamennyire elmagyarázva írni egy ilyen programot, azt nagyon meghálálnám!

"Gondoltál már arra, hogy az univerzum, amiben élünk, talán egy agysejtje egy ismeretlen lénynek?" Poco F3

(#6070) jattila48 válasza Ereshkigal (#6068) üzenetére


jattila48
aktív tag

attól az még globális, abban az értelemben, hogy nem lokális. persze nem elérhető más tu-ból. De ha nagyon akarod, tekintsük kivételnek. A c-ben ettől még nincs lokális fv.

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

(#6071) buherton válasza Ereshkigal (#6068) üzenetére


buherton
őstag

Igaz is meg nem is, mint a mesében. Fájlra lokális vagy globális lesz a függvény a static kulcsszóval. Szerintem jattila48 a lambda és társai gondolt, ami mint nyelvi elem hiányzik a C-ből. Ettől persze implementálható, ahogy az egéz C++-t. Most hirtelen nem találom ezt a könyvet, de arra emlékszem, hogy temérdek void* és -> volt benne :D .

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

(#6072) borisz1994 válasza #90088192 (#6066) üzenetére


borisz1994
csendes tag

Köszi, de egyenlőre az AVR ami érdekel. Arduino-t valamennyire sikerült megismernem, de szeretném inkább c nyelven programozni őket.

(#6073) Ereshkigal válasza buherton (#6071) üzenetére


Ereshkigal
őstag

Igaza(tok) van, mint mindig. :D

[ Szerkesztve ]

(#6074) #90088192


#90088192
törölt tag

Hello Mindenkinek :DDD

Lenne itt egy kis fennforgás és segítséget szeretnek kerni hozza, mert nem jutok dűlőre egymagamban.

A karakter kiíratás amikor elérkezik a határhoz(2X64 képpontból áll a kijelző, amiket külön kell kapcsolgatni, és 8 bit magas a "sor") akkor nem csak térfelet vált hanem nem is tudom mit csinál, kihagyja az első karakter, meg mintha csak egy oszlopnyi szemetet zúdítana a határvonalra :O

Ez lenne a problémás részlet(a font 6 szeles és 8 magas):

for(x=(charcater_code-32)*6; x<((charcater_code-32)*6)+7; x++) //Decodes the character code and make sure the data is sent by 8 bits
{if(y_offset+(x-(charcater_code-32)*6)<63) //Checks if the character has reached the border of the 2 sides of the screen
{
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x]; //Sends the data to the screen
strobe_E();

}else{ //If the Character is belong to the right side

lcd_select(1); //If yes selects the the right side
set_y(0); // Resets the offset
set_x(line_select);
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x]; //Sends the data to the screen
strobe_E();

Ez lenne az egesz:

#include "font6x8.h"
#include "screen.h"
#include "membrane.h"

void InitalizePorts_display(void)
{
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=0;

/* Command port direction settings */

DISPLAY_CS1_Direction =0 ;
DISPLAY_CS2_Direction =0 ;
DISPLAY_RS_Direction =0 ;
DISPLAY_RW_Direction =0 ;
DISPLAY_EN_Direction =0 ;

DelayUs(100);
}

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
DelayUs(15);
}else if(s==1)
{
DISPLAY_CS1 = 0; //Deselects Left side of the screen
DISPLAY_CS2 = 1; //Selects Right side of the screen
DelayUs(15);
}else{
DISPLAY_CS1 = 1; //Selects Left side of the screen
DISPLAY_CS2 = 1; //Selects Right side of the screen
DelayUs(15);
}
}

void strobe_E(void) //Turns enabling line off/on
{
DelayUs(5);
DISPLAY_EN = 0; //Turns Display Off
DelayUs(5);
DISPLAY_EN = 1; //Turns Display On
DelayUs(5);
}

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

void set_x(int x) //Select one of the 8 bit line out of the 8
{
if(x<=7 && x>=0) // Verify input parameter is in range
{
DelayUs(5);
DISPLAY_RS = 0; //Sets Instruction mode
DelayUs(5);
S_DATA_OUT = 0b10111000+x; //select the desired line from the 8 X 8bit lines
strobe_E();
}else{
MEMBRANE_MUTE=1;
}
}


void dsp_on(void)
{
DISPLAY_RS = 0; //Instruction mode
DelayUs(2);
S_DATA_OUT = 0b00111111; //Turns display controller ON
DelayUs(2);
DISPLAY_EN = 1; //Turns Enable line ON
strobe_E();
}

void clr_scr (int Fill_)

{
int x; int y;
lcd_select(2); //Select both side of the display for quicker action
for(y=0;y<=7;y++)
{
set_y(0); //Set y to 0
set_x(y); //Selects line of writing
for(x=0; x<64; x++)
{
DISPLAY_RS = 1; //Turns Data mode ON
DelayUs(2);
S_DATA_OUT = Fill_; //Send data to the selected line
strobe_E();
}
}


}

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

{ int x;
if(y_offset>=64 && 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

set_y(y_offset-64); //Set y

set_x(line_select); //Selects line of writing

for(x=(charcater_code-32)*6; x<=((charcater_code-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<=63 && y_offset>=0) {

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

set_y(y_offset); //Set y

set_x(line_select); //Selects line of writing

for(x=(charcater_code-32)*6; x<((charcater_code-32)*6)+7; x++) //Decodes the character code and make sure the data is sent by 8 bits
{if(y_offset+(x-(charcater_code-32)*6)<63) //Checks if the character has reached the border of the 2 sides of the screen
{
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x]; //Sends the data to the screen
strobe_E();

}else{ //If the Character is belong to the right side

lcd_select(1); //If yes selects the the right side
set_y(0); // Resets the offset
set_x(line_select);
DISPLAY_RS = 1;
S_DATA_OUT = font6x8[x]; //Sends the data to the screen
strobe_E();
}
}
}
else
{
MEMBRANE_MUTE=1;
}

}

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

}

[ Szerkesztve ]

(#6075) buherton válasza #90088192 (#6074) üzenetére


buherton
őstag

Ez így olvashatatlan. Kérlek vedd ki a hardcodeolt értékeket és használj függvényeket, illetve makrókat _értelmezhető_ névvel.

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

(#6076) kovisoft válasza csoki98 (#6069) üzenetére


kovisoft
őstag

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

(#6077) #90088192 válasza buherton (#6075) üzenetére


#90088192
törölt tag

Hello, ha egyre gondolunk akkor :R
azok nem hard coded értékek hanem fizikai portok.

[ Szerkesztve ]

(#6078) #90088192 válasza #90088192 (#6077) üzenetére


#90088192
törölt tag

Leesett miről beszelsz, maris javítom, elnézést kicsit korán volt :)

:R

(#6079) #90088192 válasza buherton (#6075) üzenetére


#90088192
törölt tag

Koszonom :R
Remélem erre gondoltál :)

Különben igen érdekes maga a probléma, a bal oldali képernyő gyakorlatilag túlcsordul(Módosítottam a kodon így is duplázza az oszlopokat, es elkezd a 0. oszlopba írni)

Maga a problémás részlet:

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

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

set_y(y_offset-Display_width/2); //Deducts the the half of the display size Set y

set_x(line_select); //Selects line of writing

for(x=(charcater_code-Font_offset)*Font_width; x<=((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
{
send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
}
} else if(y_offset<=(Display_width/2)-1 && y_offset>=0) {

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

set_y(y_offset); //Set y

set_x(line_select); //Selects line of writing

for(x=(charcater_code-Font_offset)*Font_width; x<((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
{if(y_offset+(x-(charcater_code-Font_offset)*Font_width)!=(Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
{
send_data_screen(font6x8[x]);

}else{ //If the Character is belong to the right side

lcd_select(1); //If yes selects the the right side
set_y(0); // Resets the offset
set_x(line_select); //Selects line of writing
send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
}
}
}
else
{
MEMBRANE_MUTE=1;
}

}

Es az egesz en block

#include "font6x8.h"
#include "screen.h"
#include "membrane.h"

#define Font_width 6
#define Font_offset 32
#define Font_height 8
#define Display_width 128
#define Dislpay_height 64
#define Display_rows 8

//#define Font_type font6x8

void InitalizePorts_display(void)
{
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=0;

/* Command port direction settings */

DISPLAY_CS1_Direction =0 ;
DISPLAY_CS2_Direction =0 ;
DISPLAY_RS_Direction =0 ;
DISPLAY_RW_Direction =0 ;
DISPLAY_EN_Direction =0 ;

DelayUs(100);
}

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
DelayUs(15);
}else if(s==1)
{
DISPLAY_CS1 = 0; //Deselects Left side of the screen
DISPLAY_CS2 = 1; //Selects Right side of the screen
DelayUs(15);
}else{
DISPLAY_CS1 = 1; //Selects Left side of the screen
DISPLAY_CS2 = 1; //Selects Right side of the screen
DelayUs(15);
}
}

void strobe_E(void) //Turns enabling line off/on
{
DelayUs(5);
DISPLAY_EN = 0; //Turns Display Off
DelayUs(5);
DISPLAY_EN = 1; //Turns Display On
DelayUs(5);
}

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

void set_x(int x) //Select one of the 8 bit line out of the 8
{
if(x<=Display_rows-1 && x>=0) // Verify input parameter is in range
{
DelayUs(5);
DISPLAY_RS = 0; //Sets Instruction mode
DelayUs(5);
S_DATA_OUT = 0b10111000+x; //select the desired line from the 8 X 8bit lines
strobe_E();
}else{
MEMBRANE_MUTE=1;
}
}


void send_data_screen (long int Data) //Sends Data to the Display hardware
{
DISPLAY_RS = 1; //Enables Data mode
DelayUs(5);
S_DATA_OUT = Data; //Insert Data to the hardware line
strobe_E();
}
void dsp_on(void)
{
DISPLAY_RS = 0; //Instruction mode
DelayUs(2);
S_DATA_OUT = 0b00111111; //Turns display controller ON
DelayUs(2);
DISPLAY_EN = 1; //Turns Enable line ON
strobe_E();
}

void clr_scr (int Fill)

{
int x; int y;
lcd_select(2); //Select both side of the display for quicker action
for(y=0;y<=Display_rows-1;y++) //Loop for the rows
{
set_y(0); //Set y to 0
set_x(y); //Selects line of writing
for(x=0; x<(Display_width/2); x++) //Loop for the columns
{
send_data_screen(Fill);
}
}


}

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

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

set_y(y_offset-Display_width/2); //Deducts the the half of the display size Set y

set_x(line_select); //Selects line of writing

for(x=(charcater_code-Font_offset)*Font_width; x<=((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
{
send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
}
} else if(y_offset<=(Display_width/2)-1 && y_offset>=0) {

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

set_y(y_offset); //Set y

set_x(line_select); //Selects line of writing

for(x=(charcater_code-Font_offset)*Font_width; x<((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
{if(y_offset+(x-(charcater_code-Font_offset)*Font_width)!=(Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
{
send_data_screen(font6x8[x]);

}else{ //If the Character is belong to the right side

lcd_select(1); //If yes selects the the right side
set_y(0); // Resets the offset
set_x(line_select); //Selects line of writing
send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
}
}
}
else
{
MEMBRANE_MUTE=1;
}

}

void string_out(char* message, float variable, int line, int y_offset)
{
int Maximum_num_char= Display_width/Font_width; //Maximum number of characters what can be placed in one row

char test[Maximum_num_char],i=0,j;
char a[Maximum_num_char];
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*Font_width,test[j]);

}

[ Szerkesztve ]

(#6080) #90088192 válasza #90088192 (#6079) üzenetére


#90088192
törölt tag

Megvan a probléma, igen érdekes Hardvere jellegű, azt gondoltam valami hülyeséget csináltam a karakter kódolással. Nem :DDD

Ez a jó:

int strobe_E(void) //Turns enabling line off/on
{
DelayUs(10);
DISPLAY_EN = 1; //Turns Display On
DelayUs(10);
DISPLAY_EN = 0; //Turns Display Off
DelayUs(10);

}

és ez a rossz:

int strobe_E(void) //Turns enabling line off/on
{
DelayUs(10);
DISPLAY_EN = 0; //Turns Display Off
DelayUs(10);
DISPLAY_EN = 1; //Turns Display On
DelayUs(10);

}

(#6081) nucso02


nucso02
csendes tag

Sziasztok!

C programozás beadandó feladatomban szeretnék egy kis segítséget kérni Tőletek.
A feladat a következő lenne:

Irjon egy chat programot! (2 fo"! - kliens/szerver)
Valositsa meg osztott memoria hasznalataval.
Amikor adott signalt kap (pl. SIGHUP), akkor olvassa ki az uzenetet.
Egyebkent varjon a felhasznalotol szoveget.
Ha beir valamit a felhasznalo, akkor irja be az osztott memoriaba, es kuldjon signalt a partner processznek.
Ugyanabban osztott memoria szegmensben tarolja el a szignalozashoz szukseges pid-eket is!
A mester processz legyen az ami hamarabb indul, ez hozza letre az osztott memoria szegmenst, illetve ez fogja megszuntetni is.
A szolga processzek(bármennyi lehet) pedig csak hasznalják az osztott memoriat.

1szolga-1mesterrel már született megoldás, viszont a bármennyi szolga kifog rajtunk.

Minden megoldás/tipp sokat segítene, és nem lennék hálátlan :R
Köszönöm előre is!

(#6082) kovisoft válasza nucso02 (#6081) üzenetére


kovisoft
őstag

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?

(#6083) Gabesson


Gabesson
csendes újonc

Sziasztok a mai digitális oktatásban kapott leckémnek egyszerűen nem tudok, hogy nekifogni. Ebben szeretnék segítséget kérni. A feladat így szól:
Készítsen programot, amely megkeresi és kiírja azokat a 10-es számrendszerbeli háromjegyű számokat, amelyeknek a számjegyeit köbre emelve és összeadva eredményül magát a számot kapjuk (Armstrong-féle számok).

(#6084) dabadab válasza Gabesson (#6083) üzenetére


dabadab
titán

És hol akadtál el?

DRM is theft

(#6085) Gabesson válasza dabadab (#6084) üzenetére


Gabesson
csendes újonc

Nagyon az elején, nem tudom, hogy inteljem be a programnak az összes háromjegyű számot.

(#6086) kovisoft válasza Gabesson (#6085) üzenetére


kovisoft
őstag

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

(#6087) kovisoft válasza kovisoft (#6086) üzenetére


kovisoft
őstag

(Bocs, kifutottam a szerkesztési időből)

De csinálhatod fordítva is: három egymásba ágyazott ciklussal mész a százasokkal 1-től 9-ig, a tízesekkel 0-tól 9-ig, az egyesekkel 0-tól 9-ig. És akkor a háromjegyű számod: százasok*100+tízesek*10+egyesek.

(#6088) Gabesson válasza kovisoft (#6087) üzenetére


Gabesson
csendes újonc

Köszönöm!

(#6089) Gabesson


Gabesson
csendes újonc

Sziasztok, eddig jutottam el, a program elindul, fut is hibaüzenet nélkül, csak nem ír ki semmit, nem látom hol rontottam el.
#include <stdio.h>
void main()
{
system("CHCP 1250"); system("CLS");
int szazasok, tizesek, egyesek, i, szam;
do {
for (i=0; i=999; i++); {
szazasok=i/100 ;
tizesek= i%100/10 ;
egyesek= i%10 ; }
}
while (i=999) ;
szam=szazasok*100+tizesek*10+egyesek;
if (szam==szazasok*szazasok*szazasok+tizesek*tizesek*tizesek+egyesek*egyesek*egyesek)
printf("%d ", szam);
}
%MCEPASTEBIN%

(#6090) axioma válasza Gabesson (#6089) üzenetére


axioma
veterán

1. hasznald a kod formazast
2. a haromjegyu szamok 100-tol vannak nem 0-tol
3. miert van do es for ciklus is?
4. a for ciklus bentmaradasi feltetele sose teljesul, mert ott <= kene legyen, a while meg a kilepesit sose eri el, (*) mivel nem noveled az i-t (na jo 1x de aztan visszaall)
+1. ilyenkor elso teszt hogy kiveszed az if-et, es ha me'g mindig nem ir ki semmit, akkor a kiirasig (feltetelig) el se jut - az nem tunt fel hogy nemcsak hogy nem ir ki, hanem nem is allt le? azt is figyeld
Egy picit kene szerintem nezegetned az alapveto vezerlesi szerkezetek helyes hasznalatat a tankonyvben, jegyzetben, vagy a neten. [Beirhatnank ide a megoldast de azzal nem jegyezned meg melyik miert nem volt jo.]

(*) Re 6092:
Igen, ezen en is gondolkoztam mert nem is neztem elsore hogy pont egy C-s topikban van egy algoritmikus(nak tuno) kerdes, nalam a hatultesztelos ciklus az kilepesi felteteleskent rogzult me'g pascal idokbol. De teny, tudhattam volna a while-bol hogy az is bennmaradasi, bocsanat a hibaert. Tehat kilep, es leall, csak a 0 nem felel meg a feltetelnek...

[ Szerkesztve ]

(#6091) kovisoft válasza Gabesson (#6089) üzenetére


kovisoft
őstag

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

[ Szerkesztve ]

(#6092) dabadab válasza kovisoft (#6091) üzenetére


dabadab
titán

amúgy sem jó, mert a feltételben a szimpla = jel nem egyenlőségvizsgálat, ami a dupla ==, hanem értékadás

És az még mindig nem lenne jó, mert a szükségesnek pont a fordítottja lenne - ugyanis az ott nem a kilépés feltétele, hanem az ismétlésés (vagyis akkor hagyja abba a do ... while-t, amikor az NEM igaz) :)

DRM is theft

(#6093) kovisoft válasza dabadab (#6092) üzenetére


kovisoft
őstag

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

(#6094) dabadab válasza kovisoft (#6093) üzenetére


dabadab
titán

Persze, úgy tulajdonképpen akár működhetne is, csak jól láthatóan a költő szándéka nem az volt és szerintem félreértette a feltételt.

DRM is theft

(#6095) #90088192


#90088192
törölt tag

Hello Mindenkinek

Segítséget szeretnek kerni, falba ütköztem, de nem értem miért.

../screen.c: In function 'put_pixel':
../screen.c:128:35: error: invalid operands to binary | (have 'int (*)(void)' and 'int')
send_data_screen(data_read | (BASE_ADDRESS_PIXEL << x%Display_pages));

Maga a probléma, amit addig értek(?), hogy nem lehet bináris műveletet elvégezni pointeren.

Azt nem értem miért lett az pointer :DDD

A program részletek amik relevánsak(Elnézést még nem kommenteltem az új szekciót mert nem működik):

int data_read(void)
{
int data_in;
DISPLAY_RS = 1;
DISPLAY_RW = 1;
DISPLAY_DATA_DIRECTION = 1;
DelayUs(Hardware_delay*2);
data_in = S_DATA_IN;
DelayUs(Hardware_delay*4);
DISPLAY_DATA_DIRECTION = 0;
return(data_in);

}

int send_data_screen (long int Data_out) //Sends Data to the Display hardware
{
if(Data_out<=(Dislpay_height/Display_pages)*(Display_width/2) ) //Checks is the data length is valid
{
DISPLAY_EN = 0; //Turns Display Off
DISPLAY_RS = 1; //Enables Data mode
DelayUs(Hardware_delay);
S_DATA_OUT = Data_out; //Insert Data to the hardware line
strobe_E(); //Turns Display On/off
DISPLAY_RS = 0; //Disables Data mode

}else{
return(1);
}
}
int put_pixel(int x, int y)
{
if(x>=0 && x<=63 && y>=0 && y<=127)
{
goto_xy(x/Display_pages,y);
send_data_screen(data_read | (BASE_ADDRESS_PIXEL << x%Display_pages));

}else{
return(1);
}
}

(#6096) buherton válasza #90088192 (#6095) üzenetére


buherton
őstag

A lényeg éppen lemaradt, hogy mi a Display_pages. Tippre egy ilyen szignatúrájú függvény: int (*)(void). Vélelmezhetően így kellene meghívnod: Display_pages().

[ Szerkesztve ]

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

(#6097) #90088192 válasza buherton (#6096) üzenetére


#90088192
törölt tag

Hello :R

#define Display_pages 8

8 X 8bites lapokra van vertikálisan felosztva a képernyő.

Ennyi lenne :K

[ Szerkesztve ]

(#6098) kovisoft válasza #90088192 (#6095) üzenetére


kovisoft
őstag

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

(#6099) Ereshkigal


Ereshkigal
őstag

Ha már pörög a topik...
Tud valaki ajánlani Windows alá konzolos interface library-t? Olyasmit, mint mondjuk az ncurses Linux alatt. A Win32 konzol apitól valami magasabb szintű cucc kéne. :)

(#6100) #90088192 válasza kovisoft (#6098) üzenetére


#90088192
törölt tag

:W :W :W :W :W
:R :R :R :R :R :R

Az volt az :DDD

Köszönöm

Copyright © 2000-2024 PROHARDVER Informatikai Kft.