Ascii на русском языке. Кодирование текстовой информации. Представление информации в компьютере

Мне лично в языке C++ всегда казалась довольно сложной для понимания тема всех эти copy assignment’ов, move constructor’ов, perfect forwarding’а и вот этого всего. Поскольку без этих знаний в современном C++ далеко не уедешь, решил попробовать во всем разобраться. Не могу сказать, что теперь владею материалом в совершенстве, но на небольшую заметку-введение вроде наскреблось. Авось кому будет интересно.

Базовый код с запретом копирования и присваивания

Если вы пока точно не знаете, как будет использоваться класс, лучше всего просто запретить копирование и присваивание. По умолчанию они разрешены и просто копируют все атрибуты класса. Часто это не то, чего вы хотите. Например, тупо копировать какие-то указатели, файловые дескрипторы или мьютексы, являющиеся атрибутами класса, явно плохая идея. Простейший код, в котором копирование и присваивание класса явно запрещены:

#include

class Coord2D {
public :
Coord2D() {
_x = 0 ;
_y = 0 ;
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") created" << std:: endl ;
}

Coord2D(int x, int y) {
_x = x;
_y = y;
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") created" << std:: endl ;
}

~Coord2D() {
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") destroyed" << std:: endl ;
}

int getX() const { return _x; }
int getY() const { return _y; }
Coord2D& setX(int x) { _x = x; return * this ; }
Coord2D& setY(int y) { _y = y; return * this ; }

Coord2D(Coord2D const & ) = delete ;

private :
int _x, _y;
} ;

int main() {
Coord2D c1;
Coord2D c2(1 , 2 ) ;

Std:: cout << "Hi!" << std:: endl ;
}

Вывод программы:

Coord2D(x = 0, y = 0) created

Hi!

Coord2D(x = 0, y = 0) destroyed

Пока что никаких неожиданностей. Стоит отметить, что вместо:

Coord2D(Coord2D const & ) = delete ;
void operator= (Coord2D const & ) = delete ;

… можно написать:

Coord2D(Coord2D const & ) = default ;
void operator= (Coord2D const & ) = default ;

… тем самым явно указав на то, что вас устраивают реализации по умолчанию.

Copy constructor

Объявим copy contructor:

/* ... */

Coord2D(Coord2D const & obj) {
_x = obj._x;
_y = obj._y;
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") copied" << std:: endl ;
}

/* ... */

int main() {
Coord2D c1(1 , 2 ) ;
Coord2D c2(c1) ;
Coord2D c3 = c1;
std:: cout << "Hi!" << std:: endl ;
}

Заметьте, что в нем мы имеем доступ к private полям второго экземпляра класса (obj), несмотря на то, что это другой экземпляр. Вывод программы:

Coord2D(x = 1, y = 2) created
Coord2D(x = 1, y = 2) copied
Coord2D(x = 1, y = 2) copied
Hi!
Coord2D(x = 1, y = 2) destroyed
Coord2D(x = 1, y = 2) destroyed
Coord2D(x = 1, y = 2) destroyed

Оба синтаксиса эквивалентны, в обоих случаях был вызван copy constructor. Конструктор для каждого объекта был вызван один раз. Можно было и не писать этот код, так как реализация copy constructor по умолчанию и так просто копирует атрибуты класса.

Copy assignment

Объявим copy assignment оператор:

/* ... */

void operator= (Coord2D const & obj) {
_x = obj._x;
_y = obj._y;
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") copy-assigned" << std:: endl ;
}

/* ... */

int main() {
Coord2D c1(1 , 2 ) ;
Coord2D c2(c1) ;
Coord2D c3 = c1;

C2 = c3;

Std:: cout << "Hi!" << std:: endl ;
}

Coord2D(x = 1, y = 2) created
Coord2D(x = 1, y = 2) copied
Coord2D(x = 1, y = 2) copied
Coord2D(x = 1, y = 2) copy-assigned
Hi!
Coord2D(x = 1, y = 2) destroyed
Coord2D(x = 1, y = 2) destroyed
Coord2D(x = 1, y = 2) destroyed

Заметьте, что деструктор при присвоении не вызывается. Это означает, что в реализации copy assignment следует освобождать старые ресурсы перед присвоением новых значений.

Move constructor

Перепишем код следующим образом:

/* ... */

Coord2D id(Coord2D x) {
std:: cout << "id called" << std:: endl ;
return x;
}

int main() {
Coord2D c1 = id(Coord2D(1 ,2 ) ) ;
c1.setX (- 1 ) ;
std:: cout << "Hi!" << std:: endl ;
}

Coord2D(x = 1, y = 2) created
id called
Coord2D(x = 1, y = 2) copied
Coord2D(x = 1, y = 2) destroyed
Hi!

Как видите, мы создаем копию из временного объекта, после чего он сразу уничтожается. Для нас это не проблема, так как объект маленький. Но если бы он содержал в себе большие объемы данных, мы бы создали их полную копию, а затем одну из копий освободили бы. Для решения этой проблемы придумали move constructor:

/* ... */
Coord2D(Coord2D&& obj) {
_x = obj._x;
_y = obj._y;
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") moved" << std:: endl ;
}
/* ... */

Coord2D(x = 1, y = 2) created
id called
Coord2D(x = 1, y = 2) moved
Coord2D(x = 1, y = 2) destroyed
Hi!
Coord2D(x = -1, y = 2) destroyed

Move constructor вызывается вместо copy constructor в случае, когда объект, из которого создается копия, вот-вот будет уничтожен. В таком конструкторе обычно данные из временного объекта переносятся в новый объект, а полям временного объекта присваиваются nullptr или что-то такое. Важно понимать, что при выходе из move constructor оба объекта должны оставаться валидными и для обоих должен корректно отрабатывать деструктор. Ссылка T&& называется rvalue reference и означает ссылку на объект, который вот-вот будет уничтожен.

Move assignment

Аналогично move constructor, только для присваивания. Например, код:

int main() {
Coord2D c1(1 ,2 ) ;
c1 = Coord2D(4 ,5 ) ;

Std:: cout << "Hi!" << std:: endl ;
}

… выведет:

Coord2D(x = 1, y = 2) created

Coord2D(x = 4, y = 5) copy-assigned

Hi!
Coord2D(x = 4, y = 5) destroyed

Объявим move assignment оператор:

/* ... */
void operator= (Coord2D&& obj) {
_x = obj._x;
_y = obj._y;
std:: cout << "Coord2D(x = " << _x << ", y = " << _y <<
") move-assigned" << std:: endl ;
}
/* ... */

Coord2D(x = 1, y = 2) created
Coord2D(x = 4, y = 5) created
Coord2D(x = 4, y = 5) move-assigned
Coord2D(x = 4, y = 5) destroyed
Hi!
Coord2D(x = 4, y = 5) destroyed

Move assignment оператор позволяет применить те же оптимизации, что и move constructor. В move constructor поля объекта, переданного в качестве аргумента, обычно как-то зануляются. В move assignment лучше сделать swap полей в двух объектах. Это позволит избавиться от дублирования кода между оператором move assignment и деструктором.

std::move

Move constructor бывает трудно стригерить. Например, код:

int main() {
Coord2D c1(Coord2D(1 ,2 ) .setX (5 ) ) ;
std:: cout << "Hi!" << std:: endl ;
}

… выведет:

Coord2D(x = 1, y = 2) created
Coord2D(x = 5, y = 2) copied

Hi!
Coord2D(x = 5, y = 2) destroyed

Так происходит, потому что метод setX возвращает lvalue reference, а у move constructor на входе совершенно другой тип, rvalue reference. Чтобы явно показать, что временный объект мы больше использовать не будем, предусмотрен std:move. Если переписать код так:

int main() {
Coord2D c1(std:: move (Coord2D(1 ,2 ) .setX (5 ) ) ) ;
std:: cout << "Hi!" << std:: endl ;
}

… программа выведет:

Coord2D(x = 1, y = 2) created
Coord2D(x = 5, y = 2) moved
Coord2D(x = 5, y = 2) destroyed
Hi!
Coord2D(x = 5, y = 2) destroyed

В сущности, std::move просто кастует lvalue reference (T&) в rvalue reference (T&&), больше ничего. При чтении кода std::move как бы говорит нам, что мы отдаем владение объектом в этом месте и далее не собираемся его использовать.

std::forward

Шаблон std::forward предназначен исключительно для написания шаблонных методов, способных принимать на вход как lvalue, так и rvalue, в зависимости от того, что передал пользователь, и передавать соответствующий тип далее без изменений. Техника получила название perfect forwarding.

Рассмотрим пример. Определим оператор сложения двух координат:

/* ... */

template < class T>
friend Coord2D operator+ (T&& a, const Coord2D& b) {
std:: cout << "Creating `Coord2D t`..." << std:: endl ;
Coord2D t(std:: forward < T> (a) ) ;
std:: cout << "`Coord2D t` created!" << std:: endl ;

return t.setX (t.getX () + b.getX () ) .setY (t.getY () + b.getY () ) ;
}

/* ... */

int main() {
Coord2D c1(1 ,1 ) , c2(1 ,2 ) , c3(1 ,3 ) ;
Coord2D c4 = c1 + c2 + c3;

Std:: cout << "Hi!" << std:: endl ;
}

Coord2D(x = 1, y = 1) created
Coord2D(x = 1, y = 2) created
Coord2D(x = 1, y = 3) created
Creating `Coord2D t`...
Coord2D(x = 1, y = 1) copied
`Coord2D t` created!
Coord2D(x = 2, y = 3) copied
Coord2D(x = 2, y = 3) destroyed
Creating `Coord2D t`...
Coord2D(x = 2, y = 3) moved
`Coord2D t` created!
[...]

Смотрите, что происходит. При первом вызове оператора сложения переменная t инициализируется при помощи copy constructor, так как c1 не является временным объектом. Однако при втором вызове первым аргументом передается временный объект c1 + c2 , и из него переменная t инициализируется уже при помощи move constructor. То есть, фактически std::forward позволил написать процедуру один раз, вместо того, чтобы писать две версии — одну, принимающую первым аргументом lvalue reference, и вторую, работающую с rvalue reference.

Заключение

Заметьте, что думать про всякие move semantics и perfect forwarding нужно только при работе с объектами, держащими в себе много данных, и только если вы часто копируете или присваиваете такие объекты. Это исключительно оптимизация, и без нее все будет совершенно корректно работать (более того, ничего этого не существовало до появления C++11). Пока профайлер не говорит вам , что вы во что-то такое не уперлись, возможно, не стоит заморачиваться. Помните также, что компилятор зачастую может избавляться от лишнего копирования объектов, см return value optimization (RVO) и copy elision .

С другой стороны, теорию понимать стоит независимо от того, упирается ваш код в копирование и перемещение объектов, или нет. Как минимум, move semantics и иже с ним может использоваться в чужом коде. В частности, он используется в STL, см например метод emplace_back класса std::vector или метод emplace класса std::map . Кроме того, понимание move semantics будет весьма нелишним при использовании

За счет которых возможно реализовать отдельные функции для обработки обычных (живущих дольше выражения) и временных объектов. Такой подход позволяет написать более оптимальный код, т.к. зная, что аргументом является временный объект (который все равно будет уничтожен после обработки), мы можем использовать данные этого объекта, вместо создания новых. Такое поведение называется семантикой перемещения, для его реализации служат перемещающие конструкторы, принимающие на вход rvalue ссылку. Расскажите про них с примерами.

  • Перемещающий конструктор. Примеры

    Рассмотрим функцию, выполняющую переворот строки, учитывая, что на вход подано rvalue (временный объект) :

    String reverse(string&& str) { string reverse_string(str.buffer); str.buffer = nullptr; std::reverse(reverse_string.begin(), reverse_string.end()); return reverse_string; }

    Тут экономия (более высокая эффективность) обеспечивается за счет того, что результирующая строка использует буфер (какие-то сырые данные, возможно char*) из временной строки. Более подробно про то, как работает этот код: . Проблема тут заключается в нарушении инкапсуляции, т.к. сторонний код (функция реверса строки) не должна иметь доступ к сырым данным строки (и даже знать как она устроена внутри).

    Решением проблемы являются перемещающие конструкторы, которые вызываются автоматически вместо конструкторов копирования если аргументом является временный объект. Для сравнения рассмотрим конструктор копирования строки и перемещающий конструктор:

    String(string const& str) : m_buf(new char), m_size(str.size()) { strcpy(m_buf, str.m_buf); } string(string const&& str) : m_buf(str.m_buf), // char* m_buf - заменяется указатель m_size(str.size()) { str.m_buf = nullptr; str.m_size = 0; }

    Конструктор копирования, как это обычно происходит, создает новый буфер для хранения данных, вызывая оператор new , а перемещающий конструктор — забирает данные у переданного ему временного объекта. Мы можем реализовать такой конструктор и для нашего (класса массива, размер которого увеличивается автоматически при вставке элемента):

    Template Array::Array(Array&& array) : m_size(array.m_size), m_realSize(array.m_realSize), m_array(array.m_array) { array.m_size = 0; array.m_realSize = 0; array.m_array = nullptr; }

    В этих примерах перемещающий конструктор является лишь более оптимальной версией конструктора копирования для случаев, когда на вход подан временный объект, например:

    Void foo(string str); void bar(const string& str); foo(employee.get_name()); bar(employee.get_office());

    Преимущества перемещающего конструктора

    Было показано, что перемещающий конструктор является облегченной версией конструктора копирования , однако иногда реализуют перемещающий конструктор для классов, копирование в которых запрещено. Ярчайший пример — std::unique_ptr<> , представляющий собой один из умных указателей стандартной библиотеки, реализующий . Суть этого класса заключается в том, что он владеет единственным указателем на некоторый объект (и автоматически разрушает объект в определенных ситуациях). Указатель должен быть единственным, следовательно конструктор копирования не должен быть доступен, однако перемещение для этого класса вполне логично (мы можем передавать владение указателем от одного объекта к другому — поэтому unique_ptr , в частности, может быть использован в качестве возвращаемого значения функции. Другими примерами такого поведения из стандартной библиотеки являются классы std::fstream и std::thread — копирование для них лишено смысла, однако передача владения файлом из одной функции в другую может быть логична.
    Таким образом, семантика перемещения является не только средством повышения эффективности программ, но и позволяет реализовать передачу владения объектом в случаях, когда копирование запрещено (является очень длительной операцией или вообще лишено смысла).

    Стоит отметить, что не для всех классов имеет смысл писать перемещающий конструктор. Так, вы не сможете например повысить эффективность за счет перемещения класса точки или любого другого класса не владеющего внешним ресурсом. Ведь повышение эффективности обеспечивается заменой копирования этого ресурса перемещением:

    Struct Point { double x, y; Point(const Point& point) : x(point.x), y(point.y) { } }

    Для этого примера не получится реализовать перемещающий конструктор более эффективно, чем конструктор копирования.

    std::move

    В ряде случаев нужно явно указать компилятору, что объект является временным — сделать это можно с помощью функции std::move , выполняющей приведение типа к rvalue (эквивалентной static_cast). Если вам нужно переместить именованный (не временный) объект — используйте std::move , т.к. в противном случае будет вызван конструктор копирования:

    Void foo(Type&& obj) { Type copy_obj(obj); // вызов конструктора копирования Type move_obj(std::move(obj)); // вызов перемещающего конструктора } foo(Type()); // успешный вызов функции foo Type obj; foo(obj); // ошибка, функция принимает ссылку на r-значение, но мы передаем l-значение

    Этот пример напоминает, что функции, принимающие указатели на rvalue будут вызваны только для временных объектов. Однако, внутри функции эти объекты уже не являются временными, ведь у них есть имя — поэтому при создании объекта copy_obj будет вызван конструктор копирования. Если нам нужно перемещение — нужно явно указать, что объект является временным с помощью std::move .

    В рассмотренном выше примере данные строки (класс string) хранились в виде массива символов, поэтому вызов m_buf(str.m_buf) работал эффективно — просто заменялся указатель. Однако, если данных хранились бы в векторе, то такой код привел бы к вызову конструктора копирования:

    String(string const&& str) : m_buf(str.m_buf) // vector m_buf, вызывается конструктор копирования { }
    Решить проблему можно с помощью std::move:
    string(string const&& str) : m_buf(std::move(str.m_buf)) // vector m_buf, вызывается перемещающий конструктор { }

    Важно помнить, что std::move не перемещает объект, а лишь выполняет приведение типа, которое позволяет вызвать перемещающий конструктор.

    std::swap

    Функция std::swap предназначена для обмена значений двух объектов. До принятия стандарта С++11 обмен происходил с использованием вспомогательной переменной, что требовало выполнения конструктора копирования и двух операций присваивания:

    Template void swap(T& a, T& b) { T c(a); a=b; b=c; }

    Сейчас для классов, поддерживающих семантику перемещения эта функция вызывает перемещающий конструктор и два перемещающих оператора присваивания:

    Template void swap(T& a, T& b) { T c(std::move(a)); a=std::move(b); b=std::move(c); }

    Это работает очень эффективно и может применяться для более простой реализации перемещающего конструктора:

    String(string&& str) : string() { swap(*this, str); }

    Перемещающий конструктор вызывает конструктор по умолчанию, в результате чего создается строка нулевой длины (память не выделяется, код работает очень быстро). Затем текущий объект обменивается при помощи перемещающей функции swap с временным, переданным в качестве аргумента.
    Не во всех случаях такой подход будет одинаково эффективным, там для класса Array , рассмотренного выше, конструктор по умолчанию динамически выделяет блок памяти некоторого начального размера.

    Перемещающий оператор присваивания и std::swap

    Оператор присваивания является одной из наиболее часто используемых функций, даже std::swap использует его, при этом семантика перемещения может повысить эффективность:

    Array get_values(); Array values; values = get_values();
    В данном примере вызов функции создает временный объект, который присваивается объекту values . Если для класса Array не реализована перемещающая версия оператора, то произойдет копирование данных массива.
    template Array& operator=(Array&& source) { if (this != &source) { delete m_array; m_array = source.m_array; m_size = source.m_size; m_realSize = source.m_realSize; source.m_array = nullptr; } return *this; }

    Оператор выполняет проверку самоприсваивания чтобы не уничтожить единственную копию данных, затем освобождает память из под данных, уже имеющихся в объекте, помещает в него данные из объекта правой части оператор и обнуляет указатель временного объекта.

  • --- Многопоточность и файлы --- Перемещение, копирование и удаление файлов

    Как упоминалось ранее, перемещение и удаление файлов или папок в классах FileInfo и DirectoryInfo обеспечивают методы MoveTo() и Delete(). В классах File и Directory доступны аналогичные методы Move() и Delete(). Вдобавок классы FileInfo и File поддерживают, соответственно, методы СоруТо() и Сору(). Однако для копирования папок целиком методов не предусмотрено. Папку можно копировать только за счет копирования каждого содержащегося в ней файла.

    Использовать все эти методы довольно просто; детальные описания способов работы с ними можно найти в документации SDK. В настоящей статье их применение иллюстрируется на примере вызова статических методов Move(), Сору() и Delete() класса File. Для этого будет взято за основу предыдущее приложение FileProperties и создана его измененная версия. При отображении свойств файла появится возможность удаления, перемещения и копирования файла в какое-то другое место.

    Добавьте следующую разметку к коду предыдущего примера:

    ... Новое расположение

    Private void buttonMove_Click(object sender, RoutedEventArgs e) { try { string filePath = Path.Combine(currentFolderPath, textBoxFileName.Text); string query = "Действительно переместить файл \n" + filePath + " ?"; if (MessageBox.Show(query, "Переместить файл?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { File.Move(filePath, textBoxNewPath.Text); DisplayFolderList(currentFolderPath); } } catch (Exception ex) { MessageBox.Show("Не удается переместить файл из-за исключения: " + ex.Message); } } private void buttonCopy_Click(object sender, RoutedEventArgs e) { try { string filePath = Path.Combine(currentFolderPath, textBoxFileName.Text); File.Copy(filePath, textBoxNewPath.Text); DisplayFolderList(currentFolderPath); } catch (Exception ex) { MessageBox.Show("Не удается скопировать файл из-за исключения: " + ex.Message); } } private void buttonDelete_Click(object sender, RoutedEventArgs e) { try { string filePath = Path.Combine(currentFolderPath, textBoxFileName.Text); string query = "Действительно удалить файл \n" + filePath + " ?"; if (MessageBox.Show(query, "Удалить файл?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { File.Delete(filePath); DisplayFolderList(currentFolderPath); } } catch (Exception ex) { MessageBox.Show("Не удается удалить файл из-за исключения: " + ex.Message); } }

    19.12.13 23.8K

    Для того, чтобы грамотно использовать ASCII , необходимо расширить знания в данной сфере и о возможностях кодирования.

    Что это такое?

    ASCII представляет собой кодировочную таблицу печатных символов (см. скриншот №1), набираемых на компьютерной клавиатуре, для передачи информации и некоторых кодов. Иными словами происходит кодирование алфавита и десятичных цифр в соответствующие символы, представляющие и несущие в себе необходимую информацию.


    Кодировка ASCII была разработана в Америке, поэтому стандартная кодировочная таблица обычно включает в себя английский алфавит с цифрами, что в общей сложности составляет около 128 символов. Но тогда возникает справедливый вопрос: что делать, если необходима кодировка национального алфавита?

    Для решения подобных вопросов были разработаны другие версии таблицы ASCII . Например, для языков с иноязычной структурой были или убраны буквы английского алфавита, или к ним добавлялись дополнительные символы в виде национального алфавита. Так, в кодировке ASCII могут присутствовать русские буквы для национального использования (см. скриншот №2).

    Где применяется система кодировки ASCII?

    Данная кодировочная система необходима не только для набора текстовой информации на клавиатуре. Она также используется в графике. Например, в программе ASCII Art Maker графические изображения различных расширений состоят из спектра символов кодировки ASCII (см. скриншот №3).


    Как правило, подобные программы можно разделить на те, что выполняют функцию графических редакторов, инвертируя изображение в текст, и на те, что конвертируют изображение в ASCII -графику. Всем известный смайлик (или как его еще называют «улыбающееся человеческое лицо ») тоже является примером кодировочного символа.

    Данный метод кодировки также может быть востребован во время написания или создания документа HTML. Например, вы вводите определённый и необходимый вам набор знаков, а при просмотре самой страницы на экран будет выведен символ, соответствующий данному коду.

    Кроме всего прочего данный вид кодировки необходим при создании многоязычного сайта, потому что знаки, которые не входят в ту или иную национальную таблицу, нужно будет заменить ASCII кодами. Если читатель непосредственно связан с информационно-коммуникативными технологиями (ИКТ), то ему будет полезно ознакомиться и с такими системами как:

    1. Переносимый набор символов;
    2. Управляющие символы;
    3. EBCDIC;
    4. VISCII;
    5. YUSCII;
    6. Юникод;
    7. ASCII art;
    8. КОИ-8.

    Свойства таблицы ASCII

    Как и любая систематизированная программа, ASCII обладает своими характерными свойствами. Так, например, десятеричная система исчисления (цифры от 0 до 9) преобразуется в двоичную систему исчисления (т.е. каждая десятеричная цифра преобразуется в двоичную 288=1001000 соответственно).

    Буквы, располагающиеся в верхних и нижних колонках, отличаются друг от друга лишь битом, что существенно снижает уровень сложности проверки и редактирование регистра.

    При всех этих свойствах кодировка ASCII работает как восьми битная, хотя изначально предусматривалась как семи битная.

    Применение ASCII в программах Microsoft Office:

    В случае необходимости данный вариант кодирования информации может быть использован в Microsoft Notepad и Microsoft Office Word. В рамках этих приложений документ может быть сохранен в формате ASCII , но в этом случае при наборе текста невозможно будет использование некоторых функций.

    В частности, будет недоступно выделение жирным и полужирным шрифтом, потому что кодирование сохраняет лишь смысл набранной информации, а не общий вид и форму. Добавить такие коды в документ вы можете с помощью следующих программных приложений.

    Кстати, на нашем сайте вы можете перевести любой текст в десятичный, шестнадцатеричный, двоичный код воспользовавшись Калькулятором кодов онлайн .

    Таблица ASCII

    ASCII (American Standard Code for Information Interchange)

    Сводная таблица кодов ASCII

    ASCII таблица кодов символов Windows (Win-1251)

    Символ

    спец. Табуляция

    спец. LF (Возвр. каретки)

    спец. CR (Новая строка)

    сцеп. SP (Пробел)

    Символ

    Расширенная таблица кодов ASCII

    Символы форматирования.

    Backspace (Возврат на один символ). Показывает на движение механизма печати либо курсора дисплея назад на одну позицию.

    Horizontal Tabulation (Горизонтальное Табулирование). Показывает движение механизма печати либо курсора дисплея до следующей предписанной "позиции табуляции".

    Line Feed (Перевод строки). Показывает движение механизма печати либо курсора дисплея к началу следующей строки (на одну строку вниз).

    Vertical Tabulation (Вертикальное Табулирование). Показывает движение механизма печати либо курсора дисплея к следующей группе строк.

    Form Feed (Перевод страницы). Показывает движение механизма печати либо курсора дисплея к исходной позиции следующей страницы, формы или экрана.

    Carriage Return (Перевод каретки). Показывает движение механизма печати либо курсора дисплея к исходной (крайней левой)позиции текущей строки.

    Передача данных.

    Start of Heading (Начало Заголовка). Применяется для определения начала заголовка, который может содержать информацию о маршрутизации или адрес.

    Start of Text (Начало Текста). Показывает начало текста и одновременно конец заголовка.

    End of Text (Конец Текста). Применяется при завершении текста, который был начат с символа STX.

    Enquiry (Запрос). Запрос идентификационных данных (типа "Кто Вы?") от удаленной станции.

    Acknowledge (Подтверждение). Приемное устройство передает этот символ отправителю в качестве подтверждения успешного приема данных.

    Negative Acknowledgement (Неподтверждение). Приемное устройство передает этот символ отправителю в случае отрицания (неудачи) приема данных.

    Synchronous/Idle (Синхронизация). Применяется в синхронизированных системах передачи. В моменты отсутствия передачи данных система непрерывно посылает символы SYN для обеспечения синхронизации.

    End of Transmission Block (Конец Блока Передачи). Показывает конец блока данных для коммуникационных целей. Применяется для разбиения на отдельные блоки больших объемов данных.

    Разделительные знаки при передаче информации.

    Другие символы.

    Null. (No character- нет данных). Применяется для передачи в случае отсутствия данных.

    Bell (Звонок). Применяется для управления устройствами сигнализации.

    Shift Out. Показывает, что все последующие кодовые комбинации должны интерпретироваться согласно внешнему набору символов до прихода символа SI.

    Shift In. Показывает, что последующие кодовые комбинации должны интерпретироваться согласно стандартному набору символов.

    Data Link Escape (Переключение). Изменение значения идущих следом символов. Применяется для дополнительного контроля или для передачи произвольной комбинации бит.

    DC1, DC2, DC3, DC4

    Device Controls (Контроль Устройства). Символы для управления вспомогательными устройствами (специальными функциями).

    Cancel (Отмена). Показывает, что данные, которые предшествовали этому символу в сообщении или блоке, должны игнорироваться (обычно в случае обнаружения ошибки).

    End of Medium (Конец Носителя). Указывает на физический конец ленты или другого носителя информации

    Substitute (Заместитель). Применяется для подмены ошибочного или недопустимого символа.

    Escape (Расширение). Применяется для расширения кода, указывая на то, что последующий символ имеет альтернативное значение.

    Space (Пробел). Непечатаемый символ для разделения слов или перемещения механизма печати или курсора дисплея вперед на одну позицию.

    Delete (Удаление). Применяется для удаления (стирания) предыдущего знака в сообщении