- Honor Magic6 Pro - kör közepén számok
- Android alkalmazások - szoftver kibeszélő topik
- Huawei Mate X6 - keleti oldal, nyugati oldal
- Honor 400 Pro - gép a képben
- Samsung Galaxy S24 FE - később
- Motorola Edge 50 Neo - az egyensúly gyengesége
- Sony Xperia 1 V - kizárólag igényeseknek
- VoLTE/VoWiFi
- Google Pixel topik
- Netfone
Új hozzászólás Aktív témák
-
kingabo
őstag
válasz
skylaner #5252 üzenetére
Jaja. Nekem clipper kódot kellett portolnom igaz C#-ra. Fv első sora if akármi, az endif x ezer sorral lejjebb. Képtelenség volt átlátni, hogy mit csinál. Ha a működés fel lett volna osztva további fk-re, akkor szépen látszott volna minden lépés, hogy mit is csinál a cucc. (pl kérd le az adatokat, szűrd le, számolj velük, generálj exportokat, mentsd a változásokat)
Ráadásul, ha ügyesen bontad szét a működést és jó fv neket adsz igen nagy mértékben le lehet csökkenteni a kommentek mennyiségét. Nem kell kiírni, hogy most ezt csinálom azt csinálom, mert az fv nevéből látszik. A sokkal fontosabb, hogy miért csinálom kommentek (ami a sok komment között elveszik) pedig szem előtt lesznek, keresés nélkül is.
A C#-os region-okra egyre több helyen tekintenek rosszként. Github-on pl több helyen is írták, hogy egyáltalán ne legyen a kódban... Mellesleg amikor egy rakat kódot összefogsz egy régióba, azt akár ahogy van ki is rakhatod egy fv-be. És késöbb, ha bele kell nyúlnod könnyebben találod meg, könnyebb módosítani, sőt még a többi x helyre se kell a fixet copy-paste-elni, mert mindenhonnan fv-t hívsz.
Persze One-Man-Army esetén úgy dolgozol, ahogy jól esik, de ha másokkal kell együtt dolgozni, vagy más kódját kapod meg, amit először meg akarnál érteni, akkor (legalábbis számomra) mindenképpen hasznos, ha fv-kba szét van robbantva a kód és átlátható, mintha azt sem tudod az 1000 sorban hol is vagy éppen.
Sztem. -
kingabo
őstag
válasz
superfinest #4288 üzenetére
A C-hez és a Javahoz gyakorlatilag teljesen másmilyen gondolkodás mód szükséges, hiába vannak közös nyelvi elemek. Ahogy már mások is írták, emiatt nem lesz sok előnyöd a C megtanulása után ahhoz képest, aki egyből a Javaval kezd, viszont sok időd elmehet vele és valószínű vért fogsz izzadni. Ráadásul sok a kezdők szemében "hibára" vagy nehézségre a java már vagy tartalmaz valamilyen nyelvi elemet, vagy megoldást, amikkel az általad kitűzött célokat könnyebben és gyorsabban el tudod érni.
-
kingabo
őstag
válasz
superfinest #4282 üzenetére
Hali!
Ez a C és nem a C++ topik. Másrészt felül a téma összefoglalóban könyveket, oldalakat is ajánlanak.
-
kingabo
őstag
Ebben a témában erősen ajánlom Brian "Beej" Hall cikkét: magyar változat, angol több formátumban. (ez alapján írtam "chat" szervert minden benne van)
-
kingabo
őstag
Vegyük a következő esetet: s1[a-0] = 9, s2[b-0] = 8, ekkor osszeg[a-0]=s1[a-0]+s2[b-0]+g; az osszeg[a] helyére 17-et ír, nem pedig 7-et. Nálad a tizesek helyén van a 4 az egyesek helyén a 11, ezért lett 411.(ha teszel egy szóközt a jegyek kiíratása közé, úgy könnyebb észrevenni) Megoldás: az osszeg[a-.. jobb oldalának vedd a 10-el vett maradékát.
-
kingabo
őstag
Nos, mivel stringként olvasol be a file-ból, ezért a tömb elemek nem a számokat, hanem azok ascii kódját tartalmazzák. Pl a 0 helyett 48-at. Tehát ha a szám kellene, nem a kódja, akkor minden karakterből le kell vonni 48-at. s1[i] -= 48; (lehet van szebb megoldás is, de most nem jut eszembe.
ui: 5 percig tudod szerkeszteni a hsz-ed.
szerk: az atoi pont erre való.
-
kingabo
őstag
Huh, 1000 éve nem olvastam file-ból c-ben.
, talán a legegyszerűbb az lenne, ha írnál egy fv-t ami az ascii-ben tárolt számot átalakítja, annak a valódi értékére. Ehhez a 0 vagy az 1 (nemtom melyik van elől) ascii kódját kellene minden számjegynél levonni.
"átvitelnél a túlcsordulásra gondolsz?"
Igen.Feladat: sztem jó az irány, az előjelezést meg nem olyan nehéz megoldani.
-
kingabo
őstag
osszeg[a-i]=s1[a-i]+s2[b-i];, ha jól sejtem itt a számok ASCII kódját adod össze, ezért van gond a kiíratással. Megoldás: a beolvasásban ne stringként olvas be, hanem számként. Hiba még, hogy pl 8+9 esetén a "túlcsordulást" nem viszed tovább.
Szerintem ha megosztod a feladatot lehet, hogy a mostani elképzelésednél könnyebbet tudnánk kitalálni.szerk: lemaradtam.
Ja és igen a szám hossz...
-
kingabo
őstag
Azt írtam, hogy hasonlít, nem azt, hogy ezaz.
Bocs rosszul rémlett a név: Eratoszthenész szitája -
kingabo
őstag
válasz
Bobrooney #3765 üzenetére
"Ha alapvetően a tömb összes eleme 0, akkor az összes elemnek a program futása során 1-nek kéne lennie."
Ez így nem igaz, hiszen az elsőt átállítod 0-ról 1-re, aztán a köveket is. Aztán kövi ciklusban a 2.at átállítod 1-ről 0-ra...
Ami pedig csak most tűnt csak fel: a while ciklisban z+=i, nekem ez vhogy z+=1 volt. -
kingabo
őstag
Elvileg azt csinálja amit írtál, hogy végig megy a tömbön és minden utána lévő értéket negál. Ill az aktuális i előttitől, az utolsó előttiig.
Debugban nézted? A fentebb említett, elrontott kiíratáson kívül más hibát nem látok benne t[z]-t iratod ki a t[i] helyett."az első for ciklust kivettem"
Akkor meg is van a hiba: memória szemét van a tömbben azért ír ki mindent!szerk: a ciklusokban túlindexelsz!!! 100 elemű a tömböd, de az i<=100 miatt a 101-ediket is megpróbálod elérni. Szintúgy a while-ban... A kinullázásban és a kiíratásnál meg nem.
-
kingabo
őstag
válasz
bandi0000 #3720 üzenetére
Pár dolog:
- a while ciklusban az i változód a tomb utolsó utáni elemére fug mutatni.
- négyzetszámot nem úgy állítasz elő, hogy 1-et vagy 2-t megszorzol 2-vel.
- miért várod, hogy a kiíratásnál más legyen az a és a b értéke, ha az utolsó for ciklusban meg se változtatod őket? -
kingabo
őstag
-
kingabo
őstag
válasz
PumpkinSeed #3660 üzenetére
Ne vedd sértésnek, de erre a két esetre kérnék pl-t.
case (400-al osztható 100al nem)
case (400-al osztható 4-el nem)Írd Clipperbe, ott lehet a case-ben ilyet írni.
-
kingabo
őstag
válasz
chabeee #3631 üzenetére
Rosszul állítod be a visszafelé mutató pointert az insert_after-ben. Először át kéne menni az új elemre és annak állítani a prevjét. Jelenleg minden prev saját magára mutat.
nodee->next = (node*)malloc(sizeof(node));
nodee->prev = nodee;
nodee = nodee->next;
nodee->data = data;...
helyettnodee->next = (node*)malloc(sizeof(node));
nodee = nodee->next;
nodee->prev = nodee;
nodee->data = data;szerk: lehet vhogy kiemlést is betenni a kódba? Nekem nem jött össze.
szerk #2: a nodee-n kívül az előtte és az utána jövőnek is karban kéne tartani a pointereit. (sztem célszerű lerajzolni, hogy mit hogy kell átkötni)
-
kingabo
őstag
-
kingabo
őstag
válasz
Jester01 #3546 üzenetére
Nyertél!
bandi0000: Korábban több megoldást is leírtunk, sztem ezt a fajta megoldást felejtsd el! (annó egy másik proginál ezért is írtam le egy másik fajta megoldást) Indok: mi van ha 100 karakteres számok kellenek? Mi van ha nem 2esből hanem 8asból kell váltani? A korábbi algókhoz alig kell hozzányúlni, a Tiédet meg teljesen újra kell írni
-
kingabo
őstag
válasz
bandi0000 #3543 üzenetére
Még if se kell.
Hátulról előre haladsz a tömbbön, a tömb i-edik értéket megszorzod a hozzátartozó hatvánnyal és ezt összegzed. A hatvány pedig a kövi: kezdetben 1 aztán minden iteráció végén szorzod 2-vel.
Ha if-fel akarod: a szorzás előtt megnézed, hogy az adott érték nem nulla-e. -
kingabo
őstag
válasz
bandi0000 #3471 üzenetére
Egy alternatív megoldás az eredeti 5letedet is felhasználva: csinálsz 3db 10 elemű tömböt feltöltöd őket, hogy a százasok, tízesek, egyesek helyére mit kell írni, ha a tömbindex + 1 az érték. Ezután a szétbontott számokat a fenti tömbökben indexként használva összefüzöd a római számot.
-
kingabo
őstag
válasz
sztanozs #3429 üzenetére
Euklideszi algoritmus, van egy bővített változata is (ezt hirtelen csak tételsorokban találtam meg
). Ha tudsz angolul, akkor jóval többet írnak róla: Euklideszi algoritmus (angol wiki).
-
kingabo
őstag
válasz
shinodas #3318 üzenetére
Egyrészt az fv meghívásakor a visszatérési értéket semmilyen változónak nem adod értékül, másrészt a 2 return nem tud végrehajtódni, ugyanis már első után befejeződik a függvény. Jelen esetben a függvényednek void-nak kéne lennie, és nem kell a végére return.
Egyébként a problémádra itt #4 JackOfAllTrades hsz-e mutat egy pl-t, erre a megoldásra céloztam fentebb.
Korábban a pointerekről írtam ide egy hosszabb hsz-t, igaz a paraméter átadás nem volt része, keresővel sztem hamar megtalálod.
Egyébként könyvből tanulsz, netes cikkből, vagy megpróbálsz rájönni hogy mennek a dolgok? Az idők folyamán elég sok könyv, jegyzet, példatár lett itt linkelve érdemes őket megnézni.
szerk: és még lassú is vagyok.
-
kingabo
őstag
válasz
shinodas #3314 üzenetére
A magan és a massal az miért 1-1 pointer? De ha már pointer, akkor miért nem egy létező memória területre mutatnak: másik változó, vagy általad lefoglalt memória terület?
Régen c-ztem már, de sztem a pointer helyett, mintha egy referenciát kéne átadni és akkor nem kell szenvedned a pointerezéssel. Amit -nem sértésként- de nem igazán értesz... -
kingabo
őstag
Persze működne láncolt listával is, de 1millió elemnél elég durva overhead lenne az 500 000. elemet megtalálni, a felezgetésekhez. Másrészt a tömb elemei sorfolytonosan vannak a memóriában, ezekből egyszerre több is bekerül a proci cache-jébe, míg a lista elemei össze-vissza lehetnek a memóriában, sokkal többször kellhet a procinak a ramhoz fordulnia. Ekkora elemszámnál meg már elég rendesen érvényesül a sok kicsi sokra megy mondás...
-
kingabo
őstag
válasz
cooldongo #3251 üzenetére
Ez már sokkal jobb.
Jól hívtad meg, viszont ennek megint nem szabadna fordulnia: int a visszatérési értéke az fv-nek, de nincs return sehol sem. Amennyiben elég a kiíratás, akkor int helyett legyen void az fv, ha kell egybeesik-e vagy sem, akkor használd (#3252) Sk8erPeter által leírt megoldást. -
kingabo
őstag
válasz
cooldongo #3248 üzenetére
Az a probléma, hogy stringként kérsz be adatot nem pedig számként.
(#3249) cooldongo: kérlek írd le saját szavaiddal, hogy mit csinál az egybeesik függvény. (nem azt, hogy mit kéne csinálnia) Egyből rájösz mi a gond.
Illetve, légy szíves programkódként beilleszteni a kódot, ahogy erre mindenki meg lett kérve az első hsz-ben. Ha úgy illeszted be, akkor tagold a kódot, hogy könnyebben olvasható legyen másoknak. (ha ez neked nem annyira fontos) Köszi.
-
kingabo
őstag
Ja hogy Ti azt az idióta összekattintgatós izét használjátok? Azzal 10 percet bohóckodtam, de hogy azzal összehozni egy bt-s távirányítást elég esélytelen.
Java esetén lejos, C esetén nxc, meg van saját assembly-je is az nbc, ezekkel programozható, a "doboz pakolós", összekattintgatós csak játék 5 éveseknek. Szerintem. -
kingabo
őstag
Ne stringgel teszteld, vagy ha azzal, akkor karakterként irasd ki, illetve írd a végére a string lezáró \0 karaktert is. Egy int tömbbel sokkal látványosabb a dolog.
Az elmélethez: azt is érdemes megmondani, hogy mi történik, ha egy n elemű tömb n+1-edik elemére hivatkozol/írod. -
kingabo
őstag
Úgy tűnik a vs alapból kinullázza a tömböt, ráadásul a gyorsabb megoldással. Vajon miért nem veszi észre, hogy a többit is lehetne optimalizálni.
hruodnand: Ha megnézed a lenti kódot (az 1db 0-ásat), akkor akár lehet az is a gond, hogy nincs elég 0.
For ciklussal kinullázni esetleg? Így akkor sem lesz gond, ha 8 helyett 22 elemű lesz a tömb. -
kingabo
őstag
Nem tudom feladat-e, de célszerű lenne ellenőrizni, hogy tényleg számot adott-e meg a lyúzer.
Pár észrevétel a kódhoz:
- az itoa-t nem használod, szerintem felesleges a hozzá tartozó include
- if(!(mard == 0 || mard == 3 || mard == 6 || mard == 9)) helyet írhatod ezt is
if(mard != 0 && mard != 3 && mard != 6 && mard != 9)) (ha már 1 hamisat talál, akkor a többit ki se értékeli)
- nem tudom kötelezőe a fenti módon való számolás, de sokat gyorsíthatnál, ha simán csak összegzed a számjegyelet, esetleg a mard-nak a 3al vett maradékát néznéd, hogy 0-e (ez utóbbi valszeg lassabb lenne, de a kód átláthatóbbá válna, illetve könnyebben módosítható, ha 3 helyett a 9-el való osztás kell)
- for ciklus helyett egy while sokkal szebb lenne -
kingabo
őstag
Ciklusban kell végezned amit leírtam.
Tehát a példádnál maradva az első iterációban leszeded az 1-et, a szám 15 lesz, aztán a másodikban a 5-t, a szám 1 lesz, aztán a harmadikban a maradék 1 lesz, a szám 0.Szerk:
Ez azért így elég csúnya: data[sizeof(int)];!! 32bites gépen ez 4 lesz, viszont 9 számjegyű számot is lehet tárolni a változóban! -
kingabo
őstag
5let: A számot osztod maradékosan 10-el, így megkapod az utolsó számjegyet, amit hozzáadsz egy összeghez. Ezt kell addig csinálnod, amíg végül 0-t nem kapsz. Ezután megvizsgálod, hogy az összeget 3-al osztva 0-e a maradék.
C-s megvalósításhoz:
maradek = szam % 10;: a szám 10-el vett osztási maradéka (a szam változatlan marad)
szam = szam / 10;: a szám osztása 10-el (int osztás) -
kingabo
őstag
válasz
eriktoth #2862 üzenetére
Pedig az arcsin-ben van faktor számítás: [link]
Viszont ezt egy sima for ciklussal sokkal könnyebben ki tudod számítani. (egy kis gondolkodás után az x ^ (2n+1)-re is kapsz egy szép iterációs képletet) Illetve azt ne felejtsd el, hogy a szigma itt egy limeszt jelent, vagyis pontos értéket nem nagyon fogsz kapni. Nekem párhuzamosan több gépen kellett sin-t számolni (pp-ből ilyen fantázia dús feladatot kaptunk), ott ha túl nagy számot adtunk meg x ^ (2n+1) igen hamar túlcsordult, ha túl kicsit, nagyon hamar átlépte a gép 0-át. (az a legkisebb 0-nál nagyobb szám, amit a gép még tud ábrázolni)
(#2863) WonderCSabo: én is így látom.
-
kingabo
őstag
válasz
chabeee #2839 üzenetére
Ezekkel mit akartál megvalósítani?
for(i=0;i<n1;i++) {
counter++;
}
for(i=0;i<n2;i++) {
counter++;
}Szerintem ez ugyanaz és nagyságrendekkel gyorsabb:
counter = n1 + n2;
A t3-at, ha csak a kiíratáshoz használod, akkor fölösleges a másolás. Ha ez egy visszatérő paraméter akarna lenni, akkor az fv végén lévő free(*(t3)); törli és ha ezután használni szerednéd (a törölt elemeket), csúnya dolgok történ(het)nek.
-
kingabo
őstag
válasz
TheRolf #2813 üzenetére
Hali!
Csak gyorsan átfutva az tűnt fel, hogy a string-ben az n+1-edik elemre hivatkozol. Pl van egy 5 hosszú stringed, akkor az indexek 0 és 4 között vannak a string[len-i] i=0 esetén viszont 5. Megoldás vonj le még 1-et az indexből, vagyis így nézzen ki string[len - i - 1].
Hibakereséhez ajánlom a debugger használatát. -
kingabo
őstag
Ez a szabványos c-ben nincs benne, a Borland tette bele a turbo c-be (meg pascalba), tudtommal.
Feribacsi555 :Ezzel tehetsz egy próbát: changing text color in c
-
kingabo
őstag
válasz
PetyaMIK #2762 üzenetére
Helló!
Jester01 észrevételein felül, while-ba kéne még egy feltétel, hogy ne kérhesd be a 101-edik értéket. Illetve kiíratásnál használhatod az index+1-et is, így nem lesz szükséged az Edik változóra.
Ja és egy kérés legközelebb a kód beillesztése után jelőld ki a kódot és nyomd meg alul a Programkód gombot, úgy nem fognak a tabulálások elveszni.
-
kingabo
őstag
válasz
Barett 50cal #2751 üzenetére
Olvass vissza pár hsz-t, ehhez nagyon hasonló dologról volt szó.
-
kingabo
őstag
válasz
Rickazoid #2745 üzenetére
Ahogy Jester01 ajánlotta sort olvass be, amit az atoi-val (ascci to int) alakíts át számmá és ennek az eredményét vizsgáld a switch-ben. Elötte persze ellenőrizni kell, hogy mit adott vissza az atoi: pl 11a esetén 11-t, a esetén 0-t (de 0 esetén is 0-t ad vissza, ami jó!), ilyenkor nyilván újra be kell kérni.
-
kingabo
őstag
válasz
Jester01 #2668 üzenetére
Úgy rémlett, hogy korábban én a noskipws-t használtam erre a problémára, a leírásban nem találtam semmit ami miatt ne működne. Viszont baromira érdekel, hogy mivel keverem?
Akkor marad a cin.get vagy a cin.getline. (sztem megéri kiszedni a sorvége jelet is a pufferből) -
kingabo
őstag
Gondolom érted magát a kivételt és hogy mi okozhatja.
Nem tudom miben fejlesztesz, ha van rá lehetőség próbáld lépésenként futtatni, hogy megtaláld a hiba helyét, pontos okát. Ha nincs rá, akkor tele kell pakolni a progit kiíratásokkal, hogy megtaláld, hogy pontosan hol váltódik ki a kivétel. Ha a hely megvan, akkor a változók értékeit/változásait írasd ki.
Haramadik lehetőség, hogy annyira lecsupaszítod a kódot amennyire csak lehet, de még a hibás rész benne van és ezzel próbálsz rájönni a hibára, vagy esetleg azt osztod meg itt, hátha valaki kiszúrja mi a gond. -
kingabo
őstag
Nekem ennyire mélyen nem kellett c-s file kezelés, sajnos.
Esetleg próbáld meg ezeket: [link], posix (hátha mond valamit) szabványban a hálózati kommunikációs részhez kell, szintén little-big endian konverzió miatt.A másik, hogy elő jöhet-e a dupla nulla? Fölösleges olyannal szívni, amit nem kell leprogramoznod.
A for írható így is:
for(i=0;i<4;j--;i++;){
s[i]=sc[j];
} -
kingabo
őstag
Próbáld meg úgy, hogy papírra csak az algót írod fel nem c-sen, hanem általánosan prg nyelv függetlenül. (beolvasás helyett pl egyszerűen tömböt használsz) Illetve nagy segítség lehet, ha pl egy minta filet, akár így x és y formában felírsz és abból "kézzel" építed fel az adat struktúrát. (lesz 5leted az algóra): X , Y , Y , X, X, Y, X, Y, Y
-
kingabo
őstag
válasz
Sweet Lou 6 #2455 üzenetére
Gondolom az sem véletlen, hogy a kettőspont c (: C) smiley-t szúrtad be.
-
kingabo
őstag
Bocs, ezt nem tudtam kihagyni: write in c
-
kingabo
őstag
válasz
lalbacsi #2448 üzenetére
Hali!
Először is: légy szíves használd a programkód gombot, hogy olvasható legyen az idézett kódod! (pár hsz-el feljebb képpel le van írva hogy hogyan kell!)
Baromi régen borland pascalban rajzolgattunk, elvileg borland c-ben ugyanazok az fv-k csak nyilván c-s stílusban...Pascalos kód: egy "forgó" kereket rajzol ki a képernyő közepére, ha minden igaz, remélem sikerül hasznát venni. (szerintem c-s "szemmel" is olvasható a kód, ha valami nem világos kérdezz, hátha rémlik még
)
uses crt,graph;
var i,gd,gm,x,y,r,vx1,vx2,vy1,vy2,f:integer;
ra:real;
function radian(fok:integer):real;
begin
radian:=fok*pi/180;
end;
begin
detectgraph(gd,gm);
initgraph(gd,gm,'c:\bp\bgi');
f:=30;
x:=getmaxx; x:=x div 2;
y:=getmaxy; y:=y div 2;
r:=100;
setlinestyle(3,$0101,3);
circle(x,y,r);
repeat
cleardevice;
setcolor(white);
circle(x,y,r);
for i:=1 to 12 do
begin
setcolor(white);
f:=f+30;
ra:=radian(f);
vx1:=x+trunc(r*cos(ra));
vy1:=y+trunc(r*sin(ra));
line(x,y,vx1,vy1);
end;
delay(60);
for i:=1 to 12 do
begin
f:=f+30;
setcolor(black);
ra:=radian(f);
vx1:=x+trunc(r*cos(ra));
vy1:=y+trunc(r*sin(ra));
line(x,y,vx1,vy1);
end;
f:=f-720;
f:=f+5;
until keypressed;
readln;
end. -
kingabo
őstag
válasz
Szőkecica #2412 üzenetére
"Azt hittem hogy az ami előtt van egy - jel :-)"
De kell valahogy azt a '-' jelet tárolnod. Akkor próbálom visszafelé. Van a "sima" char, ami -128 és 127 közötti értéket vehet fel. Ez binárisan úgy van megvalósítva (nagy vonalakban, részletesebben kettes komplemens szám ábrázolás), hogy van 8db bited, az első bit elmegy az előjel bitnek, a maradék 7 biten pedig lehet tárolni 2^7 értéket vagyis 128-at (a pozitív oldalon azért csak 127-ig megy, mert a 128-adik érték a 0
). Ha a char elé odaírod, hogy unsigned, vagyis unsigned char ertek;, akkor előjel nélküli változót deklarálsz. Ekkor az előjelnek fenntartott bit is felhasználható értékes bitként, vagyis 2^8-an számot tudsz tárolni. Mivel mindkét esetben 8biten vagyis 1 byte-on tárolod az adatokat, ezért a sizeof ugyanazt a méretet fogja megadni. Ugyanez érvényes az pl az int-nél is, csak ott 1byte, helyett ált 4byte-on tárolod az adatokat.
Ha próbálgatni akarsz: deklarálj egy előjeles és egy előjel nélküli char-t. Az előjelesnek adj egy pozitív számot értékül, aztán kasztolással* add értékül a változót az előjel nélkülinek. Ugyanezt próbáld ki negatív számmal is, aztán szerep cserével, 127-nél nagyobb értéket adj az előjel nélkülinek és ezt a változót add értékül az előjelesnek. Ja és természetesen minden értékadás pár után írasd is ki, hogy lásd a különbségeket.
*kasztolás: egy adott típusú változót "átalakítani" másik típusúvá. (kisebb-ről nagyobbra, tehát pl: char-ról int-re megkötés nélkül lehet, de visszafelé nagy valószínűséggel adat vesztés lesz, mivel az int-be jóval nagyobb számok is beleférnek)
Pl: char elojeles = -5;
unsigned char elojelnelkuli = =(unsigned char) elojeles;Bocs ennél érthetőbben nem tudom elmagyarázni.
Ha valami kimaradt, vagy nem érthető, akkor kérdezz nyugodtan.
-
kingabo
őstag
válasz
Szőkecica #2410 üzenetére
Előjeles szám a legfelső biten tárolja az előjelet, de ezzel egy hasznos bitet elvesztünk az előjel nélkülihez képest. Vagyis az előjelnélküli által tárolt legnagyobb max szám az a duplája az előjeles által tárolt max-nak.
Az azt jelenti, hogy az a változó 0 és 255 közötti értékeket vehet fel.
Itt jól megfigyelhető a signed és az unsigned által tárolható min és max értékek: [link] (c#-ról van szó, de ez ne zavarjon meg
-
kingabo
őstag
válasz
Szőkecica #2406 üzenetére
Ki kell jelölni a forráskódot és utána megnyomni a programkód gombot.
A for helyett inkább egy while ciklus kéne: kiírod az adatokat 1 oldalra egy for-ral, bekérsz addig amíg az előre/visszalépés gombját meg nem nyomják, aztán megvizsgálod, hogy merre kell lapozni és ehhez állítod a for alsó felső határát ugrás a while elejére. (pl)
-
kingabo
őstag
Emlékeim szerint leírtam, hogy a fordító hogyan határozza meg a adott elem memória beli címét, meg példákat, ezért nem értem a sizeof-os dologot miért írtad. Ha void* -ként kezelted volna akkor okés lenne, de ezen a szinten nem jön elő.
Csak kiváncsiságból ez *(ar + i ) miért tetszik jobban ennél ar[i]?ui: nem számon kérés akart lenni, az előző hsz-em, csak furcsa volt az a sizeof-os hiba.
(#2404) j0k3r!: ez fel se tűnt.
Teljesen igazad van, bár mintha jobb fordítók sipákolnának ezért.
szerk: se gcc, se g++ nem szólt még -wall-al sem... Akkor csak a c#-é.
-
kingabo
őstag
Naná, hogy elszáll!
Ez mi: *(ar+(i*sizeof(int)))??? A 400-adik elemre fogsz a ciklus végén mutatni! A pointerhez, ha hozzá adsz x-et, akkor a fordító tudja, hogy hány byte-tal kell arrébb mennie a tömbben az x-edik elemhez. Ráadásul írhatnál ar[i]-t is, ami sokkal átláthatóbb. sok értelme volt annó leírnom ezeket, ha el se olvasta senki sem...
Ha meg fordítási időben tudod a tömb méretét miért szórakozol dinamikus memória kezeléssel? -
kingabo
őstag
válasz
Sk8erPeter #2384 üzenetére
Egyet értek!
-
kingabo
őstag
válasz
Pcmagicnet #2377 üzenetére
Pár hsz-el feljebb van minta a file-ból való olvasásra.
A for ciklust akkor szokás használni, ha tudod, hogy hányszor kell lefutnia, mert pl a file első sorában megadod a sorok számát, egyébbként a while. A probléma is ehhez köthető. A ciklus magod össz vissz ennyit tartalmaz: hossz[i] = c; /* rövidített ciklus */, ezért is célszerű (pláne kezdőknek) a ciklus magot új sorba írni. A másik probléma az, hogy nem vizsgálod meg sehol sem a szavak hosszát, hanem egyből bele is teszed a tömbbe.
A ? operátornak nem ez a "megszokott" használati esete, ez átláthatóbb lenne sokkal if-ként.
valtozo = (feltetel) ? ertek_ha_igaz : ertek_ha_hamis
Én így csinálnám: ha a beolvasott szó hossza megfelelő, akkor átmásolnám tömbbe és növelném a tömbbeli szavak számát. mielött neki esnél egy problémának találj ki rá egy programozási nyelvtől független algoritmust, próbáld ki papíron, hogy jó-e. Így kivédhető lett volna az, hogy meg se vizsgáltad a beolvasott szó hosszát. -
kingabo
őstag
válasz
Korcsii #2375 üzenetére
Ok, igazad van.
A szemem az értékadáson akadt meg illetve ezen a mondaton: "csak viszont igy a tomb2 memoriacime mindig felulirodik es az utolso elem tartalma lesz mindig benne" Erre megoldás az strcpy, azt viszont tényleg nem vettem észre, hogy nincs hely foglalva a paramétereknek. -
kingabo
őstag
válasz
Korcsii #2370 üzenetére
"kingabo: strcpy jó, csak épp semmi nem létezik, amit neki adni kéne..."
Hogy hogy nem létezik?Tehát amit beolvas a file-ból az semmi?
(#2372) gergo00: maga a string is egy tömb. Vagyis a 3. dim a beolvasott szövegeket fogja tárolni.
(#2371) gergo00: miért foglalsz le 255 oszlopú tömböt, ha a ciklus végén 6 oszlop után új sort kezdesz?
-
kingabo
őstag
válasz
RexpecT #2361 üzenetére
Leírom megint hátha: Legközelebb programkódként idézd a progid! (a félkövér gomb alatt van a programkód gomb
)
"Viszont azt is meg kellene oldani, hogy a csiga ne tudjon negatív irányba visszacsúszni,de erre még nem jöttem rá, hogy hogyan is kellene."
A korábban idézett megoldásodban két pozitív számot szoroztál össze, ami mindig pozitív lesz. Ha az előző hsz-emben leírt módszert használod, akkor a for ciklus-ba tegyél egy + feltételt, hogy a visszacsúszás pozitív, vagy a ciklusban miután viszacsúszás új értéket kap megvizsgálod, hogy nempozitív-e, ha igen akkor egy break;-kel kilépsz a ciklusból. Illetve a Failure-ös részbe akkor is be kell lépni, ha a visszacsúszás nempozitív.Nincs mit!
-
kingabo
őstag
válasz
Pcmagicnet #2359 üzenetére
De sikerült megoldanod a * kiíratást az a lényeg.
Én meg kétszer is megnéztem mit akarsz mire rájöttem.
A kódtáblát én sem tudom fejből, ezért is linkeltem.
Nincs mit!(#2358) Carpigabi: nagy segítség lett volna ha elforgatod a képeket. Az első képen az 1 egy ciklust jelől, a 2 return-t (szerintem). Ha jól sejtem, valamilyen iterációval számol ki adatokat.
-
kingabo
őstag
válasz
Pcmagicnet #2355 üzenetére
A az 'i2' és a 'k2' azok milyen betűk?
Ehelyett :printf("(%1.1f%s) \n", (a / k), "%" ); ez is írható: printf("(%1.1f\%) \n", (a / k));. Ha egy string-ben egy foglalt operátort akarsz használni, mint itt pl a %-ot, vagy idézőjelet("), akkor szimplán írj elé egy \ jelet.Ha a \ jel kellene az így néz ki: \\Pont ugyanígy a printf("%s","*"); helyett printf("\*");
Illetve ha csak 1 karaktert íratsz ki akkor szebb a %s helyett a %c.
Ha akarsz a progidon rengeteget rövidíteni: ascii.Kicsit bővebben, a ciklusban a c1 a bekért betű ascii kódját fogja tárolni (vagyis ha nem %c-vel íratod ki, hanem %d-vel akkor a betű helyett az ascii kódja kerül a képernyőre). Az ascii kódot pedig szépen fel tudod használni egy tömb indexelésére. Pl a szám tömb indexeléséhez:
if (c1>='0' && c1 <='9')
{
++szam[c1-48]; //a 0 ascci kodja 48, vagyis ezt le kell vonni
}
Hasonlóan rövid lesz a betűk esetén is az 'A' esetén 65-t kell levonni, a 'a' esetén 97-et. Persze a megfelelő méretű tömböket elötte le kell foglalni.(#2356) Pcmagicnet: ránézésre jó, kipróbálod és kiderül.
-
kingabo
őstag
válasz
Pcmagicnet #2353 üzenetére
Ezt írtad :"kinyomtatja a bemenetre adott különböző karakterek előfordulási gyakoriságának hisztogramját" Ebben én nem látom sehol sem, hogy soronként kéne számolni, inkább az egészre.
"van 10db karakterem , ebből 6db 'a', és 4db 'b'. Akkor úgy kellene megjeleníteni, hogy 60% 'a', és 40% 'b' ?"
Szerintem így lenne értelme.
-
kingabo
őstag
válasz
RexpecT #2348 üzenetére
Tedd az u = u * f;-et a ciklus végére és nem kell az if, ill írhatod ezt is helyette u*= f;. Vagy még szebb, ha a for-ban az i++ után teszed.
"Annyi a baj, hogy mindig az első naphoz képest fárad a csiga, az én kódomban meg mindig az előzőnaphoz."
Pont fordítva. A Te progid a feladatban megadott pl-re rossz eredményt fog adni, mivel amikor kiér a csiga, Nálad akkor is visszacsúszik.
C-ben nincs konstans. A legegyszerűbb az, ha deklarálsz még 1 változót, amiben azt tárolod, hogy mennyivel mászik kevesebbet naponta a csiga és ezt vonod le az u-ból.Legközelebb programkódként idézd a progid, mert könnyebb átlátni, ha benne vannak a tabok.
(#2351) Pcmagicnet: ezt már akkor se értettem igazán, hogy mit akartál ezzel leírni. (csak kimaradt a hsz-ből)
Szerintem nem jó, mert ha pl van 10db 'a' betűd és semmi más, akkor (ha jól értem a kódod) 70% lesz az 'a'-k aránya a 100% helyett. -
kingabo
őstag
válasz
Pcmagicnet #2349 üzenetére
Őőő, bocs csak most vettem észre: a hisztogrammban %-os eloszlást szokás mutatni. Tehát a-ból van 5%, e-ből 12%... az összegük meg 100%. VAgyis minden elemre le kell osztani a karakterek számával és megszorozni 100-al. (az osztásnál használj kasztolást, hogy ne int hanem float osztás legyen: int-nél 1/10 = 0 float-nál: 1/10=0.1)
(#2348) RexpecT: majd késöbb átnézem, ha nem jön addig senki sem.
-
kingabo
őstag
válasz
Pcmagicnet #2345 üzenetére
Végülis így is megoldható.
5letek: a sok if helyett lehetne egy switch-ben:
switch (c)
{
case 'a': ++a; break;
...
case 'z': ++z; break;
}A case ágak végére KELL a break.
Esetleg használhatnál tömböket a számokhoz, betükhöz és sokkal rövidebb lenne a kód. -
kingabo
őstag
válasz
RexpecT #2314 üzenetére
Tudom ez Neked nem segít, de az elemeket (érték, multiplicitás) formában szokás tárolni. Ez alapján (nekem!) az tűnik logikusnak, hogy egy indexre beírod az értéket utána a multiplicitását. vagyis: 3 3 1 3, hogy az 5. elem mi a fene lehet nem tudom.
A másik kérdést nem igazán értem, hogy mire akar célozni. A tömb egy elemének maximális értékét a típusa határozza meg, pl 32 bites gépen, int esetén 2^31-1; unsigned int esetén 2^32-1. Hogy erre gondoltak-e nemtom.szerk: elöbb nem vettem észre, hogy int típusú a tömböd. Ezeseben szerintem a max a 2^31-1. A többiek majd vagy megerősítik vagy kijavítanak.
-
kingabo
őstag
Remélem elhiszed, hogy a fenti hsz-t nem 2 sec alatt írtam meg.
Sztem nem a felfogásoddal van a gond, hanem hogy egyetemen b@sznak magyarázni. Nem véletlenül van középsuliban tanár, egyetemen előadószerk: kár, hogy itt a ph!-n nem lehet olyat csinálni mint egyes másik oldalakon, hogy a kódot autómatikusan színezni, esetleg hosszabb soroktól nem zuhanna szét az oldal. (amit tudtam javítottam, van pár komment sor ami nem fért ki egy részét átküldtem új sorba, de oda meg elfelejtettem //-t tenni, 1 még maradt benn)
-
kingabo
őstag
Hát ez "picit hosszú lett. Remélem érthető. Ha kérdésed van kérdezz nyugodtan, ha a többiek valami hibát találnak szóljanak és modikkal javíttatom.
A pointer az egy mutató a memória egy pontjára, vagyis egy memória címet tárol (egy int-et). Minden pointernek meg kell mondani, hogy milyen típusra mutat, hogy a fordító tudja, mi van ott: pl char vs float, mekkora (1byte vs 4byte). A pointert minden esetben használat elött inicializálni kell! (egyszerűbben: értéket kell neki adni), mivel a pointer "kezdeti értéke" nem NULL (==megegyezés szerint nem mutat sehova sem /semmire sem), hanem valamilyen memória szemét, ha ezt a szemetet akarod felhasználni arra, hogy elérd a pointer által mutatot memória helyet elég csúnya dolgok történhetnek ("jobb esetben" az oprendszer nem hagyja, "rosszabb esetben" felhasználhatják a program eltérítésére). Pointer deklarálása: a "mutatandó" érték típusa és a változó neve elé egy *:
int * p;Érték adás:
- NULL:
int *p = NULL;
- Egy másik pointer(1), vagy pl tömb esetén annak egy tetszőleges eleme(2) (részletesen lentebb)
int *pt,*pt1,t2[]={1,2,3,5};
pt = t2; //(2)
pt1 = pt; //(1)
pt = pt1 + 3; //(2) a t2 4. elemére mutat (1+3)- Egy változó címe: a váltózó elé a '&' jelet kell írni
int *p, i = 5;
p = &i;
- Dinamikusan foglalunk le memóriát (ld. késöbb)Pointer értéke vs pointer ÁLTAL MUTATOTT memória hely értéke: ezek keverése miatt lehet igen csúnya dolgokat (==hibákat) művelni. A pointer értéke egy memória cím, ami (jó esetben) egy megfelelő értékre mutat. A pointer által mutatott hely értéke az elején részletezett, a pointer deklarácójakor megadott típusú érték. Ezt elérni a pointer neve elé tett *-al lehet. Pl az előző részből az utolsó példában a 'p' pointer értéke az 'i' változó CÍME a memóriában. Az általa mutatott ÉRTÉK, vagyis a *p értéke 5 (*p = i = 5).
A gondot az okozhatja, hogy "véletlenül" lemarad a 'p' elől a *, így a pointer kap értéket, nem az általa mutatott memória cím. Vagyis ha az 'i'-nek értéket akarunk adni a 'p' pointeren keresztül akkor így kell *p = 6; // ==i;. A következő kód hibás, csak szemléltető ellenpélda:p = 6;, ekkor az 'i' értéke nem változik, a 'p' értéke egy, a programunktól független (nem a program egy változójára, vagy általa dinamikusan lefoglalt memória területre mutat), a 6-os memória címre fog mutatni, ahol biztosan semmi keresni valónk nincs és valószínűleg az oprendszer adatai vannak, vagyis semmi jóra ne számítsunk. (akit érdekel picit részletesebben itt az utolsó 2 sor)Egy dimenziós tömb: avagy a vektor. Egy 'n' elemű vektor, n db a memóriában egymás után lévő érték. (mint linalgból) Szemléletesen pl 3 elemű tömb (az '_' helyére kerülnek az értékek: |_|_|_|
Pl: int t[]={1,2,3,5};
A dolog szépsége az, hogy a 't' is egy pointer lesz, mely a tömb első elemének memóriabeli címére fog mutani.
A tömb elemeinek elérése
- a pointer eltolása, vagyis a pointer értékéhez hozzáadva, vagy levonva belőle. Fontos: nincs semmilyen védelem, hogy a pointer ne tudjon a tömbről "lemenni". Célszerűbb (főleg az elején), inkább a másik megoldást alkalmazni, kisebb a hiba lehetősége.
pl (a fenti t-t felhasználva): int *masodikElem = t+1; // a t 2. elemére mutat (1+1)
int harmadikElemErteke = *(t+2); //t eltolva 2-vel, vagyis a 3
. elem címére mutat és vesszük a címen lévő értéket
- a [] operátort használva. a változó után írva, a zárójelek közé egész számot, vagy egész típusú változót írva.Fontos: a megszokottól eltérően, c-ben az indexelés 0-tól n-1-ig történik! Vagyis pl, a zárójelek közé 0-át írva az általunk megszokott első elemet, n-1-et írva az általunk megszokott utolsó elemet kapjuk. További megjegyzendő tény, hogy nincs semmi védelem az ellen, hogy ne "menjünk le" a tombről. Más szóval ha a c-s indexeléssel nézve a -1-edik vagy az n-edik elemét akarjuk elérni a tömbnek (ami nem létezik), akkor a memóriában a tömb elött és utána lévő értékeket fogjuk elérni, amiről már a legelején megemlítettem, hogy mindent csak jót nem jelent! (Érdekesség: a fordító ezesetben átfordítja az előző változatra. pl t[2]-ből *(t+2) lesz)Dinamikus helyfoglalás: adott a probléma: fordítási időben meg kell adnunk, hogy mekkora lesz a tömbünk mérete. Viszont, ha ez az érték csak futási időben derül ki, mert pl a felhasználó fogja megadni, akkor dinamikusan, azaz futási időben kell a tömböt lefoglalni. Módja 1 dimes tömb esetén:
- 1 deklarálni egy megfelelő típusú pointert, ami majd a tömb első (azaz 0.) elemére fog mutatni
- malloc-kal lefoglani n db, a fenti pointer által mutatott típusnak megfelelő méretű, folytonos memória területet
- a pointer típusára konvertálni a malloc által visszaadott pointert (ha valakit érdekel miért kédezzen rá, de nem igazán ez a szint, szerintem)
pl:int *p, n = 0;
//... n értéket kap
p = (int*) malloc (sor * sizeof (int));
Ha pl int helyett float kell, akkor 3 (azaz három) helyen kell cserélni a típust: a pointer deklarációjánál, a sizeof paraméterében (ez adja meg, hogy mekkora helyet foglal 1 adott típusú változó), illetve a malloc elött.
Esetleg célszerű egy if ágban lekezelni, hogy sikeres volt-e a hely lefoglalása:
if ( (ppt = (int*) malloc (oszlop * sizeof (int)) ) == NULL)
{ printf ("nincshely");
exit (1);
}//if
A fenti kód megpróbál oszlopnyi int-et lefoglalni, ennek első elemre mutató pointerét értékül kapja a ppt. Ezt utána megvizsgálunk, hogy NULL-e (ez az ami nem mutat sehova, vagyis nem sikerült lefoglalni), ha NULL, akkor a hibáról értesítjük a felhasználót és 1-es hibakóddal termináljuk (befejezzük) a program futását.
Memória felszabadítása: az általunk malloc-kal lefoglalt memóriát senki sem fogja felszabadítani, így ha már nincs rá szükségünk, vagy ugyanazt a pointert akarjuk használni egy újabb terület lefoglalásához, akkor elötte kötelező felszabadítani a memória területet, illetve célszerű a pointernek a NULL értéket adni. Ha az elöbbit elfelejtjük a programunk elszívárogtatja a memóriát (memoryleak). A felhasználó ebből azt veszi észre, hogy minnél többször futtatja a programunkat, annál több szabad hely fogy el, amit a program lefutása után nem kap vissza. A második inkább csak biztosági szempontok miatt szükséges, nehogy valaki véletlenül (esetleg rossz akaratúak direkt) a már felszabadított memória területről próbáljanak olvasni, esetleg írni (amivel más adatai írodnak felül) Fontos: NE felejtsük el felszabadítani a lefoglalt területet!
Felszabadítás: free(pointer); //ahol a pointer egy dinamukusan lefoglalt
memória terület kezdőcíme
Tényleg ne maradjon le az a free! Nem lehet elég sokszor hangsúlyozni.Több dimenziós tömbök: az egyszerűség kedvéért csak 2 dimes tömb, de ez alapján könnyen megoldható magasabb dimszámra is. (ugyanazt kell elvégezni még annyiszor, amíg el nem érjük a kívánt dim-et, ami alább következik)
Megvalósítás(elmélet): 2 dimes tömböt c-ben csak úgy tudunk megvalósítani, hogy létrehozunk egy tömböt, amely minden eleme a 2 dimes tömb egy sorára mutat.
Pl: 3x4-es tömb: van egy 3 elemű tömbünk, amelynek minden eleme egy-egy 4 elemű tömb első elemére mutat. Szemléletesen (a mutatást a -> jelőli)
_
|_| --------------> |_|_|_|_| első sor
|_| --------------> |_|_|_|_| második sor
|_| --------------> |_|_|_|_| harmadik sorTömbben lévő értékek elérése: mesélve: először (a fenti 3x4-es pl-nél maradva) a 3 elemű tömbben kell megkeresni a kiválaszotott sort tartalmazó tömb címét. Ezután elugrani erre a címre és a megadott oszlop elemének címét meghatározni.
Konkrét pl-en: próbáljuk meghatározni a fenti tömb (szokásos indexeléssel) a 3. sor 2. oszlopában lévő elemet. Ekkor először meg kell tudnunk a 3. sort tartalmazó vektor címét, vagyis t[2]-t (==t[3-1]). Ezután már csak a 2. oszlop elemét kell venni, vagyis t[2][1] (ld. előbb). Megvalósítás a pointer eltolásos technikával, inkább csak érdekesség képpen: a 3. sor címe: *(t + 2), az így megkapott vektor a 2. elemének értéke: *( *(t + 2) + 1)
2 dimes tömb lefoglalása: a fenti szemléltető ábrán is (remélhetőleg) jól látszik, hogy 4 (azaz négy) darab tömböt kell lefoglalnunk, melyek a memóriában "bárhol" lehetnek (az össz megkötés annyi, hogy a tömb elemei egymás után jönnek):
- 3db 4 elemű tömböt (vagyis lesz 3db pointerünk)
- 1db 3 elemű pointereket tartalmazó tömböt (vagyis ennek típusa pointereket tartalmató tömb, ami viszont szintén egy pointer, vagyis 2db csillag kell deklarációnál)
Pl:
//2 dimes tömb lefoglalása
int **ppt, sor, oszlop, i,j;
//.. értékadás a sor-nak és az oszlop-nak
//első rész lefoglaljuk az oszlop vektort, ami majd tárolja a
sorok címeit
if ( (ppt = (int**) malloc (sor * sizeof (int*)) ) == NULL)
{ printf("nincshely");
exit(1);
}//if
//második rész lefoglaljuk egyesével a sorokat
for (i = 0; i < sor; i++)
if ((ppt[i] = (int*) malloc (oszlop * sizeof (int)) ) == NULL)
{ printf ("nincshely");
exit (1);
}//if
//for//2 dimes tömb bejárása:
for(i=0;i<sor;i++)
{
for(j=0;j<oszlop;j++)
{
ppt[i][j]=j; //itt tetszüleges int állhat; értékadás
printf("%d ",ppt[i][j]); //érték "lekérése"
}//forj
printf("\n");
} //fori//2dimes tömb felszabadítása:
for(i = 0; i < sor; i++)
free(ppt[i]);
free(ppt);Pont úgy ahogy a fenti pl-nél maradva 4 tömböt kell lefoglalni 4-et is kell felszabadítani!
2 dimes tömb megvalósítása 1 dimes tömbbel: a 2 dimes tömb felfogható úgy is, hogy egymás után írjuk a sorait, így egy 1 dimes tömböt kapunk. A korábbi 3x4-es pl, így egy 1x12-es vektorra módosul. Egyetlen "probléma", hogy hogyan lehet kiszámolni a harmadik sor második elemének indexét. A megoldás nagyon egyszerű, csak végig kell gondolni mi történt az eredeti tömbbel (a szokásos indexelést használva): leírtunk egymás után 2 sort (2 * 4 elemet), majd a 3. sort megkezdve leírtunk még 2 elemet, vagyis meg is lett a 3.sor 2. eleme. (persze a többit is leírtuk, de az index kiszámításához nincs rájuk szükség) Vagyis mostmár általánosan: az x-edik sorhoz elötte el kell mennünk x-1 sor elemein, majd az x. sor elemei közül még az y-adikig. Legyen mondjuk minden sorban n db elem, ekkor az x-edik sor y-adik eleme: (x - 1) * n + y. Már csak azt kell végig gondolni, hogy a c féle 0-tól való indexelés változtat-e valamit vagy sem. Vagyis, ha a (innentől már a c-s indexelés) 0. sor 1. (ami nálunk az 1 sor 2. eleme) elemének az indexét kell meghatároznunk, akkor az 0 * n + 1 indexű lesz, ha az 1. sor 3. eleme 1 * n + 3, vagyis általánosan x-edik sor y-adik eleme: x * n + y.
Magasabb szinten, esetleg optimalizáláskor jöhet jól, ugyanis ezzel a módszerrel a tömb tetszőleges eleme 1 lépésben megkapható, míg a korábban leírt változattal csak 2 lépésben
Több dimenziós tömbök: csak vázlatosan: vizuális típusú embereknek: téglapból (XxY) úgy lehet téglát(XxYxZ) készíteni, hogy az (x,y) koordináta "fölé is teszünk 1 vektort(magasság)". Ezesetben ugyanúgy lesz 1 tömbünk, ami a sorokra mutató pointereket fog tartalmazni, viszont a sorok most szintén pointereket fognak tartalmazni, ezek lesznek az (x,y) helyen a fölé tett vektorra mutató pointerek. Vagyis lesz 1db X elemű tömb(int***), amiben lesznek a sorokra mutató pointerek (int**), lesz Xdb Y elemű vektor(int**), amik a magasság vektorokra mutató pointereket (int*) tartalmaznak és lesz X*Ydb Z elemű vektor (int*), ami tartalmazza a magasság adatokat (int).
Másként lehet úgy is nézni, hogy van egy vektorunk, aminek minden elem 1-1 két dimes tömbre mutat. Magasabb dim-ek ezzel a rekurzióval előállíthatók, vagy alkalmazható a fenti dim csökkentő módszer, bonyolultabb képlettel.Láncolt listák: mese: aki érti a 2 dimes tömböknél történteket, annak ez sem jelenthet gondot. A láncolt lista azt az ötletet használja fel, amit a sorok címének meghatározására használtunk fel. Viszont itt azt szeretnénk, hogy tárolhassunk a pointer mellett még adato(ka)t, illetve ne egy sorra mutasson a pointer, hanem egy másik ugyanilyen elemre. Ilyen adatszerkezetet használnak, akkor ha pl nem tudjuk előre, hogy mennyi adat lesz és a felhasználó sem tudja előre. Béna példa: mennyi madarfajt tudsz felsorolni? Ezt a példát tovább víve, a listában tárolandó adat a madárfaj neve, a pointer értéke kezdetben NULL, aztán ha a felhasználó megad egy újabb madárfajt, akkor dinamikusan létrehozunk még egy ilyen lista elemet, és ennek címét állítjuk be az előbb említett pointernek. Célszerű egy külön pointerben eltárolni a lista első elemét (fej/fej elem), és bejáráskor egy másik pointerrel (akt) végig menni rajtuk. (így nem veszik el az eleje)
Megvalósítás: szükséges hozzá tudni mi az a struct! A lista típusa egy struct lesz, ami lehetővé teszi, hogy adatokat is tárolhassunk és mutathassunk egy másik azonos típusú struct-ra.
Saját structunk létrehozása, illetve a fej deklarálása:
typedef struct madarFaj
{
char nev[30];
struct madarFaj *kov; // kov pointer madarFaj típusú
struktúrára
}MADARFAJ; //létrehoztuk a MADARFAJ nevű típust
MADARFAJ *fej, *akt;
char madarFajNeve[30];Új létrehozása és értékadások:
//ciklusban madárfaj bekérése
MADARFAJ p = (MADARFAJ*) malloc (sizeof (MADARFAJ) );
//új listaelem lefoglalása
p->nev = madarFajNeve; //elmentjük a faj nevét
p->kov = NULL; //még nincs következő lista elem, ezért nem mutat sehova sem
akt->kov = p; //hozzá fűzzük a listához az új elemet.Fontos: mivel a lista elemei is dinamikusan lefoglalt memória terültetek, ezért egyesével végig kell menni minden lista elemen és fölszabadítani!
akt = fej;
while (akt != NULL) //amíg van elem a listában
{
MADARFAJ *p = akt; //elmentjük az aktuális listaelem címét
akt = p->kov; //az aktot a következő elemre állítjuk
(felszabadítás után nehéz lenne)
free(p);
} -
kingabo
őstag
válasz
Korcsii #2301 üzenetére
"i, i-1 és/vagy i+1 is létezzen"
Jobban mondva ezek az indexek is a tömbön belül legyenek: legalább 0 és legfeljebb n-1, ha n elemű a tömb."különben szépen elszáll a program..."
Miért szállna el? Nagy valószínűséggel csak memória szemetet hasonlítgatna, ha dinamikusan lett lefoglalva a tömb, ha nem akkor a veremben elötte/utána lévő dolgokat. A c, c++ nem figyeli, hogy tömbön belül indexeltél-e. (pl a pascal-lal/ada-val ellentétben) Esetleg, ha nagyon rossz helyre menne, az oprendszer nem hagyja. c++-ban acces vialation kivételt dob ha jól rémlik, c alatt passz -
kingabo
őstag
A pointerezést holnap megpróbálom összeírni, meg a "mágiás" részt. már ha elfogadod tőlem, nem írja meg elöbb senki sem, nem google-zol rá
"Ja a lényeg kimaradt: a zh példában ha jól emlékszem 8x8-as tömb volt megadva."
Ez esetben a progi elejére:#define MAX_MERET 8 és tömb deklarációnál ciklusoknál MAX_MERET-et írod be. C-ben nincs const, csak így lehet megoldani, a precompiler fogja minden egyes helyen behelyettesíteni a kódban a MAX_MERET helyére a 8-at. Azért célszerű így csinálni, mert ha valaki azt mondja, hogy mégse 8 hanem 10 elemű a tömb, akkor 1 helyen átírod, újrafordítod és kész is vagy, nem kell mindenütt cserélgetni.aztán meg debuggolni ha valahol mégis kimaradt. A keres + csere működhet, ha a kódban nincs pl 128, de ha van, máris nem lehet keres+cserét használni"Az én hibám hogy AxB-t írtam, de ha kukacoskodni akarnék nem kötöttem ki hogy A!=B
"
Viszont azt se írtad, hogy A==B, ezért vettem úgy hogy nem egyenlők.
Nem bme-s vagyok, nem tudom ott hogy oktatják/nem oktatják a programozás. Számomra teljesen logikus volt, hogy AxB-sre ha nem megy a dolog, akkor megszorítom a kisebb dim szerinti négyzetes mátrixra...
Ú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!
- Honor Magic6 Pro - kör közepén számok
- Folyószámla, bankszámla, bankváltás, külföldi kártyahasználat
- Játékra optimalizált chipkínálatot tervez a Microsoftnak az AMD
- Microsoft Excel topic
- Milyen házat vegyek?
- Android alkalmazások - szoftver kibeszélő topik
- Luck Dragon: Asszociációs játék. :)
- Hálózati / IP kamera
- Kevesebb dolgozó kell az Amazonnak, AI veszi át a rutinfeladatokat
- Anime filmek és sorozatok
- További aktív témák...
- TP-Link ER-7212PC Omada 3-in-1 Gigabit VPN Router
- TP-Link EAP Omada Wifi AP-k (225, 245, 615)
- Mars Gaming ML-LCD240 2x ARGB 120mm FDB Fan LCD Display (Alkatrésznek) INGYEN FOXPOST
- CORSAIR K55 RGB PRO XT (Kartámasz nélküli) INGYEN FOXPOST
- Szép! Dell Latitude 7430 ÜTÉSÁLLÓ! Üzleti Profi Ultrabook 14" -60% i5-1245U 16/512 FHD IRIS Xe
- BESZÁMÍTÁS! MSI B450M R5 5600 16GB DDR4 512GB SSD RTX 3060 12GB THERMALTAKE Core V21 Enermax 650W
- Azonnali kézbesítés az év bármely pillanatában
- Eladnád a telefonod? KÉSZPÉNZES OKOSTELEFON FELVÁSÁRLÁS azonnali fizetéssel!
- Csere-Beszámítás! Custom vizes számítógép játékra! I7 12700KF / RTX 3090 / 32GB DDR5 / 1TB SSD
- Csere-Beszámítás! Asus Tuf RTX 5070Ti 16GB GDDR7 Videokártya! Bemutató darab!
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged