Strana 1 z 3

Programovanie ccs C

Napísané: 16 Júl 2019, 09:47
od používateľa niki31
Chcem sa spýtať skúsenejších programátorov na jednu vec, ohľadne porovnávania dvoch premenných. V ccs C som narazil na takýto problém. Ak vytvorím podmienku kde sa porovnávajú dve premenné, jedna je znamienková a druhá neznamienková, výsledok porovnania je chybný. Pri porovnaní dvoch čísiel napr. 5 > 2 je výsledok false. Je toto normálne aj v iných kompilátoroch alebo to je nejaký kix? Chápem že záporne číslo by bolo vyhodnotené ako väčšie lebo má nastavený znamienkový bit ale dve kladné čísla ? V žiadnej učebnici ani v manuáli kompilátora sa o tom nič nepíše.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 12:39
od používateľa peterple
veľmi divné. Až priam štandartu odporujúce. Ten hovorí že v prípade že sa porovnáva signed a unsigned tak sa signed pretypuje na unsigned. Takže 5>2 musí platiť za každých okolností.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 13:11
od používateľa maskrtnik01
tak sa signed pretypuje na unsigned
A čo to spraví so znamienkom? Povedzme -5 > 2?

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 14:27
od používateľa niki31
No je to divné, doteraz som sa stým nikde nestretol.
Vždy sa porovnávalo bez ohľadu na typ premennej a fungovalo to. V c to nefunguje a hľadať furt takéto chyby, to je zážitok.
Už som si aj začal písať zoznam podobných vecí, lebo ich je tam viac.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 15:55
od používateľa peterple
Niki: tým som chcel povedať že 5>2 by malo platiť aj v tvojom kompilátore. To že sa ti zdá že to neplatí znamená že si niečo prehliadol.

maskrtnik:
so znamienkom to neurobí nič. pretypovanie nič nemení len hovorí kompilátoru že pre túto chvíľu sa na tento kus pamäte pozeraj ako na celé číslo bez znamienka. To znamená že ak tam bude číslo -5 tak sa mu to bude zdať ako UINT_MAX-5+1

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 16:15
od používateľa maskrtnik01
Toto som chcel vedieť. Či to vynuluje, obráti polaritu na kladnú......alebo to znamienko proste zoberie ako MSB uint-u.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 16:17
od používateľa niki31
Laboroval som s tým dva dni a nepodarilo sa mi zistiť prečo to robí. Nakoniec som musel v celom programe pomeniť typy premenných na unsigned.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 16:39
od používateľa peterple
V takýchto prípadoch kuknem na vygenerovaný asm a zvyčajne mám o chvíľu jasno.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 17:12
od používateľa niki31
To je sice pravda ale nič to na veci nemení. Je nemysliteľné laborovať s každou blbosťou pol dňa a zvlášť, ak sa v programe nachádza tisíckrát.
Skôr by ma zaujímalo či to nejde nejako prenastaviť alebo čo.

Re: Programovanie ccs C

Napísané: 16 Júl 2019, 17:16
od používateľa maskrtnik01
peterple napísal:V takýchto prípadoch kuknem na vygenerovaný asm a zvyčajne mám o chvíľu jasno.
Ak asm rozumiete - nie každý to vie čítať a chápať.

Re: Programovanie ccs C

Napísané: 17 Júl 2019, 21:49
od používateľa peterple
Čo chceš prenastaviť? Normu ako pracujú kompilátory? Stále nejak moc neverím že ten test 5>2 bol false. Inak dnes každý slušný kompiler na takú konštrukciu hodí varovanie. A keď som s C začal tak som rýchlo zistil že varovania sa nevyplatí brať na ľahkú váhu. Keď sa niekomu C nepáči, tak tu má dnes mraky jazykov kde je cestička umetená. Java má všetko signed. Javascript má double, a tak podobne. Ale vždy je niečo za niečo. Za bezstarostný život sa platí. Cckar navyše píšuci pre MCU by mal vedieť ako a prečo to vo vnútri tak funguje.

Re: Programovanie ccs C

