Wszyscy wiedzą, że C jest pięknym, bezpiecznym językiem programowania na wysokim poziomie. Jednak jako programista ustawiłeś następujące zadanie.
Napisz program, aby dodać dwie liczby.
- Wejście: dwie liczby całkowite oddzielone spacjami.
- Wyjście: Suma dwóch liczb na wejściu.
Rzecz w tym, że Twój kod musi być w 100% bezpieczny. Innymi słowy, musi działać poprawnie bez względu na wejście. Jeśli dane wejściowe są rzeczywiście dwiema liczbami całkowitymi oddzielonymi spacjami, z których każda ma długość mniejszą niż 100 cyfr, musi wyprowadzić sumę. W przeciwnym razie musi wygenerować komunikat o błędzie i zakończyć pracę bezpiecznie.
Jak trudne może być w końcu?
Ogólne podziękowania zostaną przekazane patologicznym przypadkom wejściowym, które łamią odpowiedzi innych ludzi :)
Kod musi się kompilować bez ostrzeżeń przy użyciu gcc -Wall -Wextra na Ubuntu.
Wyjaśnienie.
- Dane wejściowe pochodzą ze standardowego wejścia.
- Poziome białe znaki to tylko jedna spacja. Przed pierwszą liczbą nie powinno być niczego, a wprowadzanie danych powinno być zakończone znakiem nowej linii + EOF lub po prostu EOF.
- jedyne prawidłowe dane wejściowe określone w formularzu Augmented Backus-Naur to:
NONZERODIGIT = „1” / „2” / „3” / „4” / „5” / „6” / „7” / „8” / „9” POSITIVENUMBER = NONZERODIGIT * 98DIGIT NEGATIVENUMBER = "-" POSITIVENUMBER NUMBER = NEGATIVENUMBER / POSITIVENUMBER / „0” VALIDINPUT = NUMER SP NUMBER * 1LF EOF
- Komunikatem o błędzie jest pojedyncza litera „E”, po której następuje nowy wiersz.
- Kod musi zakończyć się czysto w czasie krótszym niż 0,5 s bez względu na wejście.
Odpowiedzi:
6610 bajtów (unminified)
Program „Good boy” C spełniający wszystkie kryteria wyzwania. Używa uzupełnienia 10s dla liczb ujemnych. W zestawie także uprząż testowa i walizki testowe.
Oto mała uprząż testowa i kilka przypadków testowych na początek. Możesz oderwać się od nadmiernego używania perla. System, na którym został opracowany, nie miał nowoczesnego basha.
Mały zestaw przypadków testowych:
źródło
bc
do oddzielnej odpowiedzi.289
EDYCJA : Ten kod działa tylko dla dodatnich liczb całkowitych. Zasady zmieniły się, odkąd opublikowałem tę odpowiedź.
Wersja nieposortowana i skomentowana:
źródło
./tmp.c: In function ‘f’: ./tmp.c:3:1: warning: suggest parentheses around comparison in operand of ‘|’ [-Wparentheses] ./tmp.c:3:1: warning: suggest parentheses around comparison in operand of ‘|’ [-Wparentheses] ./tmp.c: In function ‘main’: ./tmp.c:3:1: warning: control reaches end of non-void function [-Wreturn-type]
(s>99|c<48|c>57)
przez(s>99||c<48||c>57)
poprawić?442
Jest dość długi, więc w weekend mogę go pograć w golfa. Zakłada, że dane wejściowe pochodzą ze standardowego wejścia, zakończonego EOF (bez nowej linii), separator to tylko jeden znak o wartości ASCII 32 (to znaczy
' '
znak).Komunikatem o błędzie będzie pojedynczy znak „E”, a po nim nowy wiersz.
Z nowymi liniami i odrobiną wcięcia: (następująca wersja jest czytelna, więc możesz pominąć tutaj)
Wersja do odczytu (niektóre instrukcje zostały nieco zmienione, aby były bardziej czytelne, ale to, co robią, powinno być takie samo):
Chodzi
goto fail;
o to, żeby drwić z Apple.Użyłem wersji gcc
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
i nie ma żadnych ostrzeżeń.źródło
getchar()
zawsze pobierane ze standardowego wejścia). Zakłada się, że jest zakończony EOF bez nowej linii . Możesz to przetestować, wpisując [1] [spacja] [1] [Ctrl + D] [Ctrl + D] lubecho -n '1 1' | program
633 bajtów
Program „Bad boy” C, który spełnia połowę wyzwania. Nadużywa C, rzuca wiele ostrzeżeń, ale działa ... tak jakby. Arbitralna precyzja arytmetyczna jest faktycznie wykonywana przez
bc
.Wersja nieuprawniona
źródło