Wprowadziliśmy też funkcję o nazwie GetBlue(), której celem było przyjęcie 32-bitowej liczby całkowitej bez znaku jako parametru i zwrócenie najmniej znaczących 8 bitów w następujący sposób:
uint8_t GetBlue (uint32_t tmpColor)
{
return (uint8_t) (tmpColor & 0xFF);
}
Zauważyliśmy również, że w tym przypadku zarówno operacje rzutowania, jak i maskowania były niepotrzebne (jedynym powodem ich użycia była chęć wyjaśnienia naszych intencji każdemu, kto będzie musiał zrozumieć i dalej rozwijać ten program w przyszłości) i że w rzeczywistości moglibyśmy napisać tę funkcję w następujący sposób:
uint8_t GetBlue (uint32_t tmpColor)
{
return tmpColor;
}
Napisałem komentarz: „Możesz być pewien, że kompilator ma wiedzę na temat tego, które operacje są opcjonalne i nadmiarowe, innymi słowy wie, jak zoptymalizować kod i zrobi to”. Cóż, jeśli kiedykolwiek będziesz się zastanawiać, w jaki sposób twój kod C/C++ zostanie przekonwertowany na język asemblera i kodu maszynowego, możesz skorzystać ze wspaniałego darmowego narzędzia o nazwie Compiler Explorer. Na przykład, porównanie dwóch wersji naszej funkcji powyżej pokazuje, że zwracają one identyczny kod asemblera (https://bit.ly/2P5GemJ).
Przebiegły algorytm
Muszę przyznać, że jestem z tego całkiem dumny. W cyklu Porad i Sztuczek dawno, dawno temu rozmawialiśmy o instrukcji for(), którą można streścić w następujący sposób:
for (inicjalizacja; warunek; modyfikacja)
{
// instrukcje wykonywane w pętli
}
„Inicjalizacja” to miejsce, w którym inicjalizujemy naszą zmienną kontrolną (zmienne kontrolne), „warunek” to miejsce, w którym wykonujemy test, a „modyfikacja” to miejsce, w którym zwiększamy lub zmniejszamy naszą zmienną kontrolną (zmienne kontrolne). Zauważ, że sposób, w jaki to powiedziałem, wskazuje na możliwość posiadania wielu zmiennych inicjalizacyjnych i modyfikujących. Ogólnie rzecz biorąc, początkujący myślą o instrukcji for() w następujący sposób:
for (i = 0; i < 10; i++)
{
// instrukcje wykonywane w pętli
}
W rzeczywistości jednak zarówno sekcja inicjalizacji, jak i modyfikacji może składać się z wielu elementów oddzielonych przecinkami, wyglądających jak poniżej:
for (i = 0, j = 10; i < 10; i++, j--)
{
// instrukcje wykonywane w pętli
}
Zauważ, że możemy mieć tylko jeden warunek, chociaż może on mieć wiele części, takich jak ( (i < 10) && (j > 0) ), chociaż byłoby to zbędne dla wymagań w tym konkretnym przykładzie.
Powodem, dla którego poruszam ten temat, jest to, że właśnie zaimplementowałem sprytny algorytm wykorzystujący pętlę for() tego typu i pomyślałem, że podzielenie się nim z wami może być wartościowe.