- iPhone topik
- Samsung Galaxy A54 - türelemjáték
- Android alkalmazások - szoftver kibeszélő topik
- Samsung Galaxy S21 Ultra - vákuumcsomagolás
- Hivatalos a OnePlus 13 startdátuma
- Samsung Galaxy S25 Ultra - titán keret, acélos teljesítmény
- Redmi Note 12 Pro - nem tolták túl
- VoLTE/VoWiFi
- További kavarás a Pixel 10-ek körül
- Egyszerre legnagyobb és legkisebb is a Garmin Venu X1
Ú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
x
koordináta 5 lesz, azy
pedig 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 agoto
kapcsá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
++i
tök mást csinál.continue
igazá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
continue
asm-ben 1 db jump lesz, ugyanúgy, ahogy azif
is.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.doj
egy három elemű tömb, amit inicializálni csak akkor tudsz, amikor létrehozod azemp
vá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.doj
elemeinek.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
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!
- Üzletből, garanciával, Macbook Pro Retina 14" 2021, M1 32GB RAM/1TB SSD Space gray
- HP EliteBook x360 830 G8 Core i5 1145G7 2.6GHz/16GB RAM/512GB
- UF Lenovo Yoga 9i x360 Érintős Hajtogatós Laptop Tab 14" -60% i7-1360P 16/1TB Iris Xe 2,8K OLED 90Hz
- Lenovo Yoga 9i x360 Érintős Hajtogatós Laptop Tab 14" -60% i7-1260P 16/512 Iris Xe 2,8K OLED 90Hz
- Új DELL Inspiron 16 Fémházas Multimédiás Laptop 16" -40% Ryzen 7 8840U 8mag 16/1TB FHD+ IPS
- Konica Bizhub C220 - A3 fénymásoló
- Iphone 15 Plus 128GB Pink Dobozos 12 Hónap Garancia
- PlayStation Plus Premium 24 hónapos előfizetés , egyenesen a Sony-tól!
- DELL PowerEdge R730xd 12LFF+2SFF rack szerver - 2xE5-2680v3,64GB RAM,4x1GbE,H730 RAID v ZFS
- BESZÁMÍTÁS! Gigabyte B650M R7 7700 32GB DDR5 1TB SSD RTX 5070 12GB BE QUIET! Pure Base 500DX 650W
Állásajánlatok
Cég: CAMERA-PRO Hungary Kft
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged