Skocz do zawartości

Pomoc z else if'ami


Mikolajkie

Pomocna odpowiedź

2 minuty temu, Mikolajkie napisał:

Czy mógłbyś dać mi jakieś sytuacje, w których używać osobnych if'ów, a else/if'a? 🙂

Jestem marnym autorytetem raczej🤭 no ale używasz w danej chwili tego co Ci najbardziej pasuje 😉 w przypadku else/if warunki są sprawdzane po kolei aż do napotkania prawdy, wtedy już reszty tej "drabiny" nie sprawdzamy...przez co kod może być szybszy (narazie Cię to nie interesuje) ciężko mi teraz jakiś konkretny przykład przytoczyć 🙄 osobiście ja używam else/if bardzo rzadko...zazwyczaj same if'y z else wystarczają lub switch case

Link do komentarza
Share on other sites

Okej, dzięki. Ja zwykle będę korzystał z else/if. Ale zanim napiszę jakiś warunek z else/if to muszę pomyśleć, czy wszystko będzie działać.

Tutaj w kodzie poniżej są dwa osobne warunki, bo z else/if nie działałoby (chyba). Jeśli dałoby się to jakoś upchać w else/if to ten drugi warunek nigdy nie zadziałałby. Jeśli źle myślę to proszę mnie poprawić 😄

if(digitalRead(przycisk1) == LOW || digitalRead(przycisk2)) {
  digitalWrite(diodaZielona, HIGH);
} else {
  digitalWrite(diodaZielone, LOW);
}

if(digitalRead(przycisk1) == LOW && digitalRead(przycisk2)) {
  digitalWrite(diodaCzerwona, HIGH);
} else {
  digitalWrite(diodaCzerwona, LOW);
}

 

Link do komentarza
Share on other sites

13 minut temu, Mikolajkie napisał:

Czy mógłbyś dać mi jakieś sytuacje, w których używać osobnych if'ów, a else/if'a? 🙂

void process_command(parsed_cmd_t* cmd)
{
	if(strcmp((char*) cmd->name, LED_CMD) == 0 && cmd->type == CMD_SET)
		switch_led_cmd(cmd);
	else if(strcmp((char*) cmd->name, SAVE_CMD) == 0 && cmd->type == CMD_SET)
		save_cmd(cmd);

	else if(strcmp((char*) cmd->name, FAN_SPEED_CMD) == 0)
		default_fan_speed_cmd(cmd);
	else if(strcmp((char*) cmd->name, LIGHT_VALUE_CMD) == 0)
		default_light_value_cmd(cmd);
	else if(strcmp((char*) cmd->name, ON_TIME_CMD) == 0)
		on_time_cmd(cmd);
	else if(strcmp((char*) cmd->name, FAN_DELAY_CMD) == 0)
		fan_delay_cmd(cmd);
	else if(strcmp((char*) cmd->name, FAN_TIME_CMD) == 0)
		fan_time_cmd(cmd);
	else if(strcmp((char*) cmd->name, FAN_DELTA_CMD) == 0)
		fan_delta_cmd(cmd);
	else if(strcmp((char*) cmd->name, LIGHT_DELTA_CMD) == 0)
		light_delta_cmd(cmd);

	else if(strcmp((char*) cmd->name, LIGHT_ACTIVE_R_CMD) == 0)
		active_r(cmd);
	else if(strcmp((char*) cmd->name, LIGHT_ACTIVE_G_CMD) == 0)
		active_g(cmd);
	else if(strcmp((char*) cmd->name, LIGHT_ACTIVE_B_CMD) == 0)
		active_b(cmd);

	else if(strcmp((char*) cmd->name, LIGHT_INACTIVE_R_CMD) == 0)
		inactive_r(cmd);
	else if(strcmp((char*) cmd->name, LIGHT_INACTIVE_G_CMD) == 0)
		inactive_g(cmd);
	else if(strcmp((char*) cmd->name, LIGHT_INACTIVE_B_CMD) == 0)
		inactive_b(cmd);

}

Jest to sekcja wykrywająca komendę i wykonująca odpowiednią funkcję za nią odpowiedzialną. Niestety komendy są w formie tekstowej, więc trzeba było się pomęczyć z strcmp, co jest dość wolne, ale w tym przypadku to nie ma znaczenia 😉 

// If room is not occupied, time passed and fan is not active
	if(roomIsOccupied == FALSE)
	{
		emptyTimer += deltaTime;
		if(emptyTimer / TICKS_PER_SECOND > settings->fanAutoCleanupDelay && cleanupFanActive == FALSE)
		{
			emptyTimer = 0; // Reset timer
			cleanupFanActive = TRUE; // Activate fan
		}
		else if(emptyTimer / TICKS_PER_SECOND > settings->fanAutoCleanupTime && cleanupFanActive == TRUE)
		{
			emptyTimer = 0; // Reset timer
			cleanupFanActive = FALSE; // Deactivate fan
		}
	}