Napísané: 18 Júl 2019, 09:23
od používateľa pocitujlasku
maskrtnik: ak niekto programuje mcu v C, tak sa poklada za normalne, ze vie aspon trocha asm, lebo potom vie co sa deje vnutri

Re: Programovanie ccs C

Napísané: 18 Júl 2019, 09:50
od používateľa Andy99
Uz dlhsie sledujem tuto temu a neda mi to. Chapem, ze vysledok moze byt rozdielny ci uz vzavislosti od pouzitych typov premennych alebo aj nastavenia kompilatora. Ale zaujimalo by ma, ci by si nemohol ukazat cast toho kodu, ktora robi spominane problemy. S tym, ze tam bude vidiet definicia, inicializacia, pouzitie ako aj porovnanie danych premennych. :thumbup:

Re: Programovanie ccs C

Napísané: 18 Júl 2019, 11:05
od používateľa maskrtnik01
pocitujlasku napísal:maskrtnik: ak niekto programuje mcu v C, tak sa poklada za normalne, ze vie aspon trocha asm, lebo potom vie co sa deje vnutri
Tak aritmetiku od skoku ešte rozoznám. Ale čo arduinisti napríklad? Pre nich je PORTB |= (1 << 4) cryptotext.

Re: Programovanie ccs C

Napísané: 18 Júl 2019, 11:45
od používateľa pocitujlasku
Presne na to narazam. Arduino sam dost intenzivne vyuzivam lebo nemam casu navyse a podstatne mi to ulahcuje ked robim rozne blbosti domov. Ale oni skoncili, ked napr. nalepia viac kniznic, pricom niektore z nich pouzivaju rovnake prerusenie, alebo port a program zrazu nefunguje ako ma. Ja si to vtedy viem fixnut, lebo poznam strukturu atmelu, co-to som uz robil jak v asm, tak C.
Je to podobne, ako ked niekto, kto vie poskladat PC sa vyhlasi za odbornika. Ale netusi, ze existuje nejaky bios/uefi, netusi, ze sa tam riesia nejake IRQ (schvalne, komu tato skratka este nieco povie), nevie ako komunikuju spolu zariadenia, nevie nastavit frekvenciu pamate, nasobic... Ja mam za sebou niekolko stovak poskladanych pc, zacinal som v dobe win98, w2k, kde sa este obcas co-to muselo nastavovat rucne, takze mam prehlad aj o tom, ako funguje vnutri pocitac.
Ked sa tak nad tym zamyslim, ja cokolvek som skusal, tak vzdy som skoncil na tom, ze som po nociach studoval ako to vlastne funguje, a na zaklade toho mi bolo hned jasne na co si dat pozor a kde su pripadne obmedzenia.

Re: Programovanie ccs C

Napísané: 18 Júl 2019, 18:10
od používateľa niki31
Po veľkom hľadaní na nete som zistil, že C všeobecne nevie porovnávať signed a unsigned. Rozoberali to už na viacerých fórach. Celkom názorne to je popísané na stackoverflow.

https://stackoverflow.com/questions/208 ... d-integers

Predtým som to nemohol nájsť lebo som nevedel ako problém správne pomenovať. Ja programujem 99% vecí v assembleri, takže nemám problém to obísť alebo vyriešiť inak. Samozrejme sa to dá v C riešiť pretypovaním a pod. ale o to nejde. Je skrátka zarážajúce že v manuáloch sa o tom striktne mlčí. Predsa je absurdné aby sa programátor škrabal poza uši po nociach, pri obyčajnom elementárnom porovnávaní. Od toho sú predsa manuály, príručky a učebnice, nie?
Keby som vopred o tomto probléme vedel, mohol som si ušetriť fúru času.

Re: Programovanie ccs C

Napísané: 18 Júl 2019, 18:24
od používateľa martin knocik
V manualoch sa o tom nemlci. ak si precitas knihu Ucebnica jazyka C od Herouta, tak tam najdes celu kapitolu venovanu konverzii datovych typov. a implicitn0mu (skrytemu, automatickemu) pretypovaniu.

