Typy premenných v avr-gcc: Rozdiel medzi revíziami
Z SensorWiki
(Vytvorená stránka „== '''Základné<ref>(1) vynechávame zatiaľ polia, smerníky a typy Enum, Union a pod.</ref> typy premenných v avr-gcc''' == K dispozícii máme všetky bežné typy…“) |
|||
Riadok 1: | Riadok 1: | ||
− | == '''Základné<ref> | + | == '''Základné<ref>Zatiaľ vynechávame polia, smerníky a typy Enum, Union a pod.</ref> typy premenných v avr-gcc''' == |
K dispozícii máme všetky bežné typy, ktoré sa používajú v jazyku C. | K dispozícii máme všetky bežné typy, ktoré sa používajú v jazyku C. | ||
Riadok 18: | Riadok 18: | ||
double =float<ref>Anywhere the compiler sees "double", it says to itself, "Aha! The puny human said double. But I know better, so I'll replace it with float. Muwahahaha!"</ref> | double =float<ref>Anywhere the compiler sees "double", it says to itself, "Aha! The puny human said double. But I know better, so I'll replace it with float. Muwahahaha!"</ref> | ||
− | + | Okrem toho má programátor k dispozíci aj nové typy podľa štandardu C99, ktoré majú pevne definovanú veľkosť a tým pádom je zdrojový kód prenositeľnejší. Tieto typy nájdete v knižnici | |
− | Okrem toho | + | <code><inttypes.h></code> a sú dostupné aj cez hlavičkový súbor (header) <code><stdint.h></code>. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | int32_t | + | int8_t 1 Byte (8 bitov) je to alias pre signed char |
− | uint32_t | + | uint8_t 8-bit unsigned type |
− | + | ||
− | + | int16_t 2 Byty (16 bitov) = signed int / 16-bit signed type | |
− | int64_t | + | uint16_t 16-bit unsigned type. |
− | + | ||
− | + | int32_t 4 Byty (32 bitov) 32-bit signed type | |
− | + | uint32_t 32-bit unsigned type | |
− | uint64_t | + | |
+ | int64_t 8 Bytov (64 bitov) 64-bit signed type<ref>Note: This types are not available when the compiler option -mint8 is in effect.</ref> | ||
+ | uint64_t 64-bit unsigned type | ||
+ | Okrem vyššieuvedených pridáva C99 aj typ <code>bool</code> definovaný v <code><stdbool.h></code> headri. Okrem toho sú tam aj makrá pre hodnoty <code>true</code> and <code>false</code>. | ||
− | + | Má zmysel používať tento nový typ, keď aj tak zeberie 1 bajt podobne ako unsigned char? Rozdiel je vidieť v nasledovnom príklade. Používame v ňom aj deklaráciu volatile, aby nám pri pokusoch kompilátor nevyhodnotil tento kód ako nevyužitý a nevyhodil ho celkom z výsledného programu. | |
− | |||
− | |||
− | |||
− | aj deklaráciu volatile, aby nám pri pokusoch kompilátor nevyhodnotil tento kód ako nevyužitý a nevyhodil ho celkom z výsledného programu. | ||
<source lang="c++" style="background: LightYellow;"> | <source lang="c++" style="background: LightYellow;"> | ||
Riadok 71: | Riadok 60: | ||
<references /> | <references /> | ||
+ | |||
+ | |||
+ | == Aritmetické operácie so základnými typmi == | ||
+ | |||
Ako to potom vyzerá s jednoduchými aritmetickými operáciami? | Ako to potom vyzerá s jednoduchými aritmetickými operáciami? | ||
Riadok 98: | Riadok 91: | ||
+ | |||
+ | |||
+ | == Potrebujem vo svojom programe pracovať s reálnymi číslami! == | ||
+ | |||
+ | |||
+ | |||
+ | == Aj tak potrebujem reálne čísla! == | ||
+ | |||
== Literatúra == | == Literatúra == |
Verzia zo dňa a času 13:32, 13. máj 2021
Obsah
Základné[1] typy premenných v avr-gcc
K dispozícii máme všetky bežné typy, ktoré sa používajú v jazyku C.
Veľkosť Rozsah (signed) char 1 Byte (8 bitov) <−127, +127> unsigned char 1 Byte (8 bitov) <0, 255> signed int 2 Byty (16 bitov) <−32,767, +32,767> unsigned int <0, 65,535> signed long 4 Byty (32 bitov) <−2,147,483,647, +2,147,483,647> unsigned long <0, 4,294,967,295> float 4 Byty (32 bitov) IEEE-754 https://en.wikipedia.org/wiki/Single-precision_floating-point_format double =float[2]
Okrem toho má programátor k dispozíci aj nové typy podľa štandardu C99, ktoré majú pevne definovanú veľkosť a tým pádom je zdrojový kód prenositeľnejší. Tieto typy nájdete v knižnici
<inttypes.h>
a sú dostupné aj cez hlavičkový súbor (header) <stdint.h>
.
int8_t 1 Byte (8 bitov) je to alias pre signed char uint8_t 8-bit unsigned type int16_t 2 Byty (16 bitov) = signed int / 16-bit signed type uint16_t 16-bit unsigned type. int32_t 4 Byty (32 bitov) 32-bit signed type uint32_t 32-bit unsigned type int64_t 8 Bytov (64 bitov) 64-bit signed type[3] uint64_t 64-bit unsigned type
Okrem vyššieuvedených pridáva C99 aj typ bool
definovaný v <stdbool.h>
headri. Okrem toho sú tam aj makrá pre hodnoty true
and false
.
Má zmysel používať tento nový typ, keď aj tak zeberie 1 bajt podobne ako unsigned char? Rozdiel je vidieť v nasledovnom príklade. Používame v ňom aj deklaráciu volatile, aby nám pri pokusoch kompilátor nevyhodnotil tento kód ako nevyužitý a nevyhodil ho celkom z výsledného programu.
#include <stdbool.h>
volatile bool log_x;
volatile char char_x;
main(void)
{
log_x = 255; // obsahuje true
char_x = 255; // obsahuje 255, cize true
log_x = log_x + 1; // stale obsahuje true, pretoze 1+1 = 2 a to je nenulova hodnota, cize true
char_x = char_x + 1; // tu bude 0, cize false, pretoze 255+1=256, hodnota pretecie a dostaneme nulu, cize false
}
Poznámky:
- ↑ Zatiaľ vynechávame polia, smerníky a typy Enum, Union a pod.
- ↑ Anywhere the compiler sees "double", it says to itself, "Aha! The puny human said double. But I know better, so I'll replace it with float. Muwahahaha!"
- ↑ Note: This types are not available when the compiler option -mint8 is in effect.
Aritmetické operácie so základnými typmi
Ako to potom vyzerá s jednoduchými aritmetickými operáciami? // S vypnutou optimalizaciou
// Premenna: Kod: // Miesto v pamati Velkost a Rychlost
int_y = int_x + 3; // 2 Byte 5 instrukcii / 18 Byte 0,63 us - 2Byte vyber z pamati, scitaj (s vyhodou ADIW R24,0x03 Add immediate to word) a vrat do pamati char_y = char_x + 3; // 1 Byte 3 instrukcie / 10 Byte 0,01 us long_y = long_x + 3; // 4 Byte 11 instrukcii /38 Byte 1,25 us - lebo uz tahame a ukladame 4 bajty z pamati a do pamate float_y = float_x + 3; // 4 Byte 17 instrukcii + CALL / ?? Byte 8,06 us - volame podprogram pre floaty
double_y = double_x + 3; // 4 Byte 17 instrukcii + CALL / ?? Byte 8,06 us - volame podprogram pre floaty
No a takto zasa s tými zložitejšími
// S vypnutou optimalizaciou
// Premenna: Kod: // Miesto v pamati Velkost a Rychlost
int_y = int_x / 3; // 2 Byte 10 instrukcii + CALL / 18 Byte 15,19 us - lebo na / uz nie je instrukcia! int_y = int_x / 2; // 2 Byte 10 instrukcii + CALL / 18 Byte 0,81 us - lebo /2 je >> ! char_y = char_x / 3; // 1 Byte 5 instrukcie + CALL / 10 Byte 5,38 us long_y = long_x / 3; // 4 Byte 11 instrukcii /38 Byte 39,37 us - lebo uz tahame a ukladame 4 bajty z pamati a do pamate float_y = int_x / 3; // ZLE: tu je vysledok 0, lebo celociselne delenie len ulozime do float 4 Byte 17 instrukcii + CALL / ?? Byte 17,38 us - volame podprogram pre floaty float_y = float_x / 3.0; // 4 Byte 17 instrukcii + CALL / ?? Byte 30,81 us - volame podprogram pre floaty
double_y = double_x + 3; // 4 Byte 17 instrukcii + CALL / ?? Byte 8,06 us - volame podprogram pre floaty