Tutaj warunek główny (brak osoby w pomieszczeniu) musi być spełniony, lepiej było go zrobić jako osobny, gdyż redukuje to duplikację kodu oraz jego podwójne sprawdzanie w najgorszym wypadku - w skrócie program jest szybszy i czytelniejszy.

	// Process button inputs
	button_t* fanUp = process_button(BTN_FAN_UP);
	if(fanUp->stable == TRUE && fanUp->state == GPIO_PIN_SET && fanUp->handled == FALSE)
	{
		config->fanSpeed += config->fanSpeedDelta;

		fanUp->handled = TRUE; // Handled now ;)
	}

	button_t* fanDn = process_button(BTN_FAN_DN);
	if(fanDn->stable == TRUE && fanDn->state == GPIO_PIN_SET && fanDn->handled == FALSE)
	{
		config->fanSpeed -= config->fanSpeedDelta;

		fanDn->handled = TRUE; // Handled now ;)
	}

	button_t* lightUp = process_button(BTN_LIGHT_UP);
	if(lightUp->stable == TRUE && lightUp->state == GPIO_PIN_SET && lightUp->handled == FALSE)
	{
		config->lightValue += config->lightDelta;

		lightUp->handled = TRUE; // Handled now ;)
	}


	button_t* lightDn = process_button(BTN_LIGHT_DN);
	if(lightDn->stable == TRUE && lightDn->state == GPIO_PIN_SET && lightDn->handled == FALSE)
	{
		config->lightValue -= config->lightDelta;

		lightDn->handled = TRUE; // Handled now ;)
	}

Przyciski mogą być naciśnięte w tym samym momencie. Stąd użycie osobnych if'ów dla każdego z przycisków.

Ogólnie to zazwyczaj zależy od logiki aplikacji (i optymalizacji wydajności).

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

Gdyby upchać w else/if to jak będzie to działało? Pierwszy warunek zawsze będzie spełniony i po tym od razu program wychodzi z tego wszystkiego. Więc na jakiej zasadzie mogłoby to działać i jak wyglądałby kod? Teraz jest to czytelne, ale czytelniejsze są dla mnie else/if 🙂

Edytowano przez Mikolajkie
Link do komentarza
Share on other sites

10 minut temu, Mikolajkie napisał:

Teraz jest to czytelne, ale czytelniejsze są dla mnie else/if 🙂

Poprostu musiałbyś zrobić else/if dla każdej z 4 możliwości ustawień guzików...było by to gorzej czytelne i dłuższe 😉

Link do komentarza
Share on other sites

(edytowany)

@farmaceuta Dobrze, już chyba wszystko rozumiem. Osobne if'y są czytelniejsze w takich przypadkach. Dzięki za wytłumaczenie i pomoc 😉

Edytowano przez Mikolajkie
Link do komentarza
Share on other sites

45 minut temu, ethanak napisał:

Tu jest jeszcze jeden kruczek...

Ważne jest, aby stan czegoś zewnętrznego (np. przycisku) czytać tylko raz - w przeciwnym przypadku może się zmienić między kolejnymi instrukcjami i się okaże, że żaden warunek nie jest spełniony. Przykład błędnego kodu:

if (digitalRead(X) == LOW) zapal_diodę();
if (digitalRead(X) == HIGH) zgaś_diodę();

Kod z podanego przykładu można bardzo ładnie uprościć.

Zacznę może jednak od tego dobrego zwyczaju czytania tylko raz:

bool p1 = digitalRead(przycisk1);
bool p2 = digitalRead(przycisk2);

Teraz mamy coś takiego:

if(!p1 || p2)) { // to po podstawieniu zmiennych do warunku
  digitalWrite(diodaZielona, HIGH);
} else {
  digitalWrite(diodaZielone, LOW);
}

Można stąd w ogóle wywalić if razem z else:

digitalWrite(diodaZielona, !p1 || p2);

Zadziała dokładnie tak samo...

To samo można zrobić z drugim ifem - i w ten sposób pozbywamy się zarówno problematycznego wielokrotnego odczytu stanu pinu jak i ifów w ogóle (czyli dyskusja o "else" przestaje mieć sens) 🙂

Ja tylko przypomnę pewne autentyczne zdarzenie sprzed lat...

Kod był w Pythonie, bibliotekę pisałem ja, reszta w liczbie programistów sztuk trzech zajmowała się pisaniem aplikacji. Fragment biblioyeki wyglądał mniej więcej tak:

if warunek1:
  czynność_pierwsza()
elif warunek2:
  czynność_druga()
  
if warunek3:
  czynność_trzecia()
elif warukek4:
  czynność_czwarta()
  

No i w pewnym momencie aplikacja przestała działać... po paru godzinach szukania błędu w aplikacji jeden z młodych dumny jak paw stwierdził "czego wy szukacie, tam w bibliotece był błąd, był if i zamieniłem na elif".

Oczywiście jego kawałek kodu bazujący na "poprawionym" kodzie biblioteki działał... 

Stąd biorą się zwyczaje umieszczania w kodzie komentarzy zawierających słowa ogólnie uznane za nieprzyzwoite 🙂

 

 

@ethanak w formie którą lubię. 

Muszę to jeszcze parę razy przeczytać;)

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.