Powrót

Mikroprocesorowa ośla łączka, część 21

Ostatnia część, podsumowująca, dotycząca instrukcji języka C. Przyjrzymy się dokładniej instrukcjom podstawienia oraz wywołania funkcji. Wydają się proste, ale czasami mogą kryć się w nich niespodzianki.

Działanie programów będzie uruchamiane pod kontrolą symulatora wbudowanego w środowisko Atmel Studio, gdyż zwalnia to nas z budowania odpowiedniego środowiska sprzętowego, a możliwości symulatora są wystarczające, żeby poznać szczegóły ich działania.

Instrukcja podstawienia

To podstawowa instrukcja pozwalająca na realizacje obliczeń. Jej składnia polega na intuicyjnej interpretacji: <zmienna> = <wyrażenie>. Występujący tu znak „=” jest operatorem przypisania, czyli wartość wyrażenia wynikająca z obliczenia <wyrażenie> jest przesłana do miejsca docelowego, identyfikowanego przez nazwę zmiennej. Naturalną rzeczą jest to, by typ wyrażenia (wynikający ze zmiennych i stałych występujących w wyrażeniu) był zgodny z typem miejsca docelowego. Bardzo często nie zachodzi absolutnie doskonała kompatybilność typów obu stron elementów występujących w instrukcji podstawienia i w takich sytuacjach kompilator dokona dopasowania. Czasami może to prowadzić do nieoczekiwanych efektów, o których pisałem w artykule Mikroprocesorowa ośla łączka, część 19, ZE grudzień 2025. Były to dosyć oczywiste działania, choć czasami wynik zaskakiwał, szczególnie przy mieszaniu typów ze znakiem i bez znaku. Obecnie proponuję do rozpatrzenia bardziej „dziwny” przypadek programu, pokazany na listingu 1:

uint16_t Variable1 ;
uint8_t Variable2 [ 5 ] ;
 
int main ( void )
{
  Variable1 = Variable2 ;
  while (1)
  {
  }
}

Następuje tu podstawienie do zmiennej typu 16-bitowej liczby bez znaku, tablicy pięcioelementowej. O dziwo, kompilator wygenerował kod dla takiego programu (nie dostrzegł tu błędów składniowych) a jedynie zgłosił uwagę w kategorii ostrzeżenia (ang. warning), jak widać na rysunku 1.

Rysunek 1

Sens tego komunikatu należy rozumieć jako próbę przypisania liczby całkowitej ze wskaźnika bez rzutowania. Wszystko brzmi trochę enigmatycznie. Otóż nie następuje tu przepisanie zawartości tablicy do zmiennej 16-bitowej. Tablica jako zmienna bez elementu indeksującego (podania w nawiasach [ ] numeru elementu) jest interpretowana jako wskaźnik (adres) do całej tablicy, w sumie liczba 16-bitowa, pokazuje to rysunek 2 – po uruchomieniu symulacji działania programu.

Rysunek 2

Z komunikatu ostrzeżenia została wyjaśniona kwestia wskaźnika (czyli adresu) – można podstawić do zmiennej adres dowolnego elementu z programu. Pozostaje jeszcze jego część bez rzutowania. W sytuacjach, gdy zachodzi konflikt reprezentacji, można wymusić odmienne traktowanie wartości. Należy przed wyrażeniem dodać ujęty w nawiasy identyfikator typu, na jaki ma „to być przetłumaczone”. Poprawny zapis (taki, gdzie kompilator nie zgłosił żadnych uwag) przedstawia rysunek 3.

Rysunek 3

Takim zapisem programista informuje kompilator, że jest świadomy konfliktu typów, ale tak ma być. Próba uruchomienia w symulatorze tego programu daje identyczny wynik.

Taka „sztuczka” daje się wykonać jedynie w przypadku tablic, gdyż taka zmienna jest reprezentowana jako jej adres w pamięci, czyli jako liczba całkowita bez znaku.

(…)

——– ciach! ——–

To jest tylko fragment artykułu, którego pełna wersja ukazała się w lutowym numerze czasopisma Zrozumieć Elektronikę (ZE 2/2026). Pełną wersję czasopisma znajdziesz pod tym linkiem. Natomiast niepełna, okrojona wersja, pozwalająca zapoznać się z zawartością numeru ZE 2/2026 znajduje się tutaj.

Andrzej Pawluczuk
apawluczuk@vp.pl

Uwaga! Wskazówki, jak nabyć pełne wersje dowolnych numerów ZE znajdują się na stronie:
https://piotr-gorecki.pl/n11.