2012-08-12 12 views
5

Z tego co wiem, funkcje nieczytelne to te, które nie zawsze zwracają tę samą wartość, gdy są wywoływane z tymi samymi parametrami (muszę czegoś nie mieć lub być w błędzie, popraw mnie, jeśli jestem).Dlaczego funkcja printf() jest zanieczyszczona?

Dlaczego więc printf() jest uważany za funkcję nieczystą?

Odpowiedz

15

Nie, funkcja „nieczyste” jest funkcją z ubocznych.

Innymi słowy, nie ma znaczenia ile razy można nazwać to, czysta funkcja wpłynie nic innych niż jej wyjściu.

Na przykład foo jest nieczyste, chociaż wrócić zerowy:

int x; 
int foo() { x++; return 0; } 
int bar() { return x; } 

Jeśli foo były czyste, nazywając go nie wpłynęłoby na wynik bar().

printf jest nieczysty, ponieważ jego wynik ma "efekty uboczne" - w szczególności drukuje coś na ekranie (lub w pliku itp.).
Jeśli byłby czysty, mógłbyś go nazwać miliard razy i mieć pewność, że nic złego się nie stanie.
Ale jeśli zadzwonisz printf milion razy, to na pewno jest różnica dla użytkownika - wypełnia swój ekran (lub miejsce na dysku, lub cokolwiek innego). Więc wyraźnie nie jest czysty.

Ponadto: Jeśli twoje dane wyjściowe zostały przekierowane na twoje własne dane wejściowe (nieco bezużyteczne, ale nadal), wówczas wywołanie printf wpłynęłoby na to, co otrzymasz od getchar. :) Tak więc jest to bezpośrednio obserwowalne.

+3

Ta poprawna odpowiedź nie ma nic wspólnego z 'printf'. Nie odnosi się także do ** WHY ** 'printf' jest zanieczyszczone (zewnętrzne - w przeciwieństwie do wewnętrznych - efekty uboczne). –

+0

Czy wszystkie funkcje są nieczyste. Czas wykonać (filozofia)! BTW - 'bar' zwraca x –

+0

@DavidTitarenco: Masz rację, właśnie to dodałem, dzięki! – Mehrdad

7

Są dwie części do bycia czystą funkcją. Pierwszym, jak stwierdziłeś, jest to, że funkcja musi konsekwentnie zwracać tę samą wartość dla tych samych parametrów wejściowych. Drugim kryterium, które nie spełnia, jest to, że funkcja nie może mieć skutków ubocznych, takich jak I/O lub mutacja obiektu.

+1

'printf' nie spełnia nawet pierwszych kryteriów: zwraca liczbę znaków ** pomyślnie ** wydrukowanych. – Vladimir

+0

@ Vladimir: Za każdym razem, gdy podajesz ten sam parametr wejściowy, zawsze zwróci on tę samą wartość (co oznacza liczbę znaków ** pomyślnie ** wydrukowanych). Więc w jaki sposób ** nie ** spełnia pierwsze kryteria? – cirronimbo

+0

Zwrócona wartość może się różnić w zależności od a) implementacji printf oraz b) błędów występujących podczas zapisu. Wyobraź sobie, że stdout jest zamknięty. Oto przykład: http://pastebin.com/HAtCm2Jh – Vladimir

3

Po prostu, printf jest nieczysty, ponieważ ma I/O. I/O z definicji jest nieczysty z powodu obecności zewnętrznego stanu urządzenia I/O (stan, który może różnić się od wykonania do wykonania).

0

printf() jest nieczyste, ponieważ powoduje wyjście do urządzenia I/O jako efekt uboczny .....

1

Znaczenie czystych funkcji w programowaniu jest to, że realizacja może zoptymalizować z połączenia czystego funkcji jeśli ma już wynik wywołania tej funkcji o tych samych parametrach. Najwyraźniej nie można tego zrobić dla wywołań printf.

P.S. Nawet według twojej definicji printf jest nieczysty, ponieważ może zwrócić jedną wartość, gdy się powiedzie, i inną wartość, jeśli wystąpi błąd wejścia/wyjścia, np. Brak miejsca w urządzeniu wyjściowym.

0

Wiele odpowiedzi wyjaśnia, że ​​printf ma I/O jako efekt uboczny, ale printf może mieć również inne efekty uboczne. Na przykład specyfikator %n pozwala printf na napisać na określony adres (i jest przyczyną niektórych luk w zabezpieczeniach).

Powiązane problemy