Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory Poniżej pozwoliłem sobie za cytować za wikipedią definicję zmiennej w informatyce. Najbardziej istotne elementy tego artykułu pozwoliłem sobie wstawić tutaj pogrubioną czcionką. Zmienna - konstrukcja programistyczna posiadająca trzy podstawowe atrybuty: symboliczną nazwę, miejsce przechowywania i wartość; pozwalająca w kodzie źródłowym odwoływać się przy pomocy nazwy do wartości lub miejsca przechowywania. Nazwa służy do identyfikowania zmiennej w związku z tym często nazywana jest identyfikatorem. Miejsce przechowywania przeważnie znajduje się w pamięci komputera i określane jest przez adres i długość danych. Wartość to zawartość miejsca przechowywania. Zmienna zazwyczaj posiada również czwarty atrybut: typ, określający rodzaj danych przechowywanych w zmiennej i co za tym idzie sposób reprezentacji wartości w miejscu przechowywania. W programie wartość zmiennej może być odczytywana lub zastępowana nową wartością, tak więc wartość zmiennej może zmieniać się w trakcie wykonywania programu, natomiast dwa pierwsze atrybuty (nazwa i miejsce przechowywania) nie zmieniają się w trakcie istnienia zmiennej [1]. W zależności od rodzaju języka typ może być stały lub zmienny. Konstrukcją podobną lecz nie pozwalającą na modyfikowanie wartości jest stała. Tabela poniżej przedstawia zestawienie zmiennych dla kompilatora AVR-GCC oraz ich zakresy i wielkość zajmowanej pamięci: Typ char 8 Rozmiar (bitów) Wartość minimalna Wartość maksymalna signed char 8-128 127 unsigned char 8 0 255 short int 16-32768 32767 unsigned short int 16 0 65535 int 16-32768 32767 unsigned int 16 0 65535 long int 32-2 31 2 31-1 unsigned long int 32 0 2 32-1 long long int 64-2 63 2 63-1 unsigned long long int 64 0 2 64-1 float 32 ±1.18 10-38 ±3.4 10 38 double 32 ±1.18 10-38 ±3.4 10 38 long double 32 ±1.18 10-38 ±3.4 10 38
W AVR-GCC funkcjonują jeszcze typy takie jak na przykład: uint8_t - co oznacza odpowiednik typu unsigned char z tabeli powyżej albo uint16_t - odpowiednik unsigned short int zapis uint32_t oznacza unsigned (czyli bez znaku) integer (czyli całkowity) na 32 bitach. dla ćwiczenia spróbuj odgadnąć jaki typ odpowiada poniższym zapisom ile miejsca w pamięci zajmują oraz jaki jest zakres liczb przechowywanych przez nie: int16_t - int64_t - int8_t - uint64_t - Operatory Operatory pozwalają na operowanie zmienymi np. zapis wartości do zmiennych kontruowanie wyrażeń logicznych i arytmetycznych. Słowem dla maszyny cyfrowej jaką jest komputer i języka programowania za pomocą tworzymy oprogramowanie realizujące nasze zamierzone cele jest to jedna z podstawowych konstrukcji których poznanie i zapamiętanie jest podstawą. Bez nich tworzenie oprogramowania było by bardzo trudnie a może i niemożliwe. Operatory przypisania Nową wartość można zapisać w zmiennej używając operatora przypisania "="; instrukcję przypisania należy zakończyć średnikiem. Przykład: a = 100; //zapisanie do zmiennej nowej wartości równej 100 (dziesiętnie) a = 0xFF; //zapisanie do zmiennej a nowej wartości równej 0xFF (szesnastkowo) a = 0b00010010; //zapisanie do zmiennej a nowej wartości 0b0001001 (binarnie) Ta sama zmienna może stać po obu stronach operatora przypisania, przykład: a = a + 10; Powyższy zapis oznacza:
weź wartość zmiennej a i dodaj do niej liczbę 10; następnie wynik zapisz z powrotem do zmiennej a Przykładowo jeśli zmienna a ma wartość 10 to po tej operacji w tej samej zmiennej będziemy mieli już wartość 20. Zapis ten w języku C można skrócić do postaci: a += 10; jest to samo działanie jak powyżej. Obok operatora += są do dyspozycji podobnie działające operatory przypisania: -=, *=, /=, %=, ^=, =, &=, <<=, >>=. przykładowo: a -= 17; // czyli a = a - 17 a *= 2; // czyli a = a * 2 a /= 4; // czyli a = a / 4 a %= 4; // czyli a = a % 4 a ^= 0xaaaa; a = 0x5555; a &= 0xaaaa; // czyli a = a ^ 0xaaaa // czyli a = a 0x5555 // czyli a = a & 0xaaaa a <<= 8; // czyli a = a << 8 a >>= 4; // czyli a = a >> 4 Operatory arytmetyczne W języku C istnieją operatory arytmetyczne: + dodawania - odejmowania * mnożenia / dzielenia % dzielenia modulo (reszta z dzielenia całkowitego)
Jeśli oba argumenty operatora dzielenia / będą typu całkowitego, wtedy wynik operacji dzielenia będzie typu całkowitego i część ułamkowa wyniku będzie tracona. Resztę z dzielenia liczb całkowitych można wyliczyć posługując się operatorem % (dzielenia modulo). Inaczej jest, jeśli dzielna lub dzielnik albo oba argumenty operatora dzielenia / będą typu zmiennopozycyjnego (float, double), wtedy wynik dzielenia także będzie typu zmiennopozycyjnego. Operatory zwiększania i zmiejszania. W języku C istnieją operatory zwiększające lub zmniejszające o jeden wartości zmiennych. ++ zwiększ -- zmniejsz Sposób działania tych operatorów zależy od tego, czy ++(--) znajdują się po lewej, czy po prawej stronie zmiennej. Jeśli operator ++(--) stoi po lewej stronie zmiennej, wartość zmiennej zwiększa(zmniejsza) się o jeden przed użyciem wartości zmiennej. Jeśli operator ++(--) stoi po prawej stronie zmiennej, wartość zmiennej zwiększa(zmniejsza) się o jeden po użyciu wartości tej zmiennej. int a, b; b = 5; /* 'a' i 'b' będą równe 6 */ a = ++b ; /* 'a' będzie równe 6, 'b' będzie równe 7 */ a = b++ ; /* 'a' i 'b' będą równe 6 */ a = --b ; /* 'a' będzie równe 6, 'b' będzie równe 5 */ a = b-- ; Operatory logiczne, relacji i porównania W języku C dostępne są operatory relacji: > większy >= większy równy < mniejszy <= mniejszy równy Operatory przyrównania: == równy!= różny
Operatory logiczne: && AND OR! operator negacji Wynikiem działania operatorów: relacji, przyrównania i logicznych są wartości liczbowe: 0 - gdy fałsz, 1 - gdy prawda. W języku C wartość liczbowa 0 oznacza jednocześnie wartość logiczną FAŁSZ, a wartość 1 i każda inna wartość liczbowa różna od zera oznacza wartość logiczną PRAWDA Operatory bitowe W języku C istnieje sześć operatorów bitowych: bitowe OR & bitowe AND ^ bitowe XOR >> przesunięcie w prawo << przesunięcie w lewo ~ dopełnienie jednykowe Operacje bitowe działają na wartościach całkowitych i służą do manipulowania bitami, więc są szczególnie użyteczne przy programowaniu sprzętu - przy zabawie z bitami rejestrów I/O. Operatory bitowe & i mogą się mylić z opisanymi wcześniej operatorami logicznymi && i, dlatego szczegółowo, na przykładach, wyjaśnię różnice w działaniu operatorów bitowych i logicznych. W poniższych przykładach liczby wypisane są w postaci dwójkowej. operator bitowy " " - alternatywa (OR) 0 1 0 1 0 1 0 1 0 0 1 1 0 0 1 1 = 0 1 1 1 0 1 1 1 operator logiczny OR " " 0 1 0 1 0 1 0 1(PRAWDA bo wartość różna od zera) 0 0 1 1 0 0 1 1(PRAWDA) = 0 0 0 0 0 0 0 1(PRAWDA) operator "&" - bitowa koniunkcja (AND) 0 1 0 1 0 1 0 1 & 0 0 1 1 0 0 1 1 = 0 0 0 1 0 0 0 1 operator logiczny AND "&&" 0 1 0 1 0 1 0 1(PRAWDA) & 0 0 1 1 0 0 1 1(PRAWDA) = 0 0 0 0 0 0 0 1(PRAWDA)
operator "~" - dopełnienie jedynkowe ~ 1 0 0 1 1 0 0 1 = 0 1 1 0 0 1 1 0 operator logiczny negacja "!"! 1 0 0 1 1 0 0 1(PRAWDA) = 0 0 0 0 0 0 0 0(FAŁSZ) operator "^" - bitowa alternatywa wykluczająca (XOR) 0 1 0 1 0 1 0 1 ^ 0 0 1 1 0 0 1 1 = 0 1 1 0 0 1 1 0 operator "<<" - przesunięcie w lewo 1 0 0 1 1 0 0 1 << 3 = 1 1 0 0 1 0 0 0 operator ">>" - przesunięcie w prawo liczby bez znaku (unsigned) 1 0 0 1 1 0 0 1 >> 5 = 0 0 0 0 0 1 0 0 liczby ze znakiem (signed) 1 0 0 1 1 0 0 1 >> 5 = 1 1 1 1 1 1 0 0 Proszę zauważyć że, przesuwając bity liczby o jedną pozycję w lewo mnożymy wartość liczby razy dwa; a przesuwając o jedno pozycję w prawo, dzielimy liczbę przez dwa. Jeśli trzeba mnożyć(dzielić) liczby całkowite razy(przez) 2,4,8,2 n, to można przesuwać bity. A po co? Przecież są operatory arytmetyczne mnożenia i dzielenia: *, /. Na przykład, żeby zoptymalizować program pod kątem szybkości. Przesuwanie bitów liczby jest o wiele prostszą operacją w porównaniu z mnożeniem i dzieleniem. Dla 8 bitowych mikroprocesorów operacje mnożenia i dzielenia mogą być znaczącym obciążeniem. 2 * 2 = 4 00000010 << 1 = 00000100 3 * 4 = 12 00000011 << 2 = 00001100 9 * 8 = 72 00001001 << 3 = 01001000 67 / 16 = 4 (dzielenie całkowite) 01000011 >> 4 = 00000100 W liczbach ze znakiem(signed) najstarszy bit decyduje o znaku, więc w operacji przesuwania bitów w prawo liczb ze znakiem najstarszy bit pozostanie bez zmian. W przypadku przesuwania w prawo liczb bez znaku(unsigned) najstarszy bit otrzymuje wartość 0.
literatura: https://pl.wikipedia.org/wiki/zmienna_%28informatyka%29 http://hobby.abxyz.bplaced.net/index.php?pid=4&aid=4