Új hozzászólás Aktív témák
-
Jester01
veterán
válasz
dobragab #5575 üzenetére
a címét nem képezhetjük, hiszen ahhoz először pointerré konvertálódik,
Szerinted. A szabvány szerint meg de. Idéztem ott feljebb kicsivel:
Except when it is the operand of the sizeof operator or the unary & operator
Tehát ha & operátort alkalmazol a tömbre akkor nem konvertálódik pointerré.
-
Jester01
veterán
válasz
aviator #5570 üzenetére
Ez meg a híres tömb-pointer ekvivalencia. C-ben a tömb automatikusan konvertálódik az első elemére mutató pointerré:
Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue.
-
Jester01
veterán
memóriacímet tárolnak, ami egy darab szám
Ez persze nem igaz, a pointerek belső szerkezete implementációs kérdés. Például szegmentált memóriamodellben van ugye far pointer is, amiben 2 szám is van, vagy harvard architektúrán a szám mellé még azt is tudni kell adat vagy program memória stb.
Nyilván ha akarom akkor ez 1 szám mivel csak egy halom bit azt meg bármikor felírhatom számként
Az is igaz, hogy a hétköznapi rendszerekben valóban elég egy szám.
Ezzel együtt az eredeti kiindulás az volt, hogy az & operátor nem egy számot ad vissza, hanem egy megfelelő típusú pointert. Emiatt aztán (int)&x + 1 és (int)(&x + 1) az nem ugyanaz (kivéve ha véletlenül x mérete 1 byte)
-
Jester01
veterán
válasz
ToMmY_hun #5545 üzenetére
Pedig éppenséggel pointer készítő, mivel nem csak egy számot (a címet) adja vissza hanem konkrétan egy megfelelő típusú pointert (aminek a belső reprezentációja lehet, hogy nem is csak egy szám). Arra a valamire mutató pointert gyárt neked amit operandusként megadtál. (Igen, tudom, hogy amúgy address operator a neve.)
"The result is a pointer to the object or function designated by its operand"
-
-
-
Jester01
veterán
Viszont ez minden elem elérésnél egy indirekt függvényhívás amit nem tud a fordító inline beágyazni. Bizonyos mennyiség fölött garantáltan sokkal lassabb lesz, mintha ténylegesen transzponáltad volna.
A másik, hogy a cache hatékonyságát nagyban befolyásolja a bejárás. Egy sorfolytonos bejárás sokkal gyorsabb lehet mint egy oszlopok szerinti. Az algoritmust ennek megfelelően választhattad meg, de ha a hívó egy függvénypointeresen transzponált mátrixot ad be, akkor amire a kód azt hiszi, hogy hatékony sorfolytonos az valójában nem az. Ugye bizonyos műveleteknél ezért éri meg ténylegesen transzponálni a mátrixot, a bejárás megváltoztatása helyett, még akkor is ha amúgy nincs függvénypointeres trükközés. Lásd még What every programmer should know about memory: "Through the simple transformation of the matrix we can achieve a 76.6% speed-up! The copy operation is more than made up. The 1000 non-sequential accesses really hurt. "
Virtuális mátrixokhoz viszont kétségkívül jó megoldás lehet.
-
Jester01
veterán
válasz
dabadab #5196 üzenetére
Attól függ mi a feladat pontosan. Mert ha a transzponált mátrixot oda kell adni valami másik függvénynek az boldogtalan lesz ha nem transzponálod ténylegesen mert nem tudja, hogy fel kell cserélni a koordinátákat. Persze ha van valami társított flag ami mutatja és ezt minden tudja is kezelni, akkor jó megoldás.
A kérdésre válaszolva: végig kell iterálni az alsó vagy a felső hárömszögön és cserélgetni. Már ha nem kell új helyre másolni, mert akkor az egészen végig kell menni és felcserélve kiírni.
-
Jester01
veterán
válasz
DrojDtroll #5130 üzenetére
Szerintem már ő is tudja
-
Jester01
veterán
válasz
DrojDtroll #5038 üzenetére
Ah, hát ez egyszerűbb
-
Jester01
veterán
válasz
DrojDtroll #5036 üzenetére
Elvileg a SetConsoleMode függvénnyel ki kell kapcsolni az ENABLE_LINE_INPUT beállítást. De nem tudom, nekem linuxom van
-
Jester01
veterán
válasz
DrojDtroll #5034 üzenetére
Szabvány C-ben nem, csak rendszerfüggő módon.
-
Jester01
veterán
Azért mondja a nullára, hogy páros, mivel az
A sorrend a rossz, először a nullát ellenőrizd és csak utána a paritást.
Egyébként a feladatnak nem felel meg a programod, hiszen van kiírás a (csodaszép nevű) e függvényben is. A visszatérési érték pedig mindig nulla.
Annak sem sok értelme van, hogy else if (a%2!=0), hiszen az else már magában is ezt jelenti, tekintve, hogy az előző feltétel if (a%2==0) volt.
-
Jester01
veterán
A beolvasás egyszerű feladatnak tűnik, mégis meglepően bonyolult jól csinálni.
Az fflush(stdin) nem szabványos, vagy működik vagy nem. Az ajánlott módszer teljes sorok olvasása fgets használatával, majd a beolvasott sor számmá alakítása strtol segítségével. A helyes megoldás a sor olvasásnál kezeli a túl hosszú sorokat, és az átalakítás után ellenőrzi, hogy maradt-e még feldogozatlan karakter.
Ennél egyszerűbb megoldás, ha az fflush(stdin) helyett egy fgetc(stdin) ciklussal kiolvasol mindent a sor (vagy a bemenet) végéig.
Az is rossz a kódban, hogy a scanf visszatérési értékét nem ellenőrzöd. Ha ugyanis nem számot írnak be, akkor nem tud mit konvertálni és az i értéke változatlan marad. Azt pedig nem is inicializáltad, tehát bármi lehet. Ha véletlenül 1 és 5 közé esik akkor a programod kilép a ciklusból.
-
Jester01
veterán
1. nem lehet tudni mit ír ki, mert nem definiált működés
2. itt nem kell az L, akkor kellene esetleg ha műveleteket végzel vele ami túlcsordulhat
3. nem tudjuk ennyiből megállapítani
5. a C ilyen buta
+1. ha nem az eredetit akarod módosítani, akkor foglalj dinamikusan memóriát (malloc)buherton:
-
Jester01
veterán
válasz
#68216320 #4894 üzenetére
A forrásfájl kódolása tetszőleges lehet és független a futásidejű kódolástól. Az aktuális locale beállításból jön, alapértelmezése pedig utf8. Persze meg is lehet adni a fordítónak, gcc esetén a -finput-charset kapcsolóval.
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main()
{
const wchar_t* text = L"árvíztűrő tükörfúrógép";
wchar_t buf[40];
setlocale(LC_ALL, "");
wprintf(L"Írd be, hogy %ls: ", text);
fgetws(buf, 40, stdin);
buf[wcslen(buf) - 1] = 0;
wprintf(L"Ezt írtad be: \"%ls\", %ls\n", buf,
wcscmp(text, buf) ? L"nem egyezik" : L"egyezik");
return 0;
}$ file test-utf8.c
test-utf8.c: C source, UTF-8 Unicode text
$ gcc -finput-charset=utf8 test-utf8.c
$ ./a.out
Írd be, hogy árvíztűrő tükörfúrógép: árvíztűrő tükörfúrógép
Ezt írtad be: "árvíztűrő tükörfúrógép", egyezik
$ iconv -f utf8 -t iso8859-2 < test-utf8.c > test-latin2.c
$ gcc -finput-charset=iso8859-2 test-latin2.c
$ ./a.out
Írd be, hogy árvíztűrő tükörfúrógép: árvíztűrő tükörfúrógép
Ezt írtad be: "árvíztűrő tükörfúrógép", egyezikMégegyszer, röviden: a forrás tetszőleges kódlappal lehet, ha azt megmondod a fordítónak. Futásidőben pedig a setlocale megfelelő használata szükséges. Ennyi.
-
-
Jester01
veterán
válasz
don_peter #4841 üzenetére
Mikrokontrolleren számíthat, hogy >> i vagy >> 1 mert előbbi lehetséges, hogy csak egy ciklusban, egyesével valósítható meg. A kiírást tehát célszerű úgy csinálni, hogy csak egyet léptetsz, az értéket (ha módosítható) vagy a maszkot.
for(i=0; i<8; i++, bitek >>= 1) {
if (bitek & 1) {
...
}
}Bizonyos esetekben a visszafelé futó ciklus is kisebb/gyorsabb lehet.
-
Jester01
veterán
-
-
Jester01
veterán
glibc-ben van fopencookie de az valóban nem szabványos.
Ha saját programodból akarsz mondjuk soros portra írni, akkor úgy célszerű eleve felépíteni.
-
Jester01
veterán
válasz
tototos #4687 üzenetére
Általános esetben inkább kivonás mint maszkolás mert ez utóbbi nem mindig jó.
Amúgy osztási maradékot lehet még használni, de az sokkal lassabb szokott lenni.Egyébként 62 sosem lesz, hiszen maximum 59+2=61 lehet.
A while(act_sec<wait) viszont rossz, hiszen ha az act_sec 59 akkor a wait 1 lesz és bele sem megy a ciklusba.
Ami még probléma lehet, hogy esetleg éppen az aktuális másodperc végén jársz és így akár közel 1 másodpercre is zsugorodhat a várakozási idő.
-
Jester01
veterán
válasz
tototos #4671 üzenetére
De, oda lehetne:
gcm_zeroes = kzalloc(16, GFP_KERNEL);
if (!gcm_zeroes) return -ENOMEM;
err = crypto_register_template(&crypto_gcm_base_tmpl);
if (err)
{
kfree(gcm_zeroes);
return err;
}
err = crypto_register_template(&crypto_gcm_tmpl);
if (err)
{
crypto_unregister_template(&crypto_gcm_base_tmpl);
kfree(gcm_zeroes);
return err;
}
err = crypto_register_template(&crypto_rfc4106_tmpl);
if (err)
{
crypto_unregister_template(&crypto_gcm_tmpl);
crypto_unregister_template(&crypto_gcm_base_tmpl);
kfree(gcm_zeroes);
return err;
}
err = crypto_register_template(&crypto_rfc4543_tmpl);
if (err)
{
crypto_unregister_template(&crypto_rfc4106_tmpl);
crypto_unregister_template(&crypto_gcm_tmpl);
crypto_unregister_template(&crypto_gcm_base_tmpl);
kfree(gcm_zeroes);
return err;
}
return 0; -
Jester01
veterán
válasz
buherton #4664 üzenetére
Hogy nem általános és nem ajánlott az nézőpont kérdése. A linux kernel például tele van vele (konkrétan 112235 darabot számoltam össze), mert erőforrás felszabadításhoz hiba után hasznos. Például:
gcm_zeroes = kzalloc(16, GFP_KERNEL);
if (!gcm_zeroes) return -ENOMEM;
err = crypto_register_template(&crypto_gcm_base_tmpl);
if (err) goto out;
err = crypto_register_template(&crypto_gcm_tmpl);
if (err) goto out_undo_base;
err = crypto_register_template(&crypto_rfc4106_tmpl);
if (err) goto out_undo_gcm;
err = crypto_register_template(&crypto_rfc4543_tmpl);
if (err) goto out_undo_rfc4106;
return 0;
out_undo_rfc4106:
crypto_unregister_template(&crypto_rfc4106_tmpl);
out_undo_gcm:
crypto_unregister_template(&crypto_gcm_tmpl);
out_undo_base:
crypto_unregister_template(&crypto_gcm_base_tmpl);
out:
kfree(gcm_zeroes);
return err; -
Jester01
veterán
válasz
Ereshkigal #4553 üzenetére
Nem olyan nagyon jó
Mivel az OS valószínűsíthetően tiszta lappal indítja a processzed, ezért ez a memóriaszemét jó eséllyel determinisztikus lesz. Ráadásul fordítási és memóriaellenőrzési (valgrind) figyelmeztetést is okoz. -
Jester01
veterán
válasz
don_peter #4498 üzenetére
Bináris->oktális pofon egyszerű, mivel 3 bit 1 oktális számjegyet kódol. Simán a legkisebb helyiérték felől 3 bitenként leírsz egy oktális számjegyet és kész. Feltételezem 3 bitet tudsz konvertálni, de ha nem akkor ugye a helyiértékek 4,2,1.
Bináris->hexa hasonlóan csak ott 4 bitenként haladsz.
A tízes számrendszer már külön állatfaj mivel nem kettő hatvány. Ott az általános átváltási módszert kell használni.
-
Jester01
veterán
válasz
don_peter #4445 üzenetére
C-ben is van strlen de csak akkor működik ha van egy lezáró 0 byte a karakterek után. Továbbá ez minden alkalommal végignézi a stringet, szóval nem valami gyors. Javasolt kézzel nyilvántartani a tömbbe rakott karakterek számát, ahogy te is tetted.
A másik probléma az gondolom a kávé hiányra vezethető vissza, mert óvodás matematika
Ugye ha van egy abcd szám annak az értéke a*1000+b*100+c*10+d. Ennyi segítség már elég hozzá?
-
Jester01
veterán
Hmm, a JIT kód nem tűnik túl okosnak, nem tudom mitől gyors:
0x00007fe2237a679a: movsd 0x10(%rbx,%rbp,8),%xmm0 ;*daload
; - Test::summUp@12 (line 11)
0x00007fe2237a67a0: movsd 0x8(%rsp),%xmm1
0x00007fe2237a67a6: addsd %xmm0,%xmm1
0x00007fe2237a67aa: inc %ebp
0x00007fe2237a67ac: ucomisd 0x20c(%rip),%xmm0 # 0x00007fe2237a69c0
; {section_word}
0x00007fe2237a67b4: movsd 0x8(%rsp),%xmm0
0x00007fe2237a67ba: ja 0x00007fe2237a67c0
0x00007fe2237a67bc: movapd %xmm0,%xmm1 ;*iinc
; - Test::summUp@26 (line 10)
0x00007fe2237a67c0: cmp %r11d,%ebp
0x00007fe2237a67c3: jge 0x00007fe2237a67cd
0x00007fe2237a67c5: movsd %xmm1,0x8(%rsp)
0x00007fe2237a67cb: jmp 0x00007fe2237a679a -
Jester01
veterán
válasz
dabadab #4424 üzenetére
Ez tényleg elég meglepő, de én is tudtam reprodukálni.
Elsőre rávágtam, hogy a java biztos elágazás-mentes kódot generál, de ha kicsit átírtam, hogy a gcc-nek is feltűnjön ez a lehetőség attól ugyan gyorsabb lett de még nem java szintű. Sőt, még durvább optimalizációval egy iterációban 8 elemet ad össze és még így is lassabb.A random tömböt egyébként kicseréltem, hogy mind a két implementáció azonos számokkal dolgozzon (és mindig ugyanazokkal).
-
Jester01
veterán
válasz
prosoftware #4327 üzenetére
A getchar() a sorvég jelet \n eszi meg mivel azt a scanf a [^\n] miatt nem tette meg. Persze bele lehetne oda is tenni.
-
Jester01
veterán
válasz
prosoftware #4321 üzenetére
Nem ugyanazt csinálják, ha a sorban a két számon kívül még van valami és később azt is be akarod olvasni.
scanf("%d%d%*[^\n]", &a, &b);
getchar();
scanf("%d", &c);
printf("%d %d %d\n", a, b, c);Be:
1 2 3
4
Ki: 1 2 4Az első sorban a szám után bármi lehet, azt figyelmen kívül hagyja.
scanf("%d%d%", &a, &b);
scanf("%d", &c);
printf("%d %d %d\n", a, b, c);Be: 1 2 3
Ki: 1 2 3Itt a két szám után ami még a sorban volt az megmarad és a további beolvasások felhasználják. A formátumstringben az utolsó % jel pedig igenis elírás mivel annak ott semmi értelme nincs. Ugyanígy működik anélkül is, csak akkor még helyes is.
-
Jester01
veterán
válasz
prosoftware #4318 üzenetére
Az első az megeszi az egész sort, a második az nem (a végén a % az gondolom elírás).
-
Jester01
veterán
Csinálsz egy ciklust ami végigmegy a tömbön (ez lesz a forrás pozíció) és egy változót ami a cél pozíciót tárolja. Ha az adott elemet meg kell tartani, akkor a forrásból a célba másolod és növeled a cél pozíciót, különben nem.
dst = 0;
for(src = 0; src < len; src++) {
if (!pred(a[src])) a[dst++] = a[src];
} -
-
Jester01
veterán
válasz
alapz@j #4207 üzenetére
A kapcsos zárójel elhelyezése ízlés dolga, de az egy soros dolgok köré is erősen ajánlott kitenni őket, mivel ahogy arra dababab már rámutatott, később könnyen hibához vezethet.
-
Jester01
veterán
válasz
stranger28 #4198 üzenetére
Szerintem alapvetően nincs baj az int*-al, bár tény, hogy C-ben ilyen nincs de szerintem olvashatóbb. Személy szerint szigorúan követem a soronként csak 1 változó elvet, így a "hová tartozik a *" probléma nem érint.
Ja és még a beolvasásod nem bolondbiztos. Igaz, azt C-ben nehéz is csinálni, de első körben legalább a scanf visszatérési értékét ajánlott ellenőrizni.
-
Jester01
veterán
Az akkor lehet, ha elfelejtetted hozzálinkelni a math könyvtárat. Minden bizonnyal valamit panaszkodott is a fordító, legközelebb azt is írd meg nekünk, valamint keress rá az interneten is. Jelen esetben valószínűleg undefined reference hibát kaptál ami azt jelenti, a linker nem talált valami hivatkozott szimbólumot. Ilyenkor ha nem elírás történt, akkor hiányzó könyvtárak/modulok felé kell keresgélni. Konstansra azért fordulhat, mert azt szerencsés esetben a fordító kiszámolja így nincs szükség a tényleges atan implementációra.
Végül pedig a gyógymódról. Nem írtad milyen környezetet használsz, parancssoros gcc esetén -lm kapcsolót kell alkalmazni. A -l segítségével lehet függvénykönyvtárakat hozzáadni a beszédes m pedig a matek könyvtár neve. IDE környezetben meg kell keresni hol lehet további könyvtárakat (library) beállítani és ott fel kell venni a matek könyvtárat.
-
Jester01
veterán
Mint rajottem, az ftell/fgetpos csak akkor mukodik "helyesen", ha mar olvastam a streambol.
Ha elso olvasas elott adom ki, akkor -20-at ad vissza, es innentol fogja egyesevel novelni/csokkenteni a poziciot minden getc/ungetc utan, nem nullatol.Ezt nehezen hiszem, és ha tényleg így van az bug.
Nekem egyébként működik linuxon, akár text akár binary módban nyitom meg a fájlt. -
Jester01
veterán
válasz
alapz@j #4165 üzenetére
Ahogy a kollega írta, logikailag megsemmisül és a szabvány csak ennyit ír elő.
Az már fordítófüggő, hogy ez hogyan néz ki gépi kód szinten, de rendesen optimalizáló fordító nyilván előre lefoglalja a területet és újrahasznosítja. Mellesleg a stack kezelésnek igen minimális az overheadje hiszen csak egy-egy pointer művelet.Ha érdekel a végeredmény hogy néz ki akkor kérj assembly listát a fordítódtól vagy használd ezt a remek weboldalt.
-
Jester01
veterán
válasz
Jester01 #4135 üzenetére
Sőt, durvábbat mondok. Ha azokat nézzük ahol az első 19 szám a 0, 0.01, 0.02, 0.03, 0.04, 0.05 bármelyike a huszadik pedig szépen kipótolja az összeget 1-re, akkor az 6^19 lehetőség ami nagyjából 609 billió. Ezt az életben nem fogod mind végignézni, és ez még mindig csak az összes lehetőség töredéke!
Ú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!
- Szeged és környéke adok-veszek-beszélgetek
- RETRO beárazás (mobil, PC, konzol)
- Folyószámla, bankszámla, bankváltás, külföldi kártyahasználat
- Samsung Galaxy S24 Ultra - ha működik, ne változtass!
- Telekom otthoni szolgáltatások (TV, internet, telefon)
- Okos Otthon / Smart Home
- Nem növel telepméretet a Galaxy S26 Ultra
- PlayStation 5
- Energiaital topic
- Kertészet, mezőgazdaság topik
- További aktív témák...
- Lenovo V130-15IGM laptop (Pentium Silver N5000/8GB/256GB SSD
- HPE Aruba PoE+ L3 switch raktárról azonnal elérhető!
- ÁRGARANCIA! Épített KomPhone Ryzen 7 9800X3D 32/64GB RAM RTX 5070 12GB GAMER PC termékbeszámítással
- BESZÁMÍTÁS! MSI B450M R5 5500 32GB DDR4 512GB SSD RTX 3060 12GB Rampage SHIVA Chieftec 600W
- Csere-Beszámítás! RTX Számítógép játékra! R5 5600X / RTX 3080 / 32GB DDR4 / 1TB SSD
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: CAMERA-PRO Hungary Kft
Város: Budapest