Po co jest drugi apostrof w literale znaku?

3

Wiele języków programowania ma literał znaku. W wielu językach literał znaku ma postać 'c' gdzie c to nasz znak a otaczające go apostrofy informują kompilatr/interpreter że to znak. No i właśnie po co jest ten drugi postrof? przecież jeden by starczył bo i tak nie można napisać 'cc'. Przecież starczyło by 'c', np w Clojure jest \c a w erlangu jest $c i wystarcza. Czy to ma jakieś historyczne uzasadnienie?

Takie filozoficzne pytanie przy pisani kolejnego parsera mnie naszło

4

Dla estetyki i czytelności.

Funkcji w C też moglibyśmy nie zamykać } :]
Przecież wystarczy sam return.
Następna funkcja albo koniec pliku też oznaczają, że poprzednia funkcja się skończyła.

3

Dla estetyki i czytelności.

... no i jest jeszcze taka sprawa, gdy się coś ŹLE kompiluje.

Po ilu liniach / konstrukcjach kompilator wygrzebie się do takiego punktu, że komunikaty errorów są choć częściowo użyteczne. Na pewno zamykający apostrof pomaga.
Programowanie zna soluszyny z przyklejoną opinię "write-only": wyrażenia regularne, Perl, języki multumnawiasowe (Lisp & Co) i kilka innych

5
Spine napisał(a):

Dla estetyki i czytelności.

Funkcji w C też moglibyśmy nie zamykać } :]
Przecież wystarczy sam return.
Następna funkcja albo koniec pliku też oznaczają, że poprzednia funkcja się skończyła.

Nie do końca, zawsze może być etykieta za return do użycia z goto. Tak się raczej nie robi, ale w czasach gdy C było projetowane…

Tak najogólniej, nadmiarowość w języku jest w pewnej ilości bardzo pożądana, bo sprawia, że w razie błędu, będzie on wyłapany, a nie zinterpretowany (oczywiście Java jest daleko daleko poza tą granicą :D). W tym konkretnym przypadku, znacznie łatwiej to parsować, bo mimo wszystko nie zawsze zawartość znaku to tylko jeden znak, przecież może być np. '\n'. Powodzenia w leksowaniu tego bez zamykającego apostrofu, zwłaszcza w czasach kiedy C było projektowane, każdy bajt i każdy cykl procesora się liczył. Natomiast nowe języki na ogół kopiują rozwiązania ze starych, żeby łatwiej było się przesiąść na nową technologię – przyznaję, często jest to praktykowane do przesady. No i może trochę ze względu takiego, że jak mamy cudzysłów to oczekujemy jego zamknięcia, chociaż w lispie stosuje się apostrofy bez zamknięć i nie ma z tym problemu. :)

0
elwis napisał(a):

Powodzenia w leksowaniu tego bez zamykającego apostrofu, zwłaszcza w czasach kiedy C było projektowane, każdy bajt i każdy cykl procesora się liczył.

Czy to faktycznie byłoby takie trudne?
Przy parsowaniu metodę zejść rekurencyjnych lub innych parserach LL (bo takie były używane we wczesnych latach gdy każdy bajt się liczył) łatwo parsuje się gramatyki gdzie prefiks rozróżnia. Czyli kombinacje '\ '\ooo '\xhh '\unnnn '\unnnnnnnn są IMHO łatwe do ogarnięcia (czy to wszystkie dziwne kombinacje w C? na sprawdzałem na WIkibooku. Jedyne co to unnnn i unnnnnnnn są niejednoznaczne, ale ta niejednoznaczność jest identyczna z niejednoznacznością liczb, a mimo to nie używa się znaki końca liczby np 100000'

Co do czytelności to chyba tylko dla spacji widzę sens. ' ' jest dla mnie bardziej czytelne niż '

w lispie stosuje się apostrofy bez zamknięć i nie ma z tym problemu. :)

Jeszcze w Ruscie i OCamlu

1

W Erlangu masz $\s na spację. Jest dość czytelne, chyba często nawet bardziej niż ' '. I zgadzam się, że literały znakowe mogłyby używać innego zapisu niż 'c'.

2

Moim zdaniem też jeden by wystarczył (np. 'c), leksowanie nie wcale nie było by trudne: napotykam apostrof, jeśli następny znak to prawy ukośnik interpretuję escape sequence, jeśli inny to po prostu biorę ten znak i idę dalej. Tyle że trzeba było o tym pomyśleć 40 lat temu, bo teraz trzeba by to wszędzie zmieniać. No i wiele programistów jest przyzwyczajone do apostrofów z obu stron i tylko jeden uznałoby za brzydki. Z drugiej strony, w nowszych kompilatorach drugi apostrof mógłby być po prostu opcjonalny.

5

O ile obecnie prawie wszystkie procesory operują na 8-bitowych bajtach, to przecież nie zawsze tak było. W C, typ char ma zawsze rozmiar 1 bajta, zatem w przypadku pracy na procesorze z 16-bitowymi bajtami, literał znakowy 'ab' jak najbardziej ma sens.

0
Sensacyjny Sebastian napisał(a):

O ile obecnie prawie wszystkie procesory operują na 8-bitowych bajtach, to przecież nie zawsze tak było. W C, typ char ma zawsze rozmiar 1 bajta, zatem w przypadku pracy na procesorze z 16-bitowymi bajtami, literał znakowy 'ab' jak najbardziej ma sens.

OK, to załóżmy że pracujemy na jakiejś starej Odrze i słowo tam ma 24bity i nie ma mniejszej jednostki adresowania, a Znak zajmuje 8 bitów. Mam w jakiejść komórce/zmiennej wartość 'abc', i chce wypisać, np :

char c = 'abc';
putc(c);

A jak by to działało w sytuacji odwrotnej? (przy założeniu że wejście że I/O jest 8 bitowe) czyli gdy chce wczytać znaki

char c = getc();

to czy wczyta mi \0\0a, czy całe abc? Czy język programowania Odry ogarniał taką sytuację?

3

W Perlu i w kilku innych językach można ustawić kodowanie napisów instrukcją w skrypcie. Można zrobić nawet tak, że skrypt jest w jednym kodowaniu a napisy w innym. W takiej sytuacji lekser znajduje ciapki 'napis' i wszystko między nimi uznaje za napis. Na etapie analizy nie musi sprawdzać co to za znak i po prostu leci dalej. Za przetwarzanie napisów może odpowiadać inny mechanizm.

1
PerlMonk napisał(a):

W Perlu i w kilku innych językach można ustawić kodowanie napisów instrukcją w skrypcie. Można zrobić nawet tak, że skrypt jest w jednym kodowaniu a napisy w innym. W takiej sytuacji lekser znajduje ciapki 'napis' i wszystko między nimi uznaje za napis. Na etapie analizy nie musi sprawdzać co to za znak i po prostu leci dalej. Za przetwarzanie napisów może odpowiadać inny mechanizm.

Ok, ale w Perlu wewnątrz '' jest string, a nie pojedynczy znak, więc to jest nie na temat. Jak patrzę (nas szybko) w googla to Perl nawet nie ma żadnej składni do zapisania pojedynczego znaku. Można stworzyć tylko jednoelementowego stringa

4

Czytałem wątek wcześniej i zastanawiałem się, ale moja znajomość innych języków nie jest duża. Jak miałbym obstawiać to po prostu brak mieszania w składni. Jakbym pisał to jednak bez głębszej znajomości różnic taki char traktowałbym właśnie jako string i z przyzwyczajenia stawiał ciapki na początku i końcu. Mając jakaś unifikację chyba łatwiej pisać niż pamiętać, że dla char dajemy tylko otwierający jeden, dla stringa otwierający i zamykający. Być może też łatwiej było to jakoś kompilować lub dorobić osblugę błędów. Bo gdy damy char a = 'if' to łatwo zwrócić coś typu error. string to char conversion.

0

@hauleth:

W Erlangu masz $\s na spację. Jest dość czytelne, chyba często nawet bardziej niż ' '.

w jaki sposób?

0
1a2b3c4d5e napisał(a):

@hauleth:

W Erlangu masz $\s na spację. Jest dość czytelne, chyba często nawet bardziej niż ' '.

w jaki sposób?

Dla mnie ' ' było na początku strasznie nieczytelne. Pamiętam że pierwszym semestrze studiów to pisałem coś w rodzaju 'x20' \x20 zamiast ' ', bo było dla mnie czytelniejsze

3

Czemu 'x20'? Poprawnie (zapomniałeś o ukośniku) to '\x20' czyli sześć znaków. Alternatywnie 0x20 to cztery, a najkrócej 32 - tylko dwa znaki. Najczytelniej mógłbyś zrobić makro #define SPC 32 i potem pisać po prostu SPC.

1 użytkowników online, w tym zalogowanych: 0, gości: 1