Hirdetés
- Samsung Galaxy S25 Ultra - titán keret, acélos teljesítmény
- Fotók, videók mobillal
- Xiaomi 15T - reakció nélkül nincs egyensúly
- Apple Watch
- Olyan lesz a Google Térkép, mint a segítőkész haver az anyósülésen
- iPhone topik
- Apple iPhone 14 - tavalyi termésből főzve
- Hivatalos a OnePlus 13 startdátuma
- Samsung Galaxy Watch (Tizen és Wear OS) ingyenes számlapok, kupon kódok
- Milyen okostelefont vegyek?
Új hozzászólás Aktív témák
-
dobragab
addikt
válasz
maestro87
#5683
üzenetére
"Összetett literális".
Alaptípusokra, mint amilyen az
int, azunsigned long, adouble, tudsz a programkódba beágyazott konstansokat írni. Pl:0,25UL,0x0badc0de,4.6f,0.001. Speciális literal még a string literal, amit így ismersz:"Hello world!\n".Struktúrákra, union-okra, tömbökre C89-ben ilyet csak inicializálásnál tudsz:
struct Pont p = {5, 12};
int arr[] = {1, 2, 3, 5, 8, 13, 21};
p = {12; -5}; // <- ERROR
p.x = 12;
p.y = -5; // <- macerásC99 behoz ezzel kapcsolatban két feature-t, a compound literal és a designated initializer.
Compound literal
Arra való, hogy a programkódban ne csak ilyen alaptípusokat, hanem összetett típusokat is meg lehessen adni egyetlen kifejezésben. Ehhez ugyanaz a szintaxis, mint az inicializálásnál, konyhanyelven annyi különbséggel, hogy a kapcsos zárójel tartalmát az adott típusra kell "cast-olni".
p = (struct Pont){12; -5};
struct Pont Pont_tukroz(struct Pont p)
{
return (struct Pont){p.y, -p.x};
}
struct Pont q = Pont_tukroz((struct Pont){10, 13});printf("%p\n", (int[]){1});
double osszeg = double_osszeg((double[]){1.0, 2.718, M_PI}, 3);Ezek a "változók" temporális objektumok, nincs nevük, nem képezheted a címét, mint ahogy ez is értelmetlen:
printf("%p", &1);Élettartamuk a blokk végéig tart (bezáró
}), nem úgy, mint C++-ban, ahol a pontosvesszőig (jó, nem pont így van a szabványban, de megközelítőleg pontos).Designated initializer
C-ben a struktúrák adattagjait közvetlenül érjük el, szinte mindig név szerint.
void Pont_kiir(struct Pont p)
{
printf("(%d, %d)", p.x, p.y);
}Kivéve: inicializálásnál.
struct Pont p = {5, 12};Ez egyértelműnek tűnik, az
xkoordináta 5 lesz, azypedig 12. De mi történik, ha valami bunkó így definiálta astruct Pont-ot?struct Pont
{
int y;
int x;
}Ilyenkor minden működik tovább, kivéve az inicializálást, akkor pont fordítva történnek a dolgok, mint ahogy az ember elképzelte. Ezért vezették be, hogy a struktúrákat inicializálni is lehessen név szerint:
struct Pont p = {.x = 5, .y = 12};Természetesen compound literal-lal együtt is használható.
p = {.x = 5, .y = 12};És nem csak struktúrákra, tömbökre is.
int arr[] = {[0] = 8, [1] = 13, [2] = 21};Sőt, vegyesen is.
haromszog_rajzol((struct Pont[])
{
[0] = {.x = 12, .y = 5},
[1] = {.x = -12, .y = 5},
[2] = {.x = 0, .y = 0}
});Jó eséllyel ezeket a te fordítód is támogatja, ha GCC vagy Clang, csak -std=c99 kell neki. MSVC a C99 cuccokat a 2015-ös verzió óta zömmel tudja...
EQMontoya: bocsi a magyar változónevek miatt

-
dobragab
addikt
válasz
maestro87
#5676
üzenetére
C-ben is lehet OO kódot írni, csak nehezebb, öröklést csinálni pedig undorító. Az OOP elveket viszont explicite nem támogatja a C, azaz egy C-s "osztályt" bármikor lehet szarul használni, C++-ban többé-kevésbé a használójára rá lehet kényszeríteni a "jó" használatot. Legalábbis dióhéjban ennyi.
(#5675) ToMmY_hun
C++-ban szerintem gátlástalanul lehet
return-ölni akárhonnan. C-ben vigyázni kell, mert lehet, hogy pl. hibajelzésre használt visszatérés előtt fel kéne szabadítani valami erőforrásokat, és nem történik meg automatikusan. Erre (C-s kivételkezelés) majd fogok szülni egy másik hsz-t, még agotokapcsán. -
EQMontoya
veterán
válasz
maestro87
#5671
üzenetére
Van, amikor nincs ++i.

Pl, c++.ban:for(const auto& i : my_list) { ... }A continue-ban azt szeretjük, hogy az minden nyelven ugyanúgy működik.
És hidd el, azt mindenki érti, ha pedig a ciklus közepén a ciklusváltozóhoz nyúlsz, az:
-Sokkal kevéssé érthető
-Jobb helyen arconvágnak érte, mert nagyon veszélyes.Pl.
for(int i = 0; i < valami ; ++i)
{
if(zöld(tömb[i]) && pöttyös(tömb[i])) continue;
if(sarga(tömb[i]) && !csikos(tömb[i])) continue;
//do something here...
}Sok sikert ++i-vel.

-
ToMmY_hun
senior tag
válasz
maestro87
#5671
üzenetére
Kereső algoritmusokban a keresett elem megtalálásakor hasznos lehet a
continue. Olyankor is, amikor előfeltételként vizsgálod a ciklusmagban egy számításigényes művelet elvégzésének szükségességét. (Erre írt példát EQMontoya).A mikrokontrollerek programozásához pedig nagyon kevés, speciális esetben van szükség C++ használatra. Komplexebb problémák megoldása során találkozhatsz vele, úgy mint például orvostechnikai berendezések, robotika stb. A "mitől job" kifejezés pedig nem a legcélszerűbb megfogalmazási módja a kérdésnek, nem jobb és nem is rosszabb, szimplán más a létezésének célja.

-
dobragab
addikt
válasz
maestro87
#5671
üzenetére
++itök mást csinál.continueigazából arra való, hogy ne legyen annyi egymásba ágyazás. A fenti kód így írható át:void print_primes(int * primes, int lenght)
{
for(int i = 0; i < lenght; ++i)
{
if(primes[i]>=2)
{
/* és egy rakás random utasítás */
if(is_prime(primes[i]))
printf("%d\n", primes[i]);
/* meg itt is sok utasítás */
}
}
}A bitb*szogatás nem az én területem, de tudomásom szerint a
continueasm-ben 1 db jump lesz, ugyanúgy, ahogy azifis.C++ C-hez képest nagyon sok mindent tud, amit neked első körben érdemes megnézned, az az objektumorientált tervezés.
-
EQMontoya
veterán
válasz
maestro87
#5665
üzenetére
void print_primes(int * primes, int lenght)
{
for(int i = 0; i < lenght; ++i)
{
if(i<2) continue;
if(is_prime(i)) printf("%d\n", i);
}
}Így a paraméterként kapott tömb negatív elemeire le sem fut a prímtesztelés, mert ugye nincs is értelme, lehet, hogy felkészítve sincs rá.
Teccikéteni?Hú, de nehezen ment c++ nélkül

-
-
dobragab
addikt
válasz
maestro87
#5654
üzenetére
emp.dojegy három elemű tömb, amit inicializálni csak akkor tudsz, amikor létrehozod azempváltozót.Employee emp = {
"John Sample", 0, 2500,
{1, 1, 1970},
{1, 1, 1970},
{1, 1, 1970}
};Külön inicializálni már nem tudod, csak értéket adhatsz neki. Illetve nem is neki, mert C-ben nincs tömbök közötti értékadás, hanem az elemeinek, mégpedig egy létező dátumot:
date date0 = {1, 1, 1970};Ezután adhatsz értéket az
emp.dojelemeinek.emp.doj[0] = date0;
emp.doj[1] = date0;
emp.doj[2] = date0;Itt segítségedre lehet a C99 compound literal:
emp.doj[0] = (date){1, 1, 1970};Ha kinullázni szeretnéd egy struktúra adattagjait, akkor ez nem szabványos, normális fordító nem eszi meg:
date date0 = {};Ez viszont igen:
date date0 = {0}; -
buherton
őstag
-
buherton
őstag
-
dobragab
addikt
válasz
maestro87
#5481
üzenetére
Ha jól értelmezem, a --FLOAT és a --DOUBLE független egymástól. Azaz ha csak --FLOAT=32-t adsz neki, akkor a double ugyanúgy 24 bites marad, ami szerintem nem vicces. Zavaró lehet, hogy a float pontosabb, mint a double, sőt, szemantikailag is rossz.
Így a float 32 bites értékeket tud tárolni, de számolni csak 24 bittel tud. C szabvány szerint minden lebegőpontos művelet előtt double-re vagy long double-re konvertálódnak az operandusok. Szóval a te esetedben semmit nem ér.
Ha 32 bites lebegőpontos számítás kell, akkor --DOUBLE=32 mindenképp kell. Az a te döntésed, hogy a float-ot meghagyod-e 24 bitesnek, és ahol kell a pontosság, ott double-t írsz float helyett; vagy teszel az egészre és mindkettőt 32 bitesre állítod. Én az előbbit tenném, figyelembe véve a saját kódolási stílusomat. Mindenhol double-t használok, kivéve ott, ahol a memóriával takarékoskodni kell.
-
-
dobragab
addikt
válasz
maestro87
#5473
üzenetére
Nem ismerem a fordítód #pragma-kezelését, de szerintem nem így működik. A #pragma fordító-függő, mindegyik azt csinál vele, amit akar, és a számára értelmezhetetlen #pragma-kat ignorálja. Szóval ha ezt nem tudja értelmezni, akkor is lefordul.
--FLOAT=32
Én úgy értelmeztem a dokumentációt, hogy ezt a parancssori argumentumok között kéne odaadni a fordítónak.
cc whatever.c --FLOAT=32
-
jattila48
aktív tag
válasz
maestro87
#5473
üzenetére
A float példádból az látszik, hogy a pontos bináris ábrázolásból az alsó legalább 7, de legfeljebb 12 bitet elhagyja, majd kerekít. Ha csak 6 bitet hagyna el, akkor a kiírásban pontos értéket, míg ha 13 bitet, akkor kisebb értéket (6119424) kaptál volna. Pl. lehet, hogy az alsó 8 bitet hagyja el (valószínűleg így van). Szerintem a float-od 24 bites, amiből a mantissza 16 bit (előjellel együtt, vagyis 15 értékes bit), a karakterisztika pedig 8 bit. Ha 32 bites float-ra is ugyanez a kiírás adódik, akkor a mantissza szintén 16 bit, viszont a karakterisztika is 16 bit (bár ennek nem sok értelme lenne). A float érték úgy ábrázolódik, hogy a mantissza 15 értékes bitjét 0,xxxxxxxxxxxxxxx értéknek tekinted (0, kettedes vessző után jönnek a mantissza bitjei), amit megszorzol 2^karakterisztika-val. 8 bites karakterisztikával kb. 2^127 nagyságrendű számokat tudsz ábrázolni, vagyis bőven elég nagyokat. Viszont 16 bites mantisszával legfeljebb 1/2^16 relatív pontosság érhető el. Az, hogy hány tizedes jegyre (vagy "kettedes" jegyre) pontos az ábrázolás (ez az abszolút hiba), függ a szám nagyságától, ezért csak relatív pontosságról van értelme beszélni (abszolút hiba/pontos érték). A példádban a relatív hiba 64/6123456, ami megfelel a 15-16 bites mantisszának. Ami a szorzást illeti: egész biztos, hogy mindkét operandusod float-ra fog konvertálódni, vagyis 8 bites karakterisztikával bőven ábrázolható lesz, viszont a relatív hiba ugyanúgy megmarad 1/2^16 felső korláttal. Mivel az operandusok már hibával terheltek, ezért a szorzat is az lesz (szorzásnál a relatív hibák összeadódnak). Tehát nem a kiírásnak vannak korlátai (legfeljebb normál alakban írja ki), hanem a szám ábrázolásnak, amit tudomásul kell venni, és így kell velük dolgozni. Természetesen ezekkel a korlátokkal is megvalósíthatsz tetszőleges pontosságú egész vagy float aritmetikát, azonban ez igen macerás.
-
zka67
őstag
válasz
maestro87
#5471
üzenetére
Szia, a fordítód alapértelmezett beállítása 24 bites lebegőpontos számok. Így ne csodálkozz, ha csak az első néhány számjegye pontos. A --FLOAT=32 opcióval állítsd át 32 bitesre a lebegőpontos számok formátumát, és így már 6 tizedesig pontos lesz. Továbbá a doksid 143. oldalán megtalálod a különböző változó típusok pontosságát, így nem igaz, hogy csak 16 bites számokat tud kezelni a fordítód. Van pl. signed és unsigned short long, és signed és unsigned long, 24 és 32 bites méretben.
A lebegőpontos számoknál pontosabb eredményt kapsz, ha tudod hogy hány tizedesjegy pontosságra van szükséged, és egész számokat használsz. Ha pl. 3 tizedes elég, akkor megszorzod pl. at 123.456-ot 1000-el és 123456-al dolgozol, amikor pedig az eredményre van szükséged akkor osztod 1000-el és meg is van a számod egész része. És gyorsabb is.
-
dobragab
addikt
válasz
maestro87
#5468
üzenetére
Vigyázz a formátumsztringgel. A formátumnak egyeznie kell a paraméterként kapott típussal. pl. ha ezt akarod kiíratni:
10 * 10.5
akkor ahhoz %f kell, mert a kifejezés double típusú.
Ha ugyanezt szeretnéd integer-ként (%d) kiíratni, akkor a típust hozzá kell igazítani a formátumsztringhez.
printf("%d", (int)(10 * 10.5));
-
buherton
őstag
válasz
maestro87
#5447
üzenetére
Írásra törlődő regiszterek esetén határozottan célszerű a maszkolás, vagy ha nem direktben egy címre írsz, hanem mondjuk egy struktúra pointer által mutatt pointerre, ahol már nincs castolás, és kapásból memória korrupció léphet fel. Ez kvázi egy ököl szabály, hogy csak azokat a biteket engedjük át, ami valós értéket képviselnek. A többi maszkoljuk.
Közben eszembe jutott még egy példa. Mi van ha a változó értéke éppenséggel -1? Az egész változó tele van 1-esekkel.
MOD: ilyenekre nincs iromány.
-
-
Karma
félisten
válasz
maestro87
#5441
üzenetére
1) Nekem is feeslegesnek tűnik, mintha nem akartak volna üres zárójeleket írni.
2) A vessző egy alap C operátor, azt jelenti, hogy sorban végrehajtja a három műveletet, és az utolsónak az eredményét adja vissza. Az első két tag elég fontos, ezzel címezi meg az EEPROM adott celláját és engedélyezi az olvasást – ezek nélkül a harmadik tagnak semmi értelme.
Új hozzászólás Aktív témák
● olvasd el a téma összefoglalót!
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- Luck Dragon: Asszociációs játék. :)
- Milyen TV-t vegyek?
- Amlogic S905, S912 processzoros készülékek
- Formula-1
- Proxmox VE
- Samsung Galaxy S25 Ultra - titán keret, acélos teljesítmény
- BestBuy topik
- Samsung Galaxy Felhasználók OFF topicja
- Konzolokról KULTURÁLT módon
- Mibe tegyem a megtakarításaimat?
- További aktív témák...
- iPhone 13 mini 128GB Midnight -1 ÉV GARANCIA - Kártyafüggetlen, MS3086, 100% Akkumulátor
- ÁRGARANCIA!Épített KomPhone Ryzen 7 7800X3D 32/64GB RAM RTX 5090 32GB GAMER PC termékbeszámítással
- ÁRGARANCIA!Épített KomPhone i7 14700KF 32/64GB RAM RTX 5080 16GB GAMER PC termékbeszámítással
- Samsung SyncMaster 930BF 19" 1280 x 1024 DVI!
- ÁRCSÖKKENTÉS Menő retró konfig: Q9550, Gigabyte P43, 4GB RAM, ASUS GT730
Állásajánlatok
Cég: Laptopműhely Bt.
Város: Budapest
Cég: NetGo.hu Kft.
Város: Gödöllő



Kicsit félrevezető a TutorialsPoint-os kód, szerintem nem túl célszerű így demonstrálni a continue működését.