Problemom je rôzne správanie rôznych kompilatorov. GCC pre velke x86 pri operacia signed s unsigned skor pretypuje na vasi datovy typ, kompilator od Texas Instruments v COde composeri śetrí pamat a vysledkom su casto pretecenia. (ten vypise len warningy).
Predsa je absurdné aby sa programátor škrabal poza uši po nociach, pri obyčajnom elementárnom porovnávaní. Od toho sú predsa manuály, príručky a učebnice, nie?
Keby som vopred o tomto probléme vedel, mohol som si ušetriť fúru času.
Popis práce programátora :) Tiež som sa s tým natrápil ked som na problem s prototypovaním narazil prvý krát.

Re: Programovanie ccs C

Napísané: 24 Aug 2019, 14:10
od používateľa niki31
Samotné pretypovávanie samozrejme všetci chápeme, kedy je potreba atd... . No nikde nieje ani zmienka že treba pretypovávať pri porovnávaní, ani v učebnici od Herouta. Ja osobne som bol v domnení že tieto základné veci sa robia implicitne. Ďalšia zaujímavá vec na ktorú som narazil je napr. násobenie troch a viac premenných. Keď sa násobia dve premenné dôjde implicitne k pretypovaniu, pri násobení troch premených je už výsledok nezmysel aj keď má výsledná premenná dostatočnú veľkosť.

Napr:
unsigned int8 a = 100;
unsigned int8 b = 100;
unsigned int8 c = 100;
unsigned int32 vysledok;

vysledok = a * b; vysledok je spravny
ale
vysledok = a * b * c; vysledok už je nezmysel

a nefunguje ani pretypovanie výrazu
vysledok = (int32) (a * b * c)

funguje iba takto
vysledok = (int32)a * (int32)b * (int32)c

To je zápis z ktorého sa mi dvíha žalúdok, a ako to bude vyzerať keď budem násobiť 10 premenných?
Samozrejme v knihách nikde ani zmienka, tam sa asi predpokladá že programátor bude násobiť iba dve čísla. :rolleyes:

Re: Programovanie ccs C

Napísané: 09 Okt 2019, 12:48
od používateľa Mishung
Ked budes nasobit viac premennych tak si na to spravis funkciu s variabilnym poctom vstupnych parametrov a bude to vyzerat tak pekne ze by som si to zavesil aj na stenu :)

Ak nie si masochista pripadne si necenis svoj cas tak neodporucam hladat cokolvek v knihach ked mas problem pri programovani.
Moja oblubena volba je http://www.cppreference.com

Z toho co pises predpokladam ze pri tvojom kompilatore/architekture je datovy typ int velky 2 Bajty.
Co sa stalo je ze pred tym ako sa zacalo nasobit a*b*c sa a, b aj c pretypovalo na int (v tvojom pripade 0-65535).
Preto ti este vedelo vypisat a*b ale a*b*c uz nie.

Ak chces vediet preco tak si precitaj "Integral promotion" na tomto odkaze: https://en.cppreference.com/w/cpp/langu ... conversion

TLDR:
arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied

Re: Programovanie ccs C

Napísané: 27 Aug 2020, 10:45
od používateľa niki31
Potreboval by som poradiť s ukazateľom na reťazec. Neviem ako predať ukazateľ na reťazec z funkcie do funkcie.

napr.:

void funct1 (const char *pS)
{
uint16 str = &pS; //tu str obsahuje správne adresu písmena A.
char chr = *pS; // tu sa do chr správne priradí písmeno A

funct2 (&pS); //tu volám funkciu 2 a chcem jej ako parameter predať reťazec "Ahoj" na ktorý ukazuje pS

}

void funct2 (const char *pS)
{
uint16 str = &pS; //tu str obsahuje úplne inú adresu než je pismeno A.
char chr = *pS; // tu je iný znak než pismeno A
}

main()
{
funct1("Ahoj");
}

ccs c compiler v 5.015, 16 bit mikrokontrolér DsPIC33EP ...