2012-04-15 10 views
9

Dlaczego to rozróżnienie? Wylądowałem ze strasznymi problemami, zakładając, że itoa będzie w stdlib.h, a ostatecznie zakończy się połączeniem niestandardowej wersji itoa z innym prototypem, co spowoduje powstanie szalonych błędów.atoi jest standardową funkcją. Ale itoa nie jest. Czemu?

Dlaczego więc nie jest to standardowa funkcja, nie jest itoa? Co jest z tym nie tak? I dlaczego standard jest częściowy w stosunku do brata bliźniaka atoi?

+11

'atoi' jest historyczne,' itoa' nie jest. Nie powinieneś tak naprawdę używać 'atoi' tak,' strto (u) l (l) 'jest tym, czego powinieneś używać. Dla innego kierunku, 's (n) printf'. –

+0

Jako że 'itoa' nie jest funkcją standardową, czy możesz zawrzeć to, co powinien zawierać interfejs dla funkcji' itoa', którą chcesz omówić?(Może to odpowiedzieć na twoje pytanie.) –

+0

@CharlesBailey Jestem po prostu ciekawy, dlaczego standard zawiera atoi a nie itoa –

Odpowiedz

7

No itoa kiedykolwiek został ustandaryzowany, więc aby dodać go do standardu, potrzebny byłby nieodparty powód i dobry interfejs do jego dodania.

Większość interfejsów itoa, które widziałem, używają statycznego bufora, który ma problemy z ponownym wprowadzeniem i życiem, alokuje dynamiczny bufor, który musi wywołać dzwoniący lub wymaga od użytkownika dostarczenia bufora, który sprawia, że ​​interfejs nie jest lepszy niż sprintf.

+2

itoa() z przekazanym w buforze może być ogromną wygraną przez s (n) printf(), gdy nie używa się niczego innego z tej konkretnej części biblioteki (nic w rodzinie printf()). Nie jest to powód do umieszczania itoa() w standardowej bibliotece C, ale jest to powód, aby preferować go przez coś znacznie cięższego. –

+0

@JulieinAustin: Dlaczego to ogromna wygrana? To prawda, że ​​nie musisz analizować ciągu znaków w dwóch znakach, ale nie uważam, że jest to wielka szansa. –

+2

Można także uniknąć wszystkich innych funkcji parsowania, które pojawiają się podczas jazdy z rodziną printf(). Pamiętaj - są jeszcze inne rzeczy w tym życiu, poza parsowaniem ciągów formatów. Podobnie jak ślad pamięci. –

2

Funkcja "itoa" musiałaby zwrócić ciąg znaków. Ponieważ łańcuchy nie są obiektami pierwszej klasy, wywołujący musiałby przekazać bufor + długość, a funkcja musiałaby w jakiś sposób wskazać, czy zabrakło miejsca, czy nie. Zanim dojdziesz do tego momentu, stworzyłeś coś na tyle podobnego do sprintf, że nie warto powielać kodu/funkcji. Funkcja "atoi" istnieje, ponieważ jest mniej skomplikowana (i prawdopodobnie bezpieczniejsza) niż pełne wywołanie "scanf". Funkcja "itoa" nie byłaby na tyle inna, by była tego warta.

+0

Niezupełnie. Wielu programistów zawierało itoa() - podobne procedury w kodzie na przestrzeni lat. Maksymalny rozmiar bufora był dobrze ograniczony - 6 bajtów i zapasowy dla NUL dla 16-bitowego boxa i 11 plus zapasowy dla 32-bitowego boxa. Używam funkcji itoa() w pakiecie oprogramowania do przechwytywania danych, aby sformatować ciąg tekstowy zawierający informacje o wersji i statusie. W tej implementacji przekazuję wskaźnik, ale widziałem innych, że bufor jest statyczny. Najlepszym wytłumaczeniem jest to, że tak jak standardy, istnieje wiele różnych implementacji itoa() do wyboru! –

+0

@JulieinAustin - Nie mówię, że one nie istnieją, tylko że nie są one zestandaryzowane. Twój opis pomaga zrozumieć, dlaczego. Rozmiar bufora różni się w zależności od rozmiaru rejestru urządzenia. Komitet standardów C pozostaje z dala od specyficznych dla sprzętu szczegółów takich jak ten. Zestandaryzowana funkcja musiałaby mieć spójny interfejs i działać tak samo na ** dowolnej platformie **, a jedynym praktycznym sposobem na to jest wynaleźć większość 'printf()'. – bta

+0

Odpowiedziałem na twoje stwierdzenie, że funkcja = będzie = robić różne rzeczy. Tak naprawdę nie, a implementacja może być łatwo określona za pomocą odpowiedniej liczby słów typu łasica, aby ominąć różnice w rozmiarze słowa. Mam na myśli, że dla dowolnej wielkości słowa istnieje dobrze znana, skończona liczba znaków pamięci, które są wymagane do reprezentowania wszystkich możliwych wartości całkowitych dla tego rozmiaru słowa. TL; DR - może być i było wdrażane znacznie łatwiej i bardziej konsekwentnie, niż sugerujesz. –

1

Funkcja itoa nie jest standardem prawdopodobnie dlatego, że nie ma spójnej definicji tego. Różni producenci kompilatorów i bibliotek wprowadzili subtelnie różne jego wersje, prawdopodobnie jako wynalazek, który służy jako uzupełnienie do atoi.

Jeśli jakaś niestandardowa funkcja jest powszechnie dostarczana przez sprzedawców, standardem jest skodyfikowanie to: zasadniczo dodać opis istniejącej funkcji do standardu. Jest to możliwe, jeśli funkcja ma mniej lub bardziej spójne konwencje i zachowanie argumentów.

Ponieważ wiele smaków z itoa jest już dostępnych, funkcja taka nie może zostać dodana do ISO C. Jakiekolwiek zachowanie jest sprzeczne z niektórymi implementacjami.

itoa istnieje w postaciach takich jak:

void itoa(int n, char *s); /* Given in _The C Programming Language_, 1st ed. (K&R1) */ 

void itoa(int input, void (*subr)(char)); /* Ancient Unix library */ 

void itoa(int n, char *buf, int radix); 
char *itoa(int in, char *buf, int radix); 

Microsoft udostępnia je w ich środowisku Visual C Run Time Library pod zmienioną nazwą: _itoa.

Nie tylko implementacje C historycznie umieszczono je na różnych definicjach, C programy również funkcję o nazwie itoa funkcji dla siebie, co jest kolejnym źródłem ewentualnych starć.

Zasadniczo, identyfikator itoa jest "radioaktywny" w odniesieniu do standaryzacji jako nazwa zewnętrzna lub makro. Jeśli taka funkcja jest ustandaryzowana, będzie musiała mieć inną nazwę.