Sziasztok!
Adott a következő C programrészlet:
uint16_t a=0x0100;
uint16_t b=0x0100;
uint32_t c;
c=a*b;
Mennyi lesz a c változó értéke?
Szerk.: 16 és 32 bites rendszereken különböző a végeredmény. A specifikáció megfelelő részére keresek linket.
- 7267 megtekintés
Hozzászólások
65536
- A hozzászóláshoz be kell jelentkezni
Biztos?
- A hozzászóláshoz be kell jelentkezni
Biztos. Vizsgan ulsz? :D
----------------------
while (!sleep) sheep++;
- A hozzászóláshoz be kell jelentkezni
Ha igen, akkor remélem megbukik. Ilyet kérdezni...
- A hozzászóláshoz be kell jelentkezni
Nem vizsga, hanem egy programban találtam eltérő viselkedést PC-n és 8 bites mikrokontrolleren.
Sehol nem találtam meg az idevágó specifikációt, ami megadja, hogy egy műveletet milyen pontossággal kell elvégeznie a programnak, és abban biztam, hogy valaki beidézi az idevágó passzust :-).
- A hozzászóláshoz be kell jelentkezni
Ahh, ott nem feltetlen 65535. Intte konvertalhat a szorzas, ami jelen esetben nem feltetlen nagyobb, mint 16 bit.
----------------------
while (!sleep) sheep++;
- A hozzászóláshoz be kell jelentkezni
8bitesen 2 bájtos az int...
- A hozzászóláshoz be kell jelentkezni
es mikrokontrollertol, illetve a fejleszto kornyezettol fugg ott (lasd PIC szeriak eleje)
- A hozzászóláshoz be kell jelentkezni
hozza akartam ezt irni, de megtetted helyettem:)koszi
- A hozzászóláshoz be kell jelentkezni
Nah igen, en is csak felkaptam a fejemet egy pillanatra;)
Nem effektive hozzad, de a temahoz tartozik es a kerdezonek:
- nezd meg mind a mikrokontroller, mind a fordito adatlapjat/doksijat, hogy milyen szo hosszt hasznal mihez.
- A hozzászóláshoz be kell jelentkezni
Hát a 8 bites mikrovezérlő és C fordítóiról megban a véleményem. Hirdeti magáról a fordító, hogy ANSI C kompatibilis, ennek ellenére már az első órában sikerült írnom egy ANSI C kifejezést, amit nem tudott lefordítani.
Egyszóval több 8 bites mikrovezérlő fordító nem teljesíti maradéktalanul még a legalapabbnak számító ANSI C szabványt sem, bár azt állítja a gyártója, hogy ANSI C-t tudja.
- A hozzászóláshoz be kell jelentkezni
én elgondolkoznék a kompatibilitás szó jelentésén
- A hozzászóláshoz be kell jelentkezni
Az eredmény uint32-re castolódik, tehát nincs gáz.
0x0100*0x0100=0x1_0000.
Ez uint16 esetén 0x0000-ra csonkolódna, de uint32 esetén 0x0001_0000 lesz. (Az '_' csak ezreselválasztó jelölés.)
- A hozzászóláshoz be kell jelentkezni
Bar tenyleg regen programoztam C-ben, de nekem ugy remlik, hogy signed int-te konvertalodik a szorzas eredmenye elso korben.
----------------------
while (!sleep) sheep++;
- A hozzászóláshoz be kell jelentkezni
jelen esetben mindegy.
- A hozzászóláshoz be kell jelentkezni
A kovetkezo tortenik amennyiben int szelessege kisebb mint 16 bit.
1. a es b int -re promotalodik.
2. a gep elvegzi a szorzast int ertekekkel
3. c erteket kap azaz az int eredmeny implicit typecast alltal 32 bitesre konvertalodik.
Azaz a 8 bite procinal fuggetlenul attol, hogy az int 16 vagy 8 bites, 16 biten vegzi el a muveletet. Ergo c erteke vaskos 0 -a lesz.
helyesen:
uint32_t c=(uint32_t)a * (uint32_t)b;
Ilyenkor 32 biten szamol.
- A hozzászóláshoz be kell jelentkezni
mivel nem irta le kezdetektol fogva, hogy 8bites proci, ezert mindenki 32 bitesre asszocialt. Occam borotvaja, ugye.
- A hozzászóláshoz be kell jelentkezni
ha atmel akkor bizony 0 (feltéve ha nem 32 bitest használsz)
sajnos szomorú tapasztalat. uint32_t már nem kezeli le tisztességesen.
- A hozzászóláshoz be kell jelentkezni
dehogynem, csak kasztolni kell bőszen, mert uint16_t az int (vagy int16_t)?
A kérdésre a válasz: sajnos attól függ, hogy az architektúrán/fordítóban mi az int (ami a c-nél a default típus).
- A hozzászóláshoz be kell jelentkezni
Ja, abban az esetben, ha az int legalabb 32 bites. Mert ugye integer promotion tortenik a szorzasnal.
- A hozzászóláshoz be kell jelentkezni
Es mint a kódból láthatjuk, igen, 32b-es változó.
- A hozzászóláshoz be kell jelentkezni
Nem a valtozo szelessege erdekes, hanem a sizeof(int) eredmenye, azaz a proci szo szelessege.
- A hozzászóláshoz be kell jelentkezni
Mikrokontrollereken (és nagyon régi cpu-kon) kivűl van olyan aminek kevesebb a szószélessége mint 32-bit?
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.
- A hozzászóláshoz be kell jelentkezni
DSP-n, CPLD-n és FPGA-n, illetve csak 16:53kor írta le, hogy nem csak 32biten, hanem 8bites uC-n is kérdés az aritmetika.
- A hozzászóláshoz be kell jelentkezni
Igaz. Bár fpga-n, és cpld-n (lehet hülye kérdés) a szóhosszúságot nem programozó deklarálja?
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.
- A hozzászóláshoz be kell jelentkezni
nem hülye a kérdés, és igen. Illetve megszorítás a cuccban levő összeadó, szorzó méretei.
- A hozzászóláshoz be kell jelentkezni
reméljük:)
- A hozzászóláshoz be kell jelentkezni
Akkor talán keressük meg a helyes választ.
Először is, az
uint16_t
és az
uint32_t
opcionálisan típusok, egy C99 implementációnak nem kötelező támogatnia ezeket. (ISO C99 7.18.1.1 Exact-width integer types.) Ha azonban egy implementáción léteznek ezek a típusok, akkor kötelező nekije ezeken a
typedef
-eken is elérhetővé tennie.
Ezután vesézzük ki a szorzást (ISO C99 6.5.5 Multiplicative operators). Először is, a két operanduson végrehajtjuk a usual arithmetic conversion-öket, amelyeknek a legelső lépése jelen esetben a default integer promotions mindkét operanduson. (Lásd 6.3.1.8 Usual arithmetic conversions, valamint 6.3.1.1 Boolean, characters, and integers, 2. bekezdés.)
Ha az
int
olyan, hogy tudja ábrázolni a teljes
uint16_t
értékkészletet, akkor mind
a
, mind
b
int
-re konvertálódik (mindegyik ugyanonnan indul,
uint16_t
-ről). Egyébként pedig mindkettő
unsigned int
-re. Az
unsigned int
típus minimális maximuma 65535 (ISO C99 5.2.4.2.1 Sizes of integer types
<limits.h>
), tehát az feltétlenül tudja ábrázolni az
uint16_t
teljes értékkészletét; ha azonban az
int
-is képes erre (ami platformfüggő), akkor
int
-re megyünk.
Az
uint16_t
konverziós rangja megegyezhet az
int
-ével, megegyezhet a
short
-éval, megegyezhet a
char
-éval, illetve takarhat egy extended unsigned integer típust valahol az
int
rangja alatt, azonban mind a négy esetben (az előző bekezdés szerint)
int
-re vagy
unsigned int
-re "lép elő" mind
a
, mind
b
. Az
uint16_t
nem lehet magasabb rangú az
unsigned int
-nél, mert ahhoz vagy
long
rangúnak kellene lennie (amit az értékkészlete nem tesz lehetővé), vagy az
unsigned int
-nél szélesebb extended típusnak kellene lennie, amit ismét a tartománya nem tesz lehetővé.
Mivel így két azonos típusú operandusunk van (vagy
int
mindkettő, vagy
unsigned int
-- jelöljük ezt a promotált típust most
T
-vel), azért a usual arithmetic conversion-ök mást nem írnak most elő, végrehajtjuk a szorzást.
Ha a szorzás eredménye
T
típusban ábrázolható (figyelem! itt még nincs szó konverzióról, csak arról, hogy maga az eredmény előállítható-e a
T
típusban!), akkor minden rendben van.
Ha nem, akkor már számít, hogy
T
(= a promóció eredménye)
signed int
vagy
unsigned int
lett-e. Ha az utóbbi, akkor semmi gond; a matematikai szorzatot modulo
(UINT_MAX+1)
redukáljuk. Ha
T
signed int
volt, akkor sajnos a túlcsordulás nem definiált, vége a dalnak, innentől bármi megengedett az implementáció számára. (ISO C99 6.2.5 Types, 9. bekezdés, illetve 6.5 Expressions, 5. bekezdés.)
Tegyük fel, hogy megvan az eredmény (
T
típusban, ami
int
vagy
unsigned int
a fentiek szerint). Ezt az értéket az értékadás során konvertáljuk
uint32_t
-re. (ISO C99 6.5.16.1 Simple assignment, 2. bekezdés) Mivel az
uint32_t
előjel nélküli típus, azért a túlcsordulás pontosan definiált.
(Figyelem! Ez a modulo
(UINT_MAX+1)
redukció nem ugyanaz, mint a fenti! A vonatkozó rész itt a 6.3.1.3 Signed and unsigned integers, 2. bekezdés. A fentebbi esetben egy szorzás (matematikai művelet) kiértékelése során az a kérdés kerül elő, hogy az eredmény egyáltalán előállítható-e az adott típusban. Túlcsordulás esetén előjel nélküli típusnál redukció, előjelesnél definiálatlan a viselkedés. Itt viszont egy meglévő értéket konvertálunk másik típusra. Túlcsordulás esetén előjel nélküli céltípusnál ugyanolyan a redukció, mint előbb, azonban előjelesnél sem definiálatlan a viselkedés, hanem vagy implementáció által definiált (= kötelezően dokumentálandó) a numerikus végeredmény, vagy egy impl.def. (= kötelezően dokumentálandó) szignál generálódik.)
Két gyakori kiosztást megnézve (padding biteket mindenhol kizárom, és kettes komplemenst tételezek fel a negatív ábrázoláshoz):
- 8 bites
char
, 16 bites
short
, 32 bites
int
: a promóció
signed int
-re történik. Ha a szorzat nem ábrázolható, akkor undefined behavior. Ez a legtöbb platformon azt eredményezi, hogy a kilógó biteket levágjuk, ami marad, az pedig kettes komplemens ábrázolás szerint lehet negatív is (a sign bit függvényében). Ez történik pl. x86(_64) GNU/Linux-on. A topiknyitóban megadott értékekkel természetesen nincs túlcsordulás, az eredmény 0x10000.
- 8 bites
char
, akárhány bites
short
, 16 bites
int
: az előléptetés nem látszik szükségesnek (az
uint16_t
az
unsigned int
typedef
-je), de ha a platform beteg volna, és valamilyen extended típust használna
uint16_t
-re, akkor a promóció
unsigned int
-re történik. (6.3.1.1 Boolean, characters, and integers, 1. bekezdés.) A szorzás definiált, eredménye nulla.
- 16-nál kevesebb bit az
int
-ben. Ez nem C99-konform platform.
Aki ezt nem tudja fejből, vagy nem tudja megnézni a szabványban (vagy egy ahhoz nagyon közeli draft-ban), az nagyon óvatosan írjon C programot, mert tele lesz undefined (de minimum implementation defined) behavior-rel. Vagy legalábbis szigorúan ragaszkodjon egy adott platformhoz (hardvert és fordítót beleértve).
- A hozzászóláshoz be kell jelentkezni
Vagy használjon lintet. (Ami elvileg pont az ilyen gusztustalan platformfüggő dolgok észrevételéért vol felelős.) De gondolom ma a GCC / CLang+LLVM / mimás? is rendelkezik olyan opcióval, ami ilyen lint-szerű működést eredményez.
- A hozzászóláshoz be kell jelentkezni
vuuáááuuuu. grat. szép okfejtés.
- A hozzászóláshoz be kell jelentkezni
Köszi! Szép munka!
- A hozzászóláshoz be kell jelentkezni
Kimerítő volt :)
Nem értem, miért kell egy 8 bites mikrokontrollert c-ben programozni.... Tipikus gépi kódú feleadat.
Máshogy elveszel a szabványok, túlcsordulás és hasonlók között.
---
Repeat after me: I Will Use Google Before Asking Stupid Questions...
- A hozzászóláshoz be kell jelentkezni
A produktivitás miatt. Meg nem lehet minden mikrovezérlő assemblyjét fejben tartani.
De milyen már az, hogy valaki össze akar szorozni két számot, az ábrázolási tartományokba a tényezők is beférnek, és a szorzat is belefér, de az eredmény mégsem lesz megfelelő: én elvárom a XXI. században, hogy egy szorzás eredménye vagy rendesen álljon elő, vagy OverFlowException keletkezzen.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
jávás vagy, ugye?
- A hozzászóláshoz be kell jelentkezni
le se tagadhatna :)
- A hozzászóláshoz be kell jelentkezni
Nem biztos, hogy baj az; feladathoz eszközt :)
Egyébként:
De milyen már az, hogy valaki össze akar szorozni két számot, az ábrázolási tartományokba a tényezők is beférnek, és a szorzat is belefér, de az eredmény mégsem lesz megfelelő
Hát ez az: a platformtól függően a szorzat nem biztos, hogy belefér. A Java ilyenkor kivételt dob (vagy használsz BigInteger-t). A C viszont azt mondja:
- Trust the programmer.
- Don't prevent the programmer from doing what needs to be done.
- Keep the language small and simple.
- Provide only one way to do an operation.
- Make it fast, even if it is not guaranteed to be portable.
A fordító úgy áll hozzá a programodhoz, hogy te tudod, mit csinálsz :)
- A hozzászóláshoz be kell jelentkezni
feladathoz eszközt, na de ne rosszat :-)
És igen, a program azt csinálja amit én akarok, ne azt amit gondolok :-)
Ha nem azt csinálja, az az én hibám, nem a programé.
"Felelős vagy a rózsádért."
- A hozzászóláshoz be kell jelentkezni
A Java sima integer aritmetika túlcsordulásra nem dob exception-t, hanem úgy működik, mint C-ben - a tetejét az eredménynek levágja. 0-val osztásra ad csak axception-t. Integer aritmetikára a processzor utasításait használja. Ráadásul elégé hatékony kódot csinál a JIT compilere. Ha integer utasításokat kell ciklusban végrehajtani, arra kb olyan jó, mint a C nyelv maga.
Abból, hogy a C platformfüggően értelmezi a leírt programkódot semmilyen teljesítmény nyereség nem származik, hanem csak rengeteg hiba.
- A hozzászóláshoz be kell jelentkezni
A C-ben pont az a lenyeg, hogy nem gondolkozik helyetted. Igy nem pakolja tele a forditott kodot mindenfele szemettel, es lehet benne hatekonyan mukodo programot irni. (Cserebe ismerni kell rendesen a nyelvet es az adott platformot.) A C-re szeretek ugy gondolni mint egy hordozhato assembly-re, mert kb. az is.
- A hozzászóláshoz be kell jelentkezni
" A C-re szeretek ugy gondolni mint egy hordozhato assembly-re, mert kb. az is."
Nemcsak kb. :) A C a hordozhato assembly, az eredete szerint is.
- A hozzászóláshoz be kell jelentkezni
Azert mondom, hogy csak kb., mert azert lenyegesen kenyelmesebb, viszont kevesebb szabadsagot ad.
- A hozzászóláshoz be kell jelentkezni
Nem, C#-os. És szeretem azt, hogy a feladatra koncentrálhatok, nem az eszközre.
Engem azért fizetnek, hogy megoldjak egy feladatot határidőre, és nem azért, hogy a nyelvvel szopjak.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Valakinek a C# futtatokornyezetet is meg kellett irnia. O szopott helyetted is :) + van ahol eleve nem jarhato ut a C# meg az akarmi mas, mert nem elerheto az adott platformra vagy a kod sebessege a fontos.
- A hozzászóláshoz be kell jelentkezni
+1
Valahol volt topicban, hogy EJB3 izével akart lekérdezni ütemezve plc-ket. Most csak azért felrakni egy glassfisht, hogy egy cronjobot emuláljon? JavaEE-ben Singletonnal szopni, hogy a serialport kezelés ne akadjon össze?
Hova jutott ez a világ...
- A hozzászóláshoz be kell jelentkezni
"Valakinek a C# futtatokornyezetet is meg kellett irnia." -- Éljen soká, aki bevállalta :-) Viszont ezzel megspórolt pár ezer mérnökórát a többi programozónak.
"van ahol eleve nem jarhato ut a C#" -- természetesen, a C#/Java/Python/PHP/sh sem csodaszer. De ahol választhatok, ott a legmagasabb absztrakciós szintet fogom választani (feltéve, hogy a futási sebesség és a fogyasztás kevésbé szempont). Mikrovezérlőn én is C-znék vagy C++-oznék. Ha van operációs rendszerem, és azon elmegy a keretrendszerem, akkor azt fogom választani. Miért írjak újra egy kódot, amit előttem valaki már megírt, és ami sokkal fontosabb: letesztelt.
De azt nekem senki se mondja, hogy a C kód fent említett viselkedése normális. Kevés kivételtől eltenintve mindenki azt várná, hogy az eredmény 0x0001_0000.A józan ész ezt doktálja.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Beszéltem mindenkivel, és elmagyaráztam neki, hogy elég logikus, hogy két uint16_t szorzata is uint16_t legyen, ha nem ezt akarjuk, akkor még a szorzás előtt kell elvégezni a típusátalakítást.
- A hozzászóláshoz be kell jelentkezni
+1
Ha két almát berakok egy ládába, akkor elvárom, hogy a ládában is alma maradjon, a belerakás után is.
- A hozzászóláshoz be kell jelentkezni
+1
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
Ezek szerint én vagyok az egyetlen, aki mindig jól akarja elvégezni a szorzást.
Mindig eredményt akarok, és mindig helyes eredményt akarok.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Nem, de azért általában az ember tudja, hogy mit mivel akar szorozni.
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
és milyen doménen.
- A hozzászóláshoz be kell jelentkezni
"És szeretem azt, hogy a feladatra koncentrálhatok, nem az eszközre."
Ezt hívják tipikus OOP hozzáállásnak. a nyelv nyalja ki a seggem, amit nem tud megcsinálni ara szükség sincs, problémával akarok foglalkozni nem a nyelvvel szopni...bezzeg amikor Linq-ben nem tudnak valamit megcsinálni, hozzám jönnek sírni. Az nem a nyelvvel szopás? Vagy más thread-ből UI-t basztatni. "Minek az a DispatcherObject? hámérnem oldja meg a háttérben? deszarez!". Jellemző...
- A hozzászóláshoz be kell jelentkezni
"bezzeg amikor Linq-ben nem tudnak valamit megcsinálni" -- A LINQ használata és két szám összeszorzása között van egy kis különbség: az előbbi nem kötelező, az utóbbit viszont elég nehéz mással pótolni.
"Vagy más thread-ből UI-t basztatni." -- csakhogy erről tudunk. De a 256 × 256 = 0 dolog viszont azért került elő, mert a topiknyotó nem tudott mit kezdeni a jelenséggel.
Egy jóérzésű fordító legalább egy warningot dobhatott volna.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
viszont lehet, hogy pont ezt a viselkedest varod el.
- A hozzászóláshoz be kell jelentkezni
Szerintem meg nincs különbség. Aki az elsőrendű logikát nem érti, az ne akarjon összeadni se, mikroprocesszoron.
Miről tudunk? Odajön/levelet ír/felhív skypeon és megosztja a desktopját/odahív(!!!), hogy ez elszáll. De oda is van írva az exceptionbe, hogy invocation on another thread (vagymi).
És ha én implicit modulo-t akarok a szorzásomhoz? mennyivel hatékonyabb már az (u8)256 * (u8)256 mint a ((u32)256*(u32)256)%256? Na?
- A hozzászóláshoz be kell jelentkezni
"Szerintem meg nincs különbség. Aki az elsőrendű logikát nem érti, az ne akarjon összeadni se, mikroprocesszoron." -- ügyesen lehülyézted az olvasók felét.
"De oda is van írva az exceptionbe, hogy invocation on another thread (vagymi)." -- de legalább oda van írva, hogy hol keresd a hibát. A topiknyitónak még ennyi támpontja sem volt.
"És ha én implicit modulo-t akarok a szorzásomhoz? mennyivel hatékonyabb már az (u8)256 * (u8)256 mint a ((u32)256*(u32)256)%256? Na?" -- lehet csinálni olyan processzort, ahol az utóbbi kifejezés 1 órajel, az első meg 100. Na és? Mit bizonyít ez? Mert a C nyelvi kifejezés és annak futási ideje között semmiféle összefüggés nincsen.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
" lehet csinálni olyan processzort, ahol az utóbbi kifejezés 1 órajel, az első meg 100. Na és? Mit bizonyít ez? Mert a C nyelvi kifejezés és annak futási ideje között semmiféle összefüggés nincsen."
De van, ha tudod, hogy az egyik kifejezesbol gyorsabb kod lesz arra a procira amire dolgozol. Persz, oldjon meg mindent a fordito... :D (es maris fel ora lesz egy par soros program forditasa, a fordito fejlesztesi koltsege meg az Apollo programeval fog vetekedni)
- A hozzászóláshoz be kell jelentkezni
"De van, ha tudod, hogy az egyik kifejezesbol gyorsabb kod lesz arra a procira amire dolgozol." -- akkor máris nem "hardverfüggetlen assembly" :-)
Azért vagyik nyűgös a túlcsordulások nem jelzése miatt (elfogadom azt is, ha bevallja a kütyü, hogy nem tudja megcsinálni), mert egyszer implementáltam egy Viterbi-algoritmust, ami ugye egy hibajavító megoldás. Szépen működött is, ki is javította a hibák nagy részét. Csakhogy (mert a gyanúm utólag bebizonyosodott) időnként túlcsordult a változóm, emiatt pedig nem javított ki olyan hibákat, amelyket 1 napi debugolás és kódhegesztés után már igen. És mivel elvileg sem volt lehetőségem a túlcsordulásokat figyelni (a C kitalálói nem adnak nyelvi elemet a Carry bit figyelésére -- hardverfüggetlen módon legalábbis nem: a kód PC-n készült, de ARM Cortex-M3-on futott végül [akkoriban még az volt a csúcstechnológia]), eléggé trükkös módon kellett megoldanom a problémát. Persze megoldottam, és örült a lelkem.
Mindenesetre a hosszúra sikerült beszélgetésünkből világosan látszik, hogy más-más iskola tanait hirdetjük. Neked hardverközpontúbb a gondolkodásod, nekem meg eredményközpontúbb (az én matematikám szerint a 256×256 = 0 teljesen hibás eredmény). Nem vagyunk egyformák. Még jó, kicsit egysíkú lenne a világ.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
"hardverfüggetlen assembly"
Pont ezert engedhetoek meg az ilyen kulonbsegek. Lehet benne sok odafigyelessel hordozhato kodot irni, de ugyanakkor ki lehet hasznalni a hw specifikus dolgokat is.
- A hozzászóláshoz be kell jelentkezni
Köszi a bókot. De a burkolt reductio ad hitlerumot észrevettem ám.
A HOL nincs oda irva az uzenetbe, csak az, hogy "másik threadbe akartál belehívni, ezért a szoptálcetli ma a tiéd". a hol az a stack traceben van benne, és ugye release kódban nincs debug info (ugye?), igy nincs sorszámod a stack trace-ben. Ugye. Ja, majd csinálj egy mikrofelmérést, hogy tudják-e az emberek, hogy mik vannak az Exception osztályban a Message-n kívül, meg fogsz lepődni.
Lehetne, de a mai processzorok az előbbit részesítik előnyben :-)
- A hozzászóláshoz be kell jelentkezni
És szeretem azt, hogy a feladatra koncentrálhatok, nem az eszközre. Engem azért fizetnek, hogy megoldjak egy feladatot határidőre, és nem azért, hogy a nyelvvel szopjak.
Teljesen jogos. Felesleges C-hez nyúlni, ha nem elkerülhetetlen.
- A hozzászóláshoz be kell jelentkezni
Igen, köztudott, hogy a C az egyetlen nyelv, ahol az aritmetikai műveletek túlcsordulhatnak ;)
- A hozzászóláshoz be kell jelentkezni
Nyilván :)
- A hozzászóláshoz be kell jelentkezni
Igen, köztudott, hogy a C az egyetlen nyelv, ahol az aritmetikai műveletek túlcsordulhatnak ;)
Most mellékes, hogy hány nyelvben csordulhatnak még túl, és hogy hogyan.
Az a fontos, hogy a nyelv saját fogalmai és a feladattér ("domain") fogalmai között mekkora a különbség. Ha nincs nyomós ellenérvünk, akkor olyan nyelvet érdemes választani, amely a feladattérhez a lehető legközelebb van (DSL, vagy kényelmes/biztonságos általános nyelv). A C valóban borotvaéles és gyakran igen kevéssé intuitív, ebben a tekintetben azonban csak egy példának szántam.
De azt nekem senki se mondja, hogy a C kód fent említett viselkedése normális. Kevés kivételtől eltenintve mindenki azt várná, hogy az eredmény 0x0001_0000.A józan ész ezt diktálja.
Ezzel mindenesetre értek egyet. A C a saját alkalmazási területén közel tökéletes. Ha az eredmény pontos ábrázolása elsődleges, akkor viszont olyan nyelvet kell választani, ami ezt helyből akarja (nemcsak "tudja"), vagy megfelelő függvény-/osztálykönyvtárat kell használni (C-ben, C++-ban, Java-ban stb).
Én például többnyire kerülöm a C++-t. Nagyon is valós gyakorlati hátrányai vannak, a programozása közben pedig iszonyatos mennyiségű buktatóra kell figyelni. Minden, ami a C-ben macerás, közel ugyanolyan macerás C++-ban is, de bejön még rengeteg új fogalom (többsége automatizmus, ami a "háttérben" zajlik: kivételkezelés, virtuális metódusok, különösen többszörös öröklésnél rejtett mutató-machináció, destruktorok, template-ek), emellett a stílus fontossága minimum egy nagyságrenddel nagyobb. Nincs továbbá semmilyen műszaki szabvány, amely a C++-t mondjuk a UNIX rendszerprogramozással ötvözné, ennek ellenére minden szépreményű C++ programozó azzal kezdi, hogy ír egy C++ IO/threading library-t, kivételekkel, örökléssel, wrapper class-okkal, aztán csak néz, hogy hányféleképpen tud fejreállni.
A C++-nak sokkal nagyobb a kifejezőereje, ezért sokkal nehezebb is rendesen használni. Nagyobb nyelvi odafigyelést igényel, a stílus/tervezés (mint említettem) kritikus -- sokkal inkább "mit ne használjunk", mint "mit használjunk" --, rengeteg plusz fogalmat kell bebiflázni (vagy folyton megnézni) a szabványban. Akik dobálózni szoktak a C++ programozásával, azok többnyire nem ismerik a szabványt.
- A hozzászóláshoz be kell jelentkezni
(Nem tudok mit mondani a C++-ról, nem ismerem, de valószínűleg nagyon jó valamire az is.)
- A hozzászóláshoz be kell jelentkezni
En pl. pont a hatterben torteno dolgok miatt nem szeretem a C++-t. Ugyan olyan kenyelmetlen mint a C, de ugyan ugy nem tudod mi lesz a kododbol mint egy magasabb szintu nyelvnel. (Mondom ezt ugy, hogy egyebkent a C a kedvenc nyelvem.)
- A hozzászóláshoz be kell jelentkezni
Mondjuk azért C#-al példálózni mikrokontrolleres környezetben... na, az is megér néhány InvalidArgumentException-t.
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
Nono, .NET Micro Framework nagyon nyomul ilyenekre is... (konkrétan nálunk a tanszéken vannak ilyen témák, hogy portolni adott MCU-ra...). Java dettó (ott meg a JOP érdekes projekt).
Más kérdés, hogy számomra is meglepő volt. Meg furcsa. Meg berzenkedem tőle. De van.
- A hozzászóláshoz be kell jelentkezni
Igen, tudom, hogy van .NET MF, de amennyire néztem, hw igénye számomra nagyobbnak tűnt, mint amit egy átlag mikrocontrollernek gondolnék. Igaz, nem túlzottan értek hozzájuk, szóval... :)
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
Meg nem lehet minden mikrovezérlő assemblyjét fejben tartani.
Te ugye életedben nem írtál még valódi programot assemblyben?
- A hozzászóláshoz be kell jelentkezni
Sosem. Nem programoztam 1995 és 1997 között assemblyben, nem kezdtem el egy operációs rendszert írni és nem írtam egy (csúnya, de működő) grafikus felületet sem.
Sosem láttam még assemblyt. És C-t sem. C++ meg aztán végképp nem.
Fogalmam sincs, hogy mikor számít a kód hatákonysága, és mikor a programozó produktivitása.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
lehet mikrovezerlot .net-ben is programozni, csak nem minden feladathoz lesz megfelelo
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Nagyon szép összefoglalás.
Egyébként javaslom a MISRA-C szabályok tanulmányozását a topicindítónak, sokat segíthet, elvben az ilyen huncutabb dolgok elkerülésére kiváló.
- A hozzászóláshoz be kell jelentkezni
Ugyanennek (vagyis a túl későn végzett típus-váltásnak) egy változata:
rossz:
int a= 1;
int b= 2;
double d= a/b;
jó:
int a= 1;
int b= 2;
double d= (double)a/b;
- A hozzászóláshoz be kell jelentkezni
kedvenc kérdéstípusom tesztekben :)
- A hozzászóláshoz be kell jelentkezni
az erjedt gyumolcsnek is van jo vegeredmenye
---
Egy jól megállapított probléma félig megoldott probléma.
- Charles Kettering
- A hozzászóláshoz be kell jelentkezni
A C fordító a fenti példa esetén egyébként a C-s logika szerint rendben dolgozik:
32 bit = 16 bit * 16 bit
ami valójában
32 bit = (32 bitre kasztol az eredményregiszter miatt) (16 bit * 16 bit)
Tehát ez a fenti 0x100-as értékek esetén 0-át hozza eredményül.
Ha bármelyik operandus 32 bites, akkor
32 bit = 32 bit * (32 bitre kasztol)16 bit
Ezt úgy is elérheted, ha
c = (uint32_t)a * b;
Azaz csak az "a" 32 bitesre való átalakítása már 32 bites aritmetikába rántja a "b" operandust is.
És hogy miért így csinálja? Mert így gyors, hiszen csak egyszer kasztolt 32 bitre, az aritmetika viszont 16 bites maradt. Ha a 16 bites aritmetikával való gyors számolásról a programozó látja, hogy nem fog elférni 16 biten, akkor a programozónak kell figyelmeztetnie a C fordítót, hogy 32 bites aritmetikával dolgozzon végig és ne csak a végén egyszer konvertáljon.
A C ezért nehéz nyelv. Semmi automatizmus, semmi plusz vizsgálat. A programozó amit leír, az hajtódik végre. Ellenben GYORSAN!
- A hozzászóláshoz be kell jelentkezni