Рядок (програмування) Зміст Внутрішнє представлення рядка в пам'яті | Реалізація в мовах програмування | Операції | Подання символів рядка | Див. також | Примітки | Навігаційне менювиправивши або дописавши їїр

Кодування символівТипи данихФормальні мовиПримітивні типи данихСинтаксичні одиниціРядкові алгоритми


англ.«ниткатип данихалфавітубайтівмови програмуванняUnicodeмасивомPascalASCIIСінуль-термінований рядокангл.ErlangHaskellПролог





Рядок (англ. String — «нитка, низка») або рядковий тип даних — це тип даних, значеннями якого є довільна послідовність (рядок) символів алфавіту. Кожна змінна такого типу (рядкова змінна) може бути представлена фіксованою кількістю байтів або мати довільну довжину.




Зміст





  • 1 Внутрішнє представлення рядка в пам'яті

    • 1.1 Подання масивом символів

      • 1.1.1 Переваги


      • 1.1.2 Недоліки



    • 1.2 Метод «завершального байту»

      • 1.2.1 Переваги


      • 1.2.2 Недоліки



    • 1.3 Використання обох методів


    • 1.4 Подання у вигляді списку



  • 2 Реалізація в мовах програмування


  • 3 Операції

    • 3.1 Найпростіші операції з рядками


    • 3.2 Похідні операції


    • 3.3 Операції при трактуванні рядків як списків


    • 3.4 Складніші операції


    • 3.5 Можливі завдання для рядків на природній мові



  • 4 Подання символів рядка


  • 5 Див. також


  • 6 Примітки




Внутрішнє представлення рядка в пам'яті |


Деякі мови програмування накладають обмеження на максимальну довжину рядка, але в більшості мов подібні обмеження відсутні. При використанні Unicode кожен символ рядкового типу може вимагати двох або навіть чотирьох байтів для свого представлення.


Основні проблеми в машинному поданні рядкового типу:


  • рядки можуть мати досить істотний розмір (до декількох десятків мегабайтів);

  • змінюється з часом розмір — виникають труднощі з додаванням і видаленням символів.

У поданні рядків в пам'яті комп'ютера існує два принципово різних підходи.



Подання масивом символів |


У цьому підході рядки представляються масивом символів; при цьому розмір масиву зберігається в окремій (службовій) області. Від назви мови Pascal, де цей метод був вперше реалізований, даний метод отримав назву Pascal strings.


Злегка оптимізованим варіантом цього методу є так званий формат c-addr-u (від англ. character-aligned address + unsigned number), застосовуваний в Форте. На відміну від Pascal strings, тут розмір масиву зберігається не спільно із рядковими даними, а є частиною покажчика на рядок.



Переваги |


  • програма в кожен момент часу містить відомості про розмір рядка, тому операції додавання символів в кінець, копіювання рядка і власне отримання розміру рядка виконуються досить швидко;

  • рядок може містити будь-які дані;

  • можливо на програмному рівні стежити за виходом за межі рядка при її обробці;

  • можливо швидке виконання операції виду «взяття N-го символу з кінця рядка».


Недоліки |


  • проблеми зі зберіганням і обробкою символів довільної довжини;

  • збільшення витрат на зберігання рядків — значення «довжина рядка» також займає місце і в разі великої кількості рядків маленького розміру може істотно збільшити вимоги алгоритму до оперативної пам'яті;

  • обмеження максимального розміру рядка. У сучасних мовах програмування це обмеження скоріше теоретичне, так як зазвичай розмір рядка зберігається в 32-бітовому полі, що дає максимальний розмір рядка в 4 294 967 295 байт (4 гігабайти);

  • при використанні алфавіту зі змінним розміром символу (наприклад, UTF-8), в розмірі зберігається не кількість символів, а саме розмір рядка в байтах, тому кількість символів необхідно вважати окремо.


Метод «завершального байту» |


Другий метод полягає у використанні «завершального байту»[1][2]. Одне з можливих значень символів алфавіту (як правило, це символ з кодом 0) вибирається як ознака кінця рядка, і рядок зберігається як послідовність байтів від початку до кінця. Є системи, в яких роль ознаки кінця рядка виконує не символ 0, а байт 0xFF (255) або код символу «$».


Метод має три назви — ASCIIZ (або asciiz, символи в кодуванні ASCII з нульовим завершальним байтом), C-strings (найбільшого поширення метод отримав саме в мові Сі), нуль-термінований рядок (англ. null-terminated string).



Переваги |


  • відсутність додаткової службової інформації про рядок (крім завершального байту);

  • можливість подання рядка без створення окремого типу даних;

  • відсутність обмеження на максимальний розмір рядка;

  • економне використання пам'яті;

  • простота отримання суфіксу рядка;

  • простота передачі рядків у функції (передається покажчик на перший символ);


Недоліки |


  • значний час виконання операцій отримання довжини і конкатенації рядків;

  • відсутність засобів контролю за виходом за межі рядка, в разі пошкодження завершального байта можливість пошкодження великих областей пам'яті, що може привести до непередбачуваних наслідків — втрати даних, краху програми і навіть всієї системи;

  • неможливість використовувати символ завершального байту як елемента рядка.

  • неможливість використовувати деякі кодування з розміром символу в кілька байт (наприклад, UTF-16), тому що у багатьох таких символах, наприклад Ā (0x0100), один з байтів дорівнює нулю (в той же час, кодування UTF-8 вільне від цього недоліку).


Використання обох методів |


У таких мовах, як, наприклад, Оберон, рядок розміщується в масиві символів певної довжини, причому її кінець позначається нульовим символом. За замовчуванням, весь масив заповнений нульовими символами. Такий спосіб дозволяє об'єднати багато переваг обох підходів, а також уникнути більшість їх недоліків.



Подання у вигляді списку |


Мови Erlang[3], Haskell[4], Пролог[5] використовують для рядкового типу список символів. Цей метод робить мову більш «теоретично елегантною» за рахунок дотримання ортогональності в системі типів, але приносить суттєві втрати швидкодії.



Реалізація в мовах програмування |


  • У перших мовах програмування взагалі не було рядкового типу; програміст повинен був сам будувати функції для роботи з рядками того чи іншого типу.
  • У Сі використовуються нуль-терміновані рядки з повним ручним контролем з боку програміста.
  • У стандартному Паскалі рядок виглядає як масив з 256 байтів; перший байт зберігав довжину рядка, в інших зберігається її тіло. Таким чином, довжина рядка не може перевищувати 255 символів. У Borland Pascal 7.0 також з'явилися рядки «по типу Сі» — очевидно, через те, що в число підтримуваних платформ увійшла Windows.
  • У Object Pascal та C++ STL рядок є «чорним ящиком», в якому виділення / вивільнення пам'яті відбувається автоматично — без участі програміста. При створенні рядка пам'ять виділяється автоматично; як тільки на рядок не залишиться жодного посилання, пам'ять повертається системі. Перевага цього методу в тому, що програміст не замислюється над роботою рядків. З іншого боку, програміст має недостатній контроль над роботою програми в критичних до швидкості ділянках; також важко реалізується передача таких рядків як параметр в DLL. Також Object Pascal автоматично стежить, щоб в кінці рядка був символ з кодом 0. Тому якщо функція вимагає на вході нуль-термінований рядок, для конвертації треба просто написати PAnsiChar(рядкова_змінна) або PWideChar (рядкова_змінна) (для Pascal), змінна c_str() (для Builder / STL).
  • У C # та іншими мовами із збіркою сміття рядок є незмінним об'єктом; якщо рядок потрібно модифікувати, створюється інший об'єкт. Цей метод повільний і витрачає чимало тимчасової пам'яті, але добре поєднується з концепцією збірки сміття. Перевага цього методу в тому, що присвоювання відбувається швидко і без дублювання рядків. Також є деякий ручний контроль над конструюванням рядків (в Java, наприклад, через класи StringBuffer і StringBuilder) — це дозволяє зменшити кількість виділень і вивільнень пам'яті і, відповідно, збільшити швидкість.
  • У деяких мовах (наприклад, Standard ML) крім цього, є додатковий модуль для забезпечення ще більшої ефективності — «підрядок» (SubString). Його використання дозволяє виконувати операції над рядками без копіювання їхніх тіл за допомогою маніпулювання індексами початку і кінця підрядка; фізичне копіювання відбувається лише при необхідності перетворення підрядків у рядки.


Операції |



Найпростіші операції з рядками |


  • Отримання символу за номером позиції (індексу) — в більшості мов це тривіальна операція;

  • Конкатенація (з'єднання) рядків.


Похідні операції |


  • Отримання підрядка за індексами початку і кінця;

  • Перевірка входження одного рядка в іншу (пошук підрядка в рядку);

  • Перевірка на збіг рядків (з урахуванням або без урахування регістру символів);

  • Отримання довжини рядка;

  • Заміна підрядка в рядку.


Операції при трактуванні рядків як списків |


  • Згортання;

  • Відображення одного списку на інший;


  • Фільтрація списку за критерієм.


Складніші операції |


  • Знаходження мінімального надрядка, що містить всі зазначені рядки;

  • Пошук в двох масивах рядків збігаються послідовностей (завдання про плагіат).


Можливі завдання для рядків на природній мові |


  • Порівняння на близькість зазначених рядків по заданому критерію;
  • Визначення мови і кодування тексту на підставі ймовірностей символів і складів.


Подання символів рядка |


До останнього часу один символ завжди кодувався одним байтом (8 двійкових бітів; застосовувалися також кодування з 7 бітами на символ), що дозволяло представляти 256 (128 при семибітному кодуванні) можливих значень. Однак для повноцінного представлення символів алфавітів кількох мов (багатомовних документів, друкарських символів — кілька видів лапок, тире, кількох видів прогалин і для написання текстів на ієрогліфічних мовах — китайською, японською та корейською) 256 символів недостатньо. Для вирішення цієї проблеми існує кілька методів:


  • Перемикання мови керуючими кодами. Метод не стандартизований і позбавляє текст самостійності (тобто послідовність символів без керуючого коду на початку втрачає сенс); використовувався в деяких ранніх русифікації ZX-Spectrum і БК.
  • Використання двох або більше байт для представлення кожного символу (UTF-16, UTF-32). Головним недоліком цього методу є втрата сумісності з попередніми бібліотеками для роботи з текстом при поданні рядка як ASCIIZ. Наприклад, кінцем рядка повинен вважатися вже не байт із значенням 0, а два або чотири поспіль нульових байта, в той час як одиночний байт «0» може зустрічатися в середині рядка, що збиває бібліотеку «з пантелику».
  • Використання кодування зі змінним розміром символу. Наприклад, в UTF-8 частина символів представляється одним байтом, частина двома, трьома або чотирма. Цей метод дозволяє зберегти часткову сумісність зі старими бібліотеками (немає символів 0 всередині рядка і тому 0 можна використовувати як ознака кінця рядка), але призводить до неможливості прямої адресації символу в пам'яті за номером його позиції в рядку.


Див. також |


  • Регулярний вислів

  • Список структур даних

  • Частота кадрів

  • Чорний список


Примітки |




  1. http://queue.acm.org/detail.cfm?id=2010365


  2. http://russian.joelonsoftware.com/Articles/BacktoBasics.html


  3. Simon St. Laurent. Introducing Erlang. — O'Reilly Media, Inc., 2013. — P. 62. — 185 p. — ISBN 978-1-449-33176-4.


  4. http://book.realworldhaskell.org/read/characters-strings-and-escaping-rules.html


  5. http://www.swi-prolog.org/pldoc/man?section=text-representation







Popular posts from this blog

Magento 2 duplicate PHPSESSID cookie when using session_start() in custom php scriptMagento 2: User cant logged in into to account page, no error showing!Magento duplicate on subdomainGrabbing storeview from cookie (after using language selector)How do I run php custom script on magento2Magento 2: Include PHP script in headerSession lock after using Cm_RedisSessionscript php to update stockMagento set cookie popupMagento 2 session id cookie - where to find it?How to import Configurable product from csv with custom attributes using php scriptMagento 2 run custom PHP script

Can not update quote_id field of “quote_item” table magento 2Magento 2.1 - We can't remove the item. (Shopping Cart doesnt allow us to remove items before becomes empty)Add value for custom quote item attribute using REST apiREST API endpoint v1/carts/cartId/items always returns error messageCorrect way to save entries to databaseHow to remove all associated quote objects of a customer completelyMagento 2 - Save value from custom input field to quote_itemGet quote_item data using quote id and product id filter in Magento 2How to set additional data to quote_item table from controller in Magento 2?What is the purpose of additional_data column in quote_item table in magento2Set Custom Price to Quote item magento2 from controller

How to solve knockout JS error in Magento 2 Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?(Magento2) knockout.js:3012 Uncaught ReferenceError: Unable to process bindingUnable to process binding Knockout.js magento 2Cannot read property `scopeLabel` of undefined on Product Detail PageCan't get Customer Data on frontend in Magento 2Magento2 Order Summary - unable to process bindingKO templates are not loading in Magento 2.1 applicationgetting knockout js error magento 2Product grid not load -— Unable to process binding Knockout.js magento 2Product form not loaded in magento2Uncaught ReferenceError: Unable to process binding “if: function()return (isShowLegend()) ” magento 2