- Luck Dragon: Asszociációs játék. :)
- sziku69: Szólánc.
- LordAthis: Ismét egy "Idióta" A.I. Projekt, hogy meglovagolja az aktuális trendeket...
- Geri Bátyó: Agglegénykonyha 1 – rizseshús másképp
- bambano: Bambanő háza tája
- Kalacskepu: Elrontott Radeon X1950 Pro megjavítása
- sziku69: Fűzzük össze a szavakat :)
- GoodSpeed: Bye PET Palack, hello SodaStream
- talmida: Változások
- 25
Új hozzászólás Aktív témák
-
kispx
addikt
válasz
m.zmrzlina #3899 üzenetére
Úgy, ahogy az std-ben szerepel: paraméterként átadod a rendezés feltételét.
Szer.: A "legjobb módszer" általában kontextusfüggő. Egy másik megközelítés: az utolsó paramétert lecseréled egy
bool isAscending
paraméterre. Így az olvasónak egyértelműbb, hogy mire szolgál az utolsó paraméter és nem is kellene külön függvényt írni a rendezés feltételeként. -
m.zmrzlina
senior tag
Hobbiból programozgatok saját örömömre kb középiskolás fokon és egy best practice jellegű tanács kellene.
Van egy függvényem ami cserés rendezést valósít meg:
int cseres(float tomb[],int meret, int trend)
{
float temp=0;
for (int i=0;i<meret-1;i++)
{
for (int j=i+1;j<meret;j++)
{
if(tomb[j]<tomb[i])
{
temp=tomb[i];
tomb[i]=tomb[j];
tomb[j]=temp;
}
}
}
return 0;
}Szeretném alkalmassá tenni arra, hogy növekvő és csökkenő rendezést is meg tudjon valósítani. Erre szolgálna az utolsó argumentum aminek a segítségével a
if(tomb[j]<tomb[i])
sorban lévő relációt kellene megfordítani.Oké, hogy if-fel vagy switch-case-zel ki lehet választani a szükséges sort de valami elegánsabb megoldás kellene.
Mi erre a legjobb módszer?
-
b.kov
senior tag
válasz
dobragab #3896 üzenetére
Mentségemre szóljon, hogy igyekeztem valamiféle párhuzamot vonni az előző kódokkal, így van benne getline, és stringstream.
De természetesen igazad van, felesleges stringekbe olvasgatni.
Másrészt, az olvashatóság szerintem teljesen szubjektív dolog, és megszokás kérdése.
Mobilról viszont elhiszem, hogy gyötrelem olvasni megfelelő indentálás nélkül, kódtól függetlenül. -
dobragab
addikt
Miéhéhéhéhéhéhéért nem veszi észre senki, hogy totál felesleges sztringbe olvasni? A fájlból tessék kapásból az inteket.
int n;
if (!(input >> n))
return shiet; // baj van
// blablablastd::transform-ot pedig azért szeretjük, mert karakterszámra kétszer hosszabb, olvashatóságra háromszor rosszabb, mint a vele ekvivalens for ciklus (range based for-ral)
std::istream_iterator dettó, egyetlen egyszer használtam, input iteratoros overload tesztelésére.
Hogy ne csak fikázás legyen, ha van rá igény, megmutatom szebben, csak most mobilról vagyok.
-
b.kov
senior tag
válasz
#74220800 #3893 üzenetére
Üdv!
Nem egy kezdőszelet, de ha tanulod a nyelvet, előbb-utóbb úgyis el fogod hagyni a tömböket valószínűleg, és helyette stl konténereket, és algoritmusokat fogsz használni.Itt van egy gyors szösszenet C++11-es módszerrel a problémádra:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <iterator>
#include <algorithm>
// Returns a matrix (N x M), storing read data from file
std::vector<std::vector<int32_t>> readData(std::string fileName)
{
// Open file
std::ifstream input;
try
{
input.open(fileName);
}catch(std::ios_base::failure& e)
{
std::cerr << e.what() << std::endl;
return std::vector<std::vector<int32_t>>();
}
std::string line; // For reading line by line
input >> line; // Reading N
std::vector<std::vector<int32_t>> result(std::stoi(line)); // Returnable vector
std::getline(input, line); // Reading M, but do not store
// Write from file to matrix
for(auto& matrixLine : result)
{
std::getline(input, line);
std::istringstream stringOfNumbers(line); // Split line into individual strings
// Perform a transform for storing string chunks as integers in line of matrix
std::transform(std::istream_iterator<std::string>(stringOfNumbers),
std::istream_iterator<std::string>(),
std::back_inserter(matrixLine),
[](const std::string& stringOfNumber)
{
return std::stoi(stringOfNumber);
});
}
return result;
}
int main(int argc, char** argv)
{
std::vector<std::vector<int32_t>> result = readData("input.txt");
// Writing the output into stdout
for(auto line : result)
{
for(auto elem : line)
{
std::cout << elem << ", ";
}
std::cout << std::endl;
}
return 0;
}Természetesen nem teszteltem teljes körűen, csak egyetlen bemenetre, de arra működött.
input.txt:
5 7
2 3 4 -4 3 1 0
-3 2 1023 3 -32 8 9
-2 1 0 22 3 4 93
5 3 8 2 -9 3 -9321
2 3 4 -4 3 1 0 -
kispx
addikt
válasz
#74220800 #3893 üzenetére
0) fájl megnyitás után lekell ellenőrizni, hogy sikeresen megnyitotta-e a fájlt. Ha nem sikerült megnyitni a fájlt a program akkor is tovább fog menni. Ezt meg kell akadályozni.
if (!myfile) {
cerr << "Hiba: ...";
return 0;
}1)
int x[n][ m ];N = 1000 és M = 1000 esetén ennek a mérete: 1000*1000*sizeof(int) lesz. Valószínűleg a 4 byte az int mérete nálad. Így több mint 3,8 MB ennek a változónak a mérete. Túl nagy, nem fér bele a stackbe. Olvasnivaló. Helyezd át a heapre:
int n;
int m;
row>>n;
row>>m;
int **x = new int*[n];
for(int i = 0; i< n ; i++){
x[i] = new int[m];
}Majd ha már nem használod a tömböt a delete[] x; utasítással töröld.
-
#74220800
törölt tag
Tessek. Meg annyi hogy az input fajl elso sora tartalmazza a sorok es oszlopok szamat.
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
string line;
ifstream myfile ("vmi.txt");
getline(myfile, line);
istringstream row(line);
int n;
int m;
row>>n;
row>>m;
int x[n][m];
for(int i = 0; i< n ; i++){
getline(myfile, line);
istringstream row(line);
for(int j = 0; j< m ; j++){
row>>x[i][j];
}
}
/* //kiiratasra:
for(int i = 0; i< n ; i++){
for(int j = 0; j< m ; j++){
cout<<x[i][j]<<" ";
}
cout<<endl;
}
*/
} -
#74220800
törölt tag
Okee, igaz, de az elözöt kivetelesen veletlenül irtam el.
Nademost emelejük a tetet. Igazabol nekem egy txt adatait kellenne beolvasnom soronkent es berakni egy matrixba. Ezzel meg is volnek (ket for ciklussal), belathato mennyisegü adatra müködik a program (teszteltem pl 5x5 es jo!!).
De lenne egy 1000*1000 adatot tartalmazo bemeneti txt-m de azt mar nem eszi meg.
Codeblocks azt irja main.exe has stopped working. Beleneztem a fajlba, es lattam hogy nehol a sorok meg vannak törve(akar ugy hogy a sor vegen egy space van, vagy akar egy negativ jel, vagy a szamnak csak az egyik jegye) es szerintem ezt nem tudja kezelni a progi(tehat a sortöres (adatmennyiseg miatt? vagy txt-nel maximalva van az egy sorban levo karakterek szama) ellenere folytatodik a sor). Van valami ötleted mivel lehetne müködesre birni?köszi
-
-
#74220800
törölt tag
Hi!
Most tanulgatom a c++, adodott egy problema. Standard bemenetröl olvasok be egy sort amelynek spacevel elkülönitett szamait(pl: "-23 2 785" )bele akarom tenni a tömbe. Na most ha azt egy sstream segitsegevel egy egyszerü int valtozoban tarolom szepen megkapom a sor uccso szamat. Ha a tömb uccso elemet hivon meg miert nem azt a szamot kapom meg?
Itt az alabbi kodban a a[2] miert nem ugyanaz mint a b?
#include <iostream>
#include <stdlib.h>
#include <sstream>
using namespace std;
int main()
{
string s;
getline(cin, s);
istringstream row(s);
int a[3];
int b;
for(int i = 0; i< 3 ; i++){
row>>b>>a[i];
}
cout<<endl<<a[2]<<endl;
cout<<b;
} -
choco01
addikt
Hali.
TFeri alapok mellett tudtok még ajánlani valami hasonlóan szájbarágós jól bevált irodalmat C++-ra?
-
Domonkos
addikt
válasz
_herosz #3881 üzenetére
Egyetlen c++ szabvanyban sincs VLA - fuggetlenul attol, hogy a forditod megeszi-e vagy egyaltalan szol-e ra valamit. Szerencsere vannak
sokkal jobbszabvanyabb eszkozok is az ilyen feladatra, mint pl azstd::vector
es tarsai.
Javaslom, hogy fordits-pedantic
kapcsolot hasznalva. -
_herosz
újonc
sziasztok!
1kis értelmezésre lenne szükségem, ugyanis sehogy se értem mi értelme van a dinamikus helyfoglalásnak, ha ugyanugy meg kell adnom a tömb nagyságát. Ennyi erővel a stacken is lefoglalhatom:int n ;
cout << "kerem a tomb nagysagat:"
cin>>n;
int a[n]; -
cadtamas
tag
Köszönöm mindenkinek a segítséget.
-
válasz
cadtamas #3877 üzenetére
Ha Pythont ismered, ott minden paraméter referenciaként adódik át, sőt, ott gyakorlatilag az összes változó referencia, ami szerintem elég vicces működést tud produkálni meg rengeteg fejtörést azoknak, akik nem igazán értik, hogy mi a referencia.
Egyébként visszatérve azért, hogy miért jobb a referenciaként átadott paramétert módosítani, mint a visszatérési értéket használni: mert sokkal hatékonyabb. Ha tisztán érték szerint átadott, majd visszatérési értékkel átírt objektumnál háromszor kell a komplett objektumot (ami csatolt részeivel együtt akármekkora lehet, akár gigabyte-os méretű is!) háromszor kell mindenestül átmásolni (egyszer az érték szerinti átadásnál, másodszor akkor, amikor ezt átmásoljuk visszatérési értéknek, harmadszor meg akkor, amikor a visszatérési értéket beírjuk a régi helyére), referenciakénti átadáskor meg nullaszor. Egyébként ezért van az, hogy C++-ban (a primitív típusokat (int, double, boolean, ilyenek, amik beleférnek egy regiszterbe) leszámítva) minden paramétert referenciaként szokás átadni, legfeljebb kap egy constot, hogy tudjuk, hogy ahhoz nem fog hozzápiszkálni a függvény.
-
cadtamas
tag
válasz
dobragab #3876 üzenetére
Hazudnék, ha azt mondanám, hogy minden világos, de remélem ahogy haladok a tananyaggal majd megvilágosodok. Eddig nem volt bajom a könyvvel, de azt észrevettem, hogy nem bajlódik az alapokkal és bizonyos tudásszintet természetesnek vesz.
Kezdőknek semmiképp sem ajánlanám.
Egy éve tanulom a pythont, csak az unreal engine miatt kénytelen vagyok megtanulni a c++ alapjait is. Nem volt rossz ötlet azzal kezdeni, egyes dolgokat jóval nagyvonalúbban kezel. -
dobragab
addikt
válasz
cadtamas #3875 üzenetére
Némi terminológia, hogy eligazodj azon a könyvön túl is:
mutató == pointer
hivatkozás == referenciaHa a függvény feladata egy változó módosítása, akkor miért nem adjuk meg a függvény visszatérési értékének ezt az értéket és írjuk felül az eredeti változót?
Mert nem mindig lehet megtenni, vagy logikailag nincs értelme, vagy 2 értéket kéne visszaadnia, amit nem lehet, stb.
-
cadtamas
tag
válasz
dabadab #3874 üzenetére
Nagyon köszönöm a válaszod.
A fő felhasználási terület a függvények paramétereinél van. A paramétereket alapvetően átadhatjuk értékként vagy hivatkozásként: ha értékként adjuk át, akkor ha a függvényben bizergáljuk, az nincs kihatással az eredeti változóra - ha hivatkozásként, akkor meg igen.
Ha a függvény feladata egy változó módosítása, akkor miért nem adjuk meg a függvény visszatérési értékének ezt az értéket és írjuk felül az eredeti változót?
A másik felhasználás az, amikor new-val hozunk létra objektumokat, hogy az élettartamuk független legyen annak a függvénynek az élettartamától, amelyik létrehozza őket (ugye a helyi változók csak addig élnek, amíg a függvény le nem fut - ha new-val hozol létre valamit, az meg addig, amíg rá nem küldesz egy delete-et).
Erre tudnál adni valami pédát, mert nem értem miért lenne szükségem bármire egy függvényből annak lefutása után. (kivéve persze az eredményt) Vagy ha szükségem van rá, akkor miért nem a programtörzsben deklarálom?
-
válasz
cadtamas #3873 üzenetére
(Jézusom, ez a példaprogram... az már önmagában elég ahhoz, hogy azt javasoljam, hogy inkább tanulj valami másból)
Szóval: a mutató egy olyan változó, ami egy másik változó vagy objektum helyére (címére) mutat a memóriában. Ez eddig megvan? Itt a két fő koncepciók az, hogy van olyan, hogy a memóriacím (a számítógépben a byte-ok meg vannak számozva nullától kezdve nagyonsokig és ezzel a számmal lehet rájuk hivatkozni) és hogy minden változó meg objektum valójában egy rakat byte-ként létezik a számítógépben.
A hivatkozás az gyakorlatilag egy mutató, csak a szintaxisban van különbség: ott feltételezik, hogy minket elsősorban a mutatott dolog érdékel, nem maga a memóriacím és így nem várja el a fordító hogy csillaggal meg nyillal bohóckodjunk, megspórolva némi gépelést meg olvashatóbbá téve a kódot.
Miért jó, hogy vannak ilyenek?
A fő felhasználási terület a függvények paramétereinél van. A paramétereket alapvetően átadhatjuk értékként vagy hivatkozásként: ha értékként adjuk át, akkor ha a függvényben bizergáljuk, az nincs kihatással az eredeti változóra - ha hivatkozásként, akkor meg igen.
A másik felhasználás az, amikor new-val hozunk létra objektumokat, hogy az élettartamuk független legyen annak a függvénynek az élettartamától, amelyik létrehozza őket (ugye a helyi változók csak addig élnek, amíg a függvény le nem fut - ha new-val hozol létre valamit, az meg addig, amíg rá nem küldesz egy delete-et).
-
cadtamas
tag
Sziasztok, pár hete tanulom a c++ nyelvet és a Tanuljunk meg programozni c++ nyelven 24 óra alatt c. könyvet használom. Eljutottam a mutatók/hivatkozások témakörhöz és egy kissé megakadtam.
Valójában teljes a káosz.
Azt nem fejti ki rendesen, hogy miért kellenek a mutatók/hivatkozások, de azt igen, hogy miket ne csináljak mert ha törölt hivatkozásra mutat a mutató akkor túlcsordul a memória és az internet letörli önmagát, aztán összecsomagol és visszaköltözik az anyjához.Itt van ez a példaprogram:
//12.5 Lista
//A memóriszivárgás javítása
#include <iostream>
class SimpleCat //létrehozom az osztályt, minden frankó
{
public:
SimpleCat(int age, int weight);
~SimpleCat() {}
int GetAge() { return itsAge; }
int GetWeight() { return itsWeight; }
private:
int itsAge;
int itsWeight;
};
SimpleCat::SimpleCat(int age, int weight) : //deklaráljuk a simplecat osztályt
itsAge(age), itsWeight(weight) {} //Gondolom itt meg azonnal meghívjuk a függvényeit, bár ilyet még korábban nem láttam
SimpleCat & TheFunction(); //Ez egy funkció, de lövésem sincs, miért így kell megadni és innentől elveszítem a fonalat
int main()
{
SimpleCat & rCat = TheFunction();
int age = rCat.GetAge();
std::cout << "rCat is " << age << " years old!\n";
std::cout << "&rCat: " << &rCat << std::endl;
SimpleCat*pCat = &rCat;
delete pCat;
return 0;
}
SimpleCat & TheFunction()
{
SimpleCat * pFrisky = new SimpleCat(5, 9);
std::cout << "pFrisky: " << pFrisky << std::endl;
return *pFrisky;
}Segítenétek nekem a helyére rakni a dolgokat?
De valami emberi nyelven megfogalmazva.
Miért kellenek a mutatók és a hivatkozások és mire használjuk őket? -
leviske
veterán
Sziasztok!
Ezer bocs a zavarásért, de belecsöppentem tanulóként egy olyan projektbe, ahol boost-ot is kell használni, többek közt a Python miatt. Bár a boost beállításokat már elvégeztem, de a vc141-es fordítóval, ami mint kiderült, nem volt okos húzás részemről, mert a projekt vc120-as és nem akarnék a többi résztvevőnek bekavarni. Most utólag felraktam a MSVC2015-öt a kompatibilitási cuccaival, így már a 2017-ben is tudok mit kezdeni a vc120-es verzióval. Viszont a boost-ból nincsenek vc120-as .lib fájlok (LINK : fatal error LNK1104: cannot open file 'libboost_regex-vc120-mt-gd-1_65_1.lib'), csak vc141-esek. A leírásában nem látok túl sok segítséget ahhoz, hogy hogy tudnám utólag létrehozatni vele a vc120-as fájlokat is.
Ebben tudna valaki segíteni?
-
MATEO6600
őstag
Sziasztok!
Ide is beírom a kér(d)ésemet:
Adott egy komoly és alapos C# tudás, viszont C++-ból teljesen 0-án állok, és szeretném megtanulni a nyelvet.
Tudnátok nekem valami javasolt könyvet / weboldalt / pluralsight tutorialt adni, aminek érdemes nekiállnom?
Rengeteg oktató anyag van, de általában 0 programozási tudásról indítanak, viszont nekem itt van a C# tudásom. -
dobragab
addikt
válasz
jattila48 #3857 üzenetére
Végül nem is használtam többszörös öröklést emiatt, megoldottam kompzícióval. Így azonban az ősosztály pointert kell static_cast-olnom egy típusmezőtől függően egyik illetve másik leszármazott osztály pointerré, és ezzel elérni a kompozícióval mindkét osztályban létrehozott tagobjektumot, holott ez lehetett volna ős is.
Jol ertem, hogy a dynamic_cast runtime overhead-je helyett felvettel egy tipusmezot?
Mintha annak nem lenne overheadje, vagy negativ hatasa a karbantarthatosagra.
Ha az interface konstruktora trivialis, akkor a leszarmazott konstruktoraval nem kell foglalkozni, meg virtualis oroklesnel sem. Megoldja a fordito.
a kompozícióval mindkét osztályban létrehozott tagobjektumot
Ezzel ujrakrealtad a diamond-problema alapproblemajat, hogy ketszer szerepel a diamond "csucsa" a memoriakepben (nalad is ketto van), amit a virtual inheritance old meg. Szerintem sokkal egyszerubb lenne inkabb a diamondbol kihagyni a virtual kulcsszavakat, azt' jonapot. Igen, az interface ketszer lesz benne, de abban csak 1-1 vptr van. [link]
Szerintem sokkal kifizetodobb helyenkent leirni azt a dupla static_cast-ot (ahol mindegy, hogy A-ra vagy B-re cast-olod kozepen), mint tipusmezot hasznalni.
Egyebkent javaban sem fenekig tejfel az interface. Ott kotelezo az implementalt fuggvenyeket mind kiirni, akkor is, ha absztrakt. Azaz a linkelt peldaban A-ban es B-ben is kb. meg kellene ismetelni f deklaraciojat. Ja, es a javas interfesznek is van tisztesseges overheadje.
-
jattila48
aktív tag
C++ -ban sajnos nincs (java értelemben vett) interface, csak valami hasonló az absztrakt class-okkal. Ez azonban nem ugyanaz (egyébként nem ismerem a Javát), mert az ilyen osztályok mérete nem 0. Ebből adódik a jól ismert diamond probléma, annak minden nyűgjével. Ilyen pl., hogy a virtuális ősosztály pointert nem lehet static_cast-olni leszármazott osztályra (csak dynamic_cast => runtime overhead), és a legleszármazottabb osztály konstruktorából kell hívni a virtuális ősosztály konstruktorát. Ez akkor is így van, ha a virtuális ősosztály összes tfv.-e pure virtual és nincs adattagja (interface). Nekem most nagyon jól jött volna, ha java-szerű interface lenne a C++-ban, és nem kell megküzdeni (fölöslegesen) a diamond problémával. Végül nem is használtam többszörös öröklést emiatt, megoldottam kompzícióval. Így azonban az ősosztály pointert kell static_cast-olnom egy típusmezőtől függően egyik illetve másik leszármazott osztály pointerré, és ezzel elérni a kompozícióval mindkét osztályban létrehozott tagobjektumot, holott ez lehetett volna ős is.
Az MSVC-nek van ugyan _interface kulcsszava, de az nem különbözik attól, mintha tiszta absztrakt osztály írnék. Van-e olyan C++ fordító, ami valami java féle interface-t támogat? Nincs is tervbe véve hogy későbbi szabványok támogatni fogják? -
CPT.Pirk
Jómunkásember
válasz
dabadab #3855 üzenetére
QRect, oké.
Arra gondoltam, hogy class-on kívüli változókat töltök fel a MainWindow létrejövetelénél és azokat simán átadom másik fájlnak, de rá kellett jönnöm, hogy a gomb előbb jön létre, mint a MainWindow amin rajta van így ez nem járható.
Végül aztán a slotokkal sikerült megcsinálni. Betettem a MainWindowhoz egy slotot a két QRect elküldésére, a constructorban megcsinálom a qrectec feltöltését és a connectet a vevő oldallal, majd emittálok.
...
connect(this, &MainWindow::SendDimensions, ui->movedPushButton, &mousemovedbutton::GetDimensions);
LabelDimensions.setX(ui->label_2->width());
LabelDimensions.setY(ui->label_2->height());
PushBtnDimensions.setX(ui->movedPushButton->width());
PushBtnDimensions.setY(ui->movedPushButton->height());
emit SendDimensions(LabelDimensions, PushBtnDimensions);Így most faszán odaérnek a paraméterek a vevő oldalra és tudok velük dolgozni.
-
válasz
CPT.Pirk #3854 üzenetére
Nyilván szükséged van a konkrét példányra ahhoz, hogy meg tudd hívni annak egy függvényét és értelmes adatot kapjál vissza - ez C-ben is pont ugyanígy van, ha egy x változód struct_a típussal, akkor annak nem tudod úgy lekérdezni a tagjait, hogy csinálsz egy struct_a típusú y változót és azt állsz neki olvasni
Mivel a te MainWindow objektumodot pointerét egy random widgetből megkapni nem igazán triviális (és ez jól van így), ezért inkább javasolnám a slotos-signalos megközelítést, az a korrekt (és ennek jelen esetben a C++-hoz semmi köze, ha C-ben lenne megírva a QT, akkor is ez lenne a helyes út).
Ja, az, hogy egy téglalapról szóló infót a QPoint típusú változóban adsz át, azért nem egy nagydíjas ötlet
, ott van a QRect, használd inkább azt, a geometry() úgyis azt adja vissza.
-
CPT.Pirk
Jómunkásember
Sima C-s és Pascalos fejjel van egy kérdésem.
QT creatorban a MainWindow osztálynak van egy ilyen része:
public:
explicit MainWindow(QWidget *parent = 0);
QPoint GetLabel2WidthHeight();
QPoint GetPushButtonDimensions();amikkel szeretném máshonnan lekérdezni a mainformon lévő két widget xy paraméterét.
Egy másik CPP fájlból szeretném az előző paramétereket átemelni, és ott dolgozni velük:
...
int Border_x, Border_y, PB_Width, PB_Heigt;
mousemovedbutton::mousemovedbutton(QWidget *parent) : QPushButton(parent)
{
MainWindow * mw = new MainWindow();
QPoint Dimensions;
Dimensions = mw->GetLabel2WidthHeight();
Border_x = Dimensions.x();
Border_y = Dimensions.y();
Dimensions = mw->GetPushButtonDimensions();
PB_Width = Dimensions.x();
PB_Heigt = Dimensions.y();
qDebug() << "GetDimensions " << QString("bx: %1 by: %2 | w: %3 h: %4").arg(Border_x).arg(Border_y).arg(PB_Width).arg(PB_Heigt);
}
...Ez így nem ad hibát fordításkor, de a program meghal, valszeg mert nem kellene még egy példányt létrehoznom a MainWIndow-ból...
C-ben set és get függvényeket írogattam ilyesmire, úgy simán ment a dolgok átadása fájlok között. Pascalban sem volt bonyolultabb. Itt c++ alatt egyáltalán megoldható ez amit szeretnék, vagy ezt is valahogy slotokkal és szignálokkal kellene csinálni?
Röviden összefoglalva egy cimkéből csinált keretben van egy gomb, amit az egérmutató közeledésére szeretnék arrébb mozgatni, de ehhez kellene a keret és a gomb xy paraméteri. Az egérmutató mozgására adott szignál meg slotos részek már megvannak.
-
dobragab
addikt
-
G.A.
aktív tag
Üdv!
A következő problémám akadt a Visual Studio 2015-ben C++ alatt.
UDP Socketeket (küldés/fogadás) szeretnék létrehozni, amik külön szálon futnának.
A gondom ott kezdődik, hogy ha a include-olom a "thread" könyvtárat, de még nem használom a funkcióit, akkor is hibák keletkeznek a működő socket funkciókkal:
Thread könyvtárral együtt:
bind(socketC, (SOCKADDR*)&myAddress, sizeof(myAddress));
nincs complie error, bind nem működik (nem jön létre)iResult = bind(socketC, (SOCKADDR*)&myAddress, sizeof(myAddress));
error: no suitable conversion conversion from ... existsThread könyvtár nélkül mindkét megoldásnál nincs error és működik is a bind().
Mi lehet itt a baj?
-
dobragab
addikt
válasz
dabadab #3844 üzenetére
Mondjuk, kicsit általánosabban is meg lehetne fogalmazni, hogy tuti ne lődd tökön magad:
- Inicializáló listán ne hívj tagfüggvényt
- Inicializáló listán ne add ki a this-t vagy a *this-t
- Ha az osztály polimorfikus (van virtuális függvénye), ugyanezek a kitételek érvényesek a törzsre is.Utóbbi esetben a nem virtuális függvény hívása is veszélyes, figyelembe véve a template method pattern-t és ezt.
-
Hiftu
senior tag
Ez a téma elég messzire vezet. Szerintem két különálló részként kellene tekinteni egy kódra:
1, objektumok létrehozásra és kapcssolatok felépítése
2, business logika megvalósítása az objektumokkal.Ha lehetséges, akkor egy objektum kapja meg paraméterként a vele együttműködő objektumokat.
(nem minden esetben megoldható.) Ezáltal kisebb lesz a függőség és flexibilisebb a kód.
A létrehozás közben pedig kisebb lesz az esély a katasztrófákra. -
-
dobragab
addikt
válasz
EQMontoya #3841 üzenetére
Megnéztem, se gcc 7.1.1, se clang 4.0, se clang-tidy nem találja meg. Utóbbiba mondjuk lehetne egy ilyen check-et építeni, majd rá is kérdezek, mert tényleg oltári szopás lehet egy ilyenből.
Valami clang sanitizer tuti megtalálná, de ez elvileg megfogható statikus ellenőrzéssel is.
Talán a legnagyobb probléma itt az, hogy a ctor valami olyat próbál csinálni, ami nem teljesen feladata
Az a vicc, hogy semmi olyan nem történik, mert a count_a melléktermékeként áll elő a prod kódban is a b.
-
EQMontoya
veterán
Én is azon gondolkodtam este (némi privát üzenetetek váltását követően), hogy hogyan lehetne ezt kivédeni. Mert ha ctorbab b@ssza el az ember az init sorrendet, arra ugye van warning, egyértelmű user error.
Ezt viszont már nem veszi észre a fordító, mert az a-t inicializálni próbáló fv. dependál b-n.
Tehát warning nem lesz, viszont irgalmatlan szívás igen.Ugye először lehetne még jönni azzal, hogy ctorból nem hívogatunk tagfüggvenyeket, de nem virtuálisakat nyugodtan lehet.
Talán a legnagyobb probléma itt az, hogy a ctor valami olyat próbál csinálni, ami nem teljesen feladata, de ez megint megfoghatatlan.
-
dobragab
addikt
Így van.
Amikor a count_a hívódik, a b adattag még nincs inicializálva, így nettó undefined behaviour.
Nálam természetesen a saját allokátortól valamiért (debug mód, vagy OS security, vagy direkt kiszúrásból) kinullázott memóriaterületet kaptam, ami véletlenül az adott implementációban az üres vektor memóriaképével egyezett (count == 0, capacity == 0, data == nullptr)... Ezen frankón lefutott a push_back. Otthon egyébként debug módban crash, release-ben fut.
Az első megoldást választottam, mert a prod kódban ott nem egy sima int van, hanem egy bonyolult, connection állapotot kezelő cucc, rengeteg adattaggal, az egyik konstruktorparaméterére hívtam egy count_a-szerűséget. És még a vektor is csak metaadat, így a tagfüggvényben csak lestem, miért romlik el minden, és a hitem szerint jól inicializált, sehol máshol nem módosított vektorra csak egy nap debugprintf után gondoltam.
Majd beletúrok az allokációba, hogy debug módban írja felül random adattal a memóriaterületet.
Amúgy meg szerintem kéne kérnünk egy SPOILER taget a topikba
-
Hiftu
senior tag
Közben kipróbáltam. Segmentation fault-ot írt ki.
A b.push_back(i)-re hasalt el.
Akkor ötletem nem volt rossz, csak az eredménye: az a inicializálásakor még nincsen b vectorod.Megoldás #1:
Felcseréled az a és b változó sorrendjét.
Ez egy elég gyenge megoldás, több változó esetén szívhatsz vele.Megoldás #2:
Az összefüggő adatok inicializálását kiveszed az inicializálási listából (de szarul hangzik magyarul)
és berakod a constructor függvénytörzsébe. -
Hiftu
senior tag
Gyanítom, hogy 0-t kapsz a b vector méretére, különben nem írtad volna. Ha jól gyanítom, akkor az adattagok létrehozása a deklarálás sorrendjében történik. Az elképzelés em az, hogy "a" inicializálása után meghívodik a vector default constructora, ami üresre állítja azt.
-
dobragab
addikt
Napi mitírki. Szó szerint, hétfő délután óta ezt debuggoltam.
#include <iostream>
#include <vector>
class X
{
int a;
std::vector<int> b;
int count_a(int i)
{
b.push_back(i);
return i*i;
}
public:
X(int i)
: a{count_a(i)}
{ }
void f() const
{
std::cout << b.size() << std::endl;
}
};
int main()
{
X x{4};
x.f();
return 0;
} -
dobragab
addikt
Napi Májkroszoft. Alapszituáció: az
strerror
nem thread safe, lehet, hogy valami globális memóriaterületen van a buffer, amit az strerror ír (!), és két threadről hívva minden szétrohad. Már ez is Microsoft-specifikus, mert *IX-eken az strerror semmit nem ír, csak kikeresi a sztringek közül az aktuálisat.Erre a C11 szabvány megoldása:
errno_t strerror_s(char *buf, rsize_t bufsz, errno_t errnum);
size_t strerrorlen_s(errno_t errnum);Tök frankó, lekéred a hosszát előre, allokálsz valamit neki, majd beleíratod.
Ehhez képest a Microsoft (néhány wide verzió mellett) ezt nyújtja:
errno_t strerror_s(char *buffer, size_t numberOfElements, int errnum);
errno_t _strerror_s(char *buffer, size_t numberOfElements, const char *strErrMsg);Jól látható, hogy az
strerrorlen_s
függvényt sikeresen kifelejetették, és használhatatlan az egész. Azstrerror_s
nem tudja visszaadni sehogy a méretet, ha nem fér bele.És akkor a dokumentáció, ami miatt a maradék hajamat is kitépem:
If strErrMsg is NULL, _strerror_s returns a string in buffer containing the system error message for the last library call that produced an error. The error-message string is terminated by the newline character ('\n'). If strErrMsg is not equal to NULL, then _strerror_s returns a string in buffer containing (in order) your string message, a colon, a space, the system error message for the last library call producing an error, and a newline character. Your string message can be, at most, 94 characters long.
- Miért zárja le sorvéggel?
- Miért pont Unixos sorvéggel?
- Hogy sikerült kitalálni, hogy pont 94 karakteres lehet a saját üzenet? Nem annyi lenne a dolga, hogy ráhív egy strlcpy-t? Miért kell felesleges limitációt bevezetni ide is?These functions validate their parameters. If buffer is NULL or if the size parameter is 0, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue, the functions return EINVAL and set errno to EINVAL.
Ha a buffer csak simán kicsi, akkor is EINVAL-lal tér vissza, és ez sehol nincs ledokumentálva. És hogy miért pont EINVAL, az is rejtély, amikor ott van pont erre, szabványosítva az E2BIG és az ENAMETOOLONG.
_strerror_s, _wcserror_s, and __wcserror_s are not part of the ANSI definition but are instead Microsoft extensions to it. Do not use them where portability is desired; for ANSI compatibility, use strerror_s instead.
Mivan? ANSI kompatibilitás? Az strerror_s sose volt ANSI szabvány része, de az ISO C11-é igen. És - ahogy a Macskafogóban elhangzott - a műsort itt tetszették felejteni. Az a függvény, ami ezt a foshányást használhatóvá teszi, nincs implementálva.
template <size_t size>
errno_t strerror_s( char (&buffer)[size], int errnum); // C++ onlyIn C++, using these functions is simplified by template overloads; the overloads can infer buffer length automatically, eliminating the need to specify a size argument. For more information, see Secure Template Overloads.
Miééééhéhéhéhéért? Ha már C++, lehetne mondjuk std::string-gel visszatérő, ami az egész buffer nyavalyát feleslegessé teszi, az APIt pedig használhatóvá. De nem, a C++ template magic-et arra kell használni, hogy a hetvenes évekbeli borzalmasan szar API fényesebb legyen.
Szóval nekem így sikerült használhatóbbá tennem. Tudtok ajánlani valami jobbat esetleg?
std::string const& stdc_error::strerror(int no)
{
static thread_local std::string result(BUFSIZ, '\0');
// Let's hope strerror_s can't fail unless buffer is too small.
// Anyway, if buffer is small, it returns EINVAL (?)
int err;
while ((err = strerror_s(&result[0], result.size(), no)) == EINVAL)
result.resize(result.size() * 2);
if (err != EINVAL) // should not happen
result = "An unknown error occured in strerror_s.";
// Removing trailing '\n'. Assuming that if it contains a newline,
// it won't be in the middle of the string.
// Looking at this wonderful API, this assumption is risky.
auto pos = result.find_last_of('\n');
if (pos != std::string::npos)
result[pos] = '\0';
return result;
} -
G.A.
aktív tag
válasz
mgoogyi #3830 üzenetére
(Az első gondolatom vmi rejtett karakter a kódban, amitől valamiért meghülyül a fordídtó.)
Köszönöm szépen! Igazad van!
A kód pdf-ből történt másolása során az "enter" kód nem lett úgymond konstans. (Néhol \n, máshol \r\n)
Bezártam a VS-t, majd újranyitottam és egyből jelezte is a hibát és ki is javította.Köszönöm szépen még egyszer a segítséget!
-
mgoogyi
senior tag
Ha csinálsz szándékosan egy szintaktikai hibát, akkor minden sorra igaz ez a sorszám tévedés?
Hátha ki lehetne találni, hogy melyik sortól hülyül meg a sorszám.
(Az első gondolatom vmi rejtett karakter a kódban, amitől valamiért meghülyül a fordídtó.)Meglehetősen ezoterikus hibának látszik.
-
G.A.
aktív tag
Üdv!
A Visual Studio 2015-el (c++-ban irt kód) akadt egy kis gondom...
A kódot egy chip (FT2232H) "Application Note"-jából másoltam, ill. módosítom saját feladatomhoz.
A képen található a hiba amivel nem tudok mit kezdeni.Fordításkor azt a hibát kapom, hogy: 'byOutputBuffer': undeclared identifier
A 340, ill. a 342-es sorban is...
1. - az adott változó nem s abban a sorokban található
2. - a funkció elején ott virít a változó (létezik) (lentebbi két képen látható)Érdekesség:
Egy másik változóval is volt(van) ilyen problémám. Annak a "megoldása" az volt, hogy kikommenteltem //-el a változót, majd 2 sorral lentebb beillesztettem és így már megy is... (de hogy, mitől...???)
Képekben:
Hibás kód:
Működő kód:Ez valami VS'15 bug lenne?
-
jattila48
aktív tag
válasz
nonsen5e #3826 üzenetére
.hpp-be lehetőleg ne tegyél fv. vagy globális változó defíníciót (csak deklarációt), mert ezeket beinklúdolod a különböző fordítási egységekbe, amik le is fordulnak, de mindegyik object kódban megjelenik a beinklúdolt fv. kódja, amit a linker többszörös definíciónak vesz. Pl:
//akarmi.hpp
#ifndef _AKARMI_HPP_
#define _AKARMI_HPP_
int f(int x){
return x;
}
#endif
//akarmi1.cpp
#include "akarmi.hpp"
#include <stdio.h>
int g(int x);
void main(void){
printf("%d",f(5));
printf("%d",g(6));
}
//akarmi2.cpp
#include "akarmi.hpp"
int g(int x){
return f(x);
}Itt az akarmi1.cpp-be, és az akarmi 2.cpp-be is bekerül az f fv. kódja, linkeléskor pedig dupla definíció miatt hibát ad a linker. Helyesen az akarmi.hpp-be csak deklaráció kerül (fv. prototype)
//akarmi.hpp
#ifndef _AKARMI_HPP_
#define _AKARMI_HPP_
int f(int x);
#endifés valamelyik .cpp állományba (akár új akarmi3.cpp-be) írod az f fv. definícióját.
Remélem tudtam segíteni. -
mgoogyi
senior tag
válasz
nonsen5e #3826 üzenetére
Tudsz feltenni netre egy problémás minimál csomagot?
A leírásodból halvány fingom sincs, hogy mi lehet gond + nem tudok róla, hogy a .h és .hpp fileok között bármi különbség kéne legyen a kiterjesztésen kívül."rögtön különböző hibákra hivatkozik"
Konkrétan?"operator<< multiple deklarációra hivatkozik"
nem include-olod duplán ugyanazt véletlenül? (akár közvetetten is) -
nonsen5e
veterán
Üdv!
Milyen extra dolgokat érdemes tudni a .hpp header file-okról?
C-ben semmi gondom nem akadt lekezelni őket, minden további nélkül megtömtem a .h állományokat a függvénydeklarációkkal, majd a .c fileokat az implementációkkal.Most egy projektben alapból megírtam mindent a .hpp-be, szedném szét, hogy szépen strukturált legyen, de most amint kiszedem akár egy függvény törzsét is, rögtön különböző hibákra hivatkozik.
A .hpp-ben levő operator<< multiple deklarációra hivatkozik (ebből nincsen pedig dupla), míg ettől a .hpp-től teljesen külön .hpp file másik operator<<-ra meg már nem talál illeszkedő elemet. Teszi ezt akkor, ha a cpp-be akár egy szimpla, csak a teszt kedvéért megírt (cout << "hello world") függvényt is átteszek. Ha üresen hagyom, akkor működik minden.
-
dobragab
addikt
válasz
EQMontoya #3823 üzenetére
Nem. A mutable az ellenség megtévesztése miatt került oda, az élet szülte változatban nem volt mutable.
[=]
valamiért (nem tudom, miért, számomra is rejtély) nem x-et, hanem this-t capture-öli érték szerint, de mivel this az eredeti objektumra mutat, az eredeti x-et változtatja. Tehát 3.(#3822) Domonkos
Funkcionális programozás nélkül elég mélyen lennék a ganéban, így egy teljes natív C++ shell motorja ~2000 sor.
-
EQMontoya
veterán
válasz
dobragab #3821 üzenetére
Hát, ha ez egy value szerinti capture (
[=]
), akkor az eredeti X-et nem módosíthatja, hanem csinál egy copyt.
Ez kvázi egy private member lesz abban a function objectben, amit a lambdából csinál a fordító. Mutable meg gondolom, azért lett, mert különben nem fordult, mert a saját privát X copyját nem illene módosítania.
Szóval szerintem 0-t ír ki, és mutalbe nélkül nem fordul. -
dobragab
addikt
Napi mitírki, nem magamtól szültem, élet hozta.
#include <iostream>
struct X
{
int x = 0;
void f()
{
[=]() mutable
{
x = 3;
}();
}
};
int main()
{
X x;
x.f();
std::cout << x.x;
}a) nem fordul
b) 0
c) 3 -
Hiftu
senior tag
válasz
Hunmugli #3817 üzenetére
Elmondom, miért nem ajánlott ilyesmiröl még gondolkodni sem.
1, nem tudod lokálisan elemezni a függvényt. Egy csomó külsö függösége lenne.
2, a külsö függöségei gyakorlatilag láthatatlanok lennének.
3, mások számára olvashatatlan lenne a kód (a való életben ez fontos). Keresnék a változókat lokálisan, paraméterként, adattagként, globálisnak és sehol nem találnák. Ez bujócskának jó lenne, de szoftvernek rossz.
4, hála istennek a c++ nem enged meg ilyet.Megoldás: használj paramétert és minden rendben lesz.
-
Domonkos
addikt
válasz
Hunmugli #3817 üzenetére
Pointeres hackelessel tuti meg tudnad oldani - noha majdnem ugyanott lennel, ha egy pointert passzolgatnal/raknal egy kulso szkopba a valtozo helyett...
Egyeb ami eszembe jut, az a kulonbozo IPC megoldasok, mint peldaul az osztott memoria. Nem nagyo elegans, az olvashatosagon tuti ront es foloslegesen bonyolitja meg a dolgot, ha csak erre szeretned hasznalni, de mukodhet. -
válasz
Hunmugli #3817 üzenetére
"El tudok érni egy nemglobális változót egy függvényből anélkül, hogy benne hoznám létre, vagy hogy átadnám neki?"
Szerencsére nem.
( Illetve nyilván mindent meg lehet csinálni, pointerekkel pl. megoldható, de ahhoz azért elég jól kell tudni, hogy adott architektúrán az adott fordító mit csinál és pontosan hova kell célozni a stackben. Ja, meg persze feltétel, hogy az adott változó ténylegesen létezzen, mert a példádban a fordítók jó eséllyel kioptimalizálnák a szam változót )
-
Hunmugli
aktív tag
El tudok érni egy nemglobális változót egy függvényből anélkül, hogy benne hoznám létre, vagy hogy átadnám neki?
Valami ilyesmit akarnék megvalósítani:
#include <iostream>
using namespace std;
void kiir ();
int main () {
int szam = 42;
kiir();
return 0;
}
void kiir () {
cout << main::szam << endl; //tudom, hogy ilyen nincs, de szeretnem, ha lenne
}Kb úgy kéne, mintha a mainben közvetlenül létrehozott változók (is) globálisak lennének. Van erre mód?
Szerk.: Ez nem egy probléma, vagy ilyesmi, csak szeretném kijátszani a scope-okat
-
Hunmugli
aktív tag
Egyenlőre nem volt időm a témával foglalkozni, de talán a jövőhéten már lesz. Ismerek egy helyet, tele nehéz feladatokkal, van benne gráfos is, majd meglátom, melyikekkel nem bírok el
-
#36268800
törölt tag
Sziasztok!
Hogyan érdemes, hogyan lehet egy egyszerű játéknak szép főmenüt készíteni?
Egy objektumorientált Snake-et szeretnék készíteni és arra gondoltam, hogy a főmenü lehetne egy HTML5 + CSS3 szerű(!) valami (a formázások, színösszeállítások végett, hogy szép legyen).Hogyan lehetne ezt vagy valamit, ami hasonlót eredményez, kivitelezni?
-
nji
aktív tag
sziasztok,
nem tudtok valakit Miskolc környékén, aki pénzért hajlandó korrepetálni?
Esetleg skype-on is jó, ha megbízható és leinformálható valaki, mert nem szeretnék úgy járni, hogy átutalom a pénzt és nem kapok cserébe oktatást.
Kezdő vagyok, természetesen a neten már sok mindent megnéztem, de jó lenne, ha valaki sorról sorra elmagyarázná az összefüggéseket egy bonyolult programon.
Pl előbb deklarálom a függvényt, meg megadom a struktúrát, osztályt, aztán meg kifejtem a függvényt aztán meg hívom a függvényt, meg vannak a visszatérési értékek , de kellene valaki, aki egy összetett programon keresztül az egész logikát elmagyarázza. Mint egy állatorvosi ló, ami alapján már más programot is meg tudnék írni.
Van valaki, aki ilyesmiben tud segíteni? -
mgoogyi
senior tag
Debug módban indítva breakpointoknál meg tudod fogni a progi futását. Katt a sor elé és megjelenik egy piros pötty. Ha megállt a breakpointnál: F5 hagyja továbbfutni a progit, F10 egy sort lép, F11 belelép a hívandó függvénybe. Amikor áll a cucc, meg tudod nézni a változók értékét is. Próbálkozz, menni fog.
-
Lejszi
senior tag
Sziasztok!
Ms Visual Studiot hasznalok. Egyik nap egyszer csak megbolondult a progi es nem akarja megjeleniteni az eredmenyt. A kod (ha jo) termeszetesen lefut, de nem latom az eredmenyt. Tudna vki segiteni ebben?
Par hete kezdtem el tanulni a c++ nyelvet szoval elegge kezdonek szamitok.
Ha a _getch() -t irom a vegere akkor sem jelenit meg semmit a kepernyon.Itt egy pelda program es amit kiir lefutas kozben es utana:
Futas kozben, amikor keri az erteket:
Majd miutan lefutott:
-
mgoogyi
senior tag
válasz
Hunmugli #3797 üzenetére
"Baloldalt egy char van, jobboldalt egy bit, ez nem fog menni".
A char egy 8 bites szám és jobb oldalt nem bit van, hanem egy másik 8 bites szám, aminek jellemzően egy adott bitje tér el a többitől. Innentől pedig az alap bitműveletek kellenek (és,vagy,xor,negálás)
Amit csinálsz, azt szokták flageknek hívni, minden bitnek megvan a saját jelentése.Nem kell túlgondolni az elképzelést:
1101 & 0010 = 0000 (bit ellenőrzés)
1101 | 0010 = 1111 (bit beállítás)Gyakorold valamennyit papíron, lehet az segít abban, hogy lásd, hogy melyik művelet mire jó.
Pl. 1-es bittel éselés az adott bit értékét fogja kiköpni, 0-ással(1011) az adott bitet állítod garantáltan nullára.A flagekre visszatérve: ilyesmit szoktak csinálni, hogy:
Option1 = 1 (001)
Option2 = 2 (010)
Option3 = 4 (100)Options = 101 esetén az option 1 és 3 van bekapcsolva.
Bár lehet, hogy te pontosan erre akarod használni."C bitjei balról jobbra vannak számozva, 0tól kezdődően 7ig. Function szerűen kéne"
Szerintem jobbról balra számozd a biteket, akkor a természetes bitsorrendet kapod és a 001 = 1-et jelent majd decimálisan, az 100 meg 4-et pl.
A 0-ás indexű bit a 2^0-át jelenti, az 1-es a 2^1, stb.stb.Ha kérdésed van bitekkel kapcsolatban, akkor kérdezz(akár privátban is rámírhatsz), ezzel relatíve sok gyakorlatom van.
-
Domonkos
addikt
válasz
Hunmugli #3800 üzenetére
Ha masolsz kodot, akkor rapillanthatok hogy mi csuszhat felre.
BTW: elozo hozzaszolasomban irtam, hogy jol optimalizalva ez akar egyetlen muvelet is lehet. Nos nem.Ha
N
is parameter, akkor (a regiszterekbe masolgatassal egyutt) 4 utasitas lesz. Viszont annyi igaz, hogy ennel nem lesz mar nagyon optimalizaltabb megoldas. Az egy muveletet azt a megfelelo bit atbillentesere ertettem.
Új hozzászólás Aktív témák
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- Milyen billentyűzetet vegyek?
- Kertészet, mezőgazdaság topik
- Energiaital topic
- Android játékok topikja
- Megjöttek a be quiet! Pure Loop 3 sorozatú kompakt AIO-i
- Goddess of Victory:Nikke
- Intel Core Ultra 3, Core Ultra 5, Ultra 7, Ultra 9 "Arrow Lake" LGA 1851
- Milyen videókártyát?
- Gitáros topic
- Telekom otthoni szolgáltatások (TV, internet, telefon)
- További aktív témák...
- BESZÁMÍTÁS! Asus Maximus VIII Hero i7 6700K 16GB DDR4 512GB SSD RX 5700 XT 8GB Zalman i3 NEO 700W
- Huawei Nova Y70 128GB, Kártyafüggetlen, 1 Év Garanciával
- Apple iPhone 12 / 128GB / Gyárifüggetlen / 12Hó Garancia / 100% akku
- BESZÁMÍTÁS! ASUS VS228DE FHD TN 5ms monitor garanciával hibátlan működéssel
- Lenovo ThinkPad T15 Gen 2 Intel Core i5-1135G7
Állásajánlatok
Cég: FOTC
Város: Budapest