2009-01-03 6 views
14

Dokładnie to: Czy długość łańcuchów jest równa wielkości bajtu? Czy ma to znaczenie w języku?Czy długość łańcuchów jest równa wielkości bajtu?

Myślę, że tak, ale chcę się tylko upewnić.

Informacje dodatkowe: Po prostu zastanawiam się ogólnie. Moja specyficzna sytuacja to PHP z MySQL.

Jako odpowiedź brzmi nie, to wszystko, co potrzebuję wiedzieć.

Odpowiedz

46

Nie. Łańcuch zakończony zerem ma jeden dodatkowy bajt. Pas paskowy (skrót do Delphi) ma dodatkowy bajt na długość. Łańcuchy unicode mają więcej niż jeden bajt na znak.

Przez kodowanie Unicode zależy to od kodowania. Może to być 2 lub 4 bajty na znak lub nawet mieszanka 1,2 i 4 bajtów.

+0

W języku Delphi shortstring ma jeden dodatkowy bajt, ale inne typy ciągów mają dodatkowe cztery bajty. – inzKulozik

+0

Wiem, ale krótkie struny są nazywane paskalami ;-). –

+2

Bardzo dobra odpowiedź, krótka i słodka, od razu do rzeczy i zawiera najbardziej popularne przykłady z życia wzięte. –

6

To zależy od tego, co masz na myśli przez "długość". Jeśli masz na myśli "liczbę znaków", to nie, wiele języków/metod kodowania używa więcej niż jeden bajt na znak.

22

To całkowicie zależy od platformy i reprezentacji.

Na przykład w .NET ciąg zajmuje dwa bajty w pamięci na punkt kodowy UTF-16. Jednak pary zastępcze wymagają dwóch wartości UTF-16 dla pełnego znaku Unicode w zakresie U + 100000 do U + 10FFFF. Forma w pamięci ma również narzut na długość ciągu znaków i ewentualnie dopełnienie, jak również na zwykły obiekt narzutowy wskaźnika typu itp.

Teraz, gdy piszesz ciąg na dysku (lub sieć, itp.) z .NET, określasz kodowanie (większość klas ma domyślną wartość UTF-8). W tym momencie rozmiar zależy w dużej mierze od kodowania. ASCII zawsze bierze jeden bajt na znak, ale jest bardzo ograniczony (bez akcentów itp.); UTF-8 daje pełny zakres Unicode ze zmiennym kodowaniem (wszystkie znaki ASCII są reprezentowane w jednym bajcie, ale inne zajmują więcej). UTF-32 zawsze używa dokładnie 4 bajty dla dowolnego znaku Unicode - lista jest długa.

Jak widać, nie jest to prosty temat. Aby obliczyć, ile miejsca zajmie ciąg, musisz określić dokładnie, jaka jest sytuacja - czy jest to obiekt w pamięci na jakiejś platformie (a jeśli tak, to która platforma - potencjalnie nawet do implementacji i ustawienia systemu operacyjnego) lub czy jest to surowa zakodowana postać, na przykład plik tekstowy, a jeśli tak, to które kodowanie.

+2

Co za bałagan! – Malfist

+1

Oczywiście rozmiar na dysku zmienia się z/bez LM. Tylko dla dodatkowej zabawy ;-p –

3

Nie ma jednej odpowiedzi; to zależy od języka i realizacji (należy pamiętać, że niektóre języki mają wiele implementacje!)

Zero-zakończone ciągi ASCII zajmują przynajmniej jednego bajta więcej niż „treści” łańcucha. (Więcej może być przydzielonych, w zależności od tego, jak został utworzony łańcuch).

Ciągi zakończone zerem za pomocą deskryptora (lub podobnej struktury) do zapisu długości, co zabiera dodatkową pamięć gdzieś.

Łańcuchy Unicode (w różnych językach) używają dwóch bajtów na znak.

Do łańcuchów w składnicy obiektów można się odwoływać za pomocą uchwytów, które dodają warstwę pośrednią (i więcej danych) w celu uproszczenia zarządzania pamięcią.

2

Masz rację. Jeśli kodujesz jako ASCII, jeden bajt na znak. W przeciwnym razie jest to jeden lub więcej bajtów na znak.

W szczególności ważne jest, aby wiedzieć, w jaki sposób wpływa to na operacje podciągania. Jeśli nie masz jednego bajtu na znak, czy s [n] otrzymasz n-ty bajt lub n-ty znak? Uzyskanie n-tego znaku będzie nieefektywne dla dużych n zamiast stałych, jak to jest z jednym bajtem na znak.