Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информационные преобразования числовых форматов....doc
Скачиваний:
3
Добавлен:
13.11.2018
Размер:
333.31 Кб
Скачать

Символьные преобразования числовой информации

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

Ниже представлена программа C7, в которой целое положительное число переводится и формата unsigned int в формат символьного массива. Каждый символ отображает один бит исходного числа. В программе применяется технологический прием рекурсивной функции IntChar( ). Это удобный прием для теории программирования, однако в приложениях он не всегда находит применение, поскольку реализация рекурсивной функции сопровождается значительными временными затратами, связанными с размещениями очередного экземпляра вызова функции IntChar( ) в стеке параметров операционной системы. Задача функции IntChar( ) в некотором смысле совпадает с назначением ранее обсуждавшейся функции BinaryInt( ) (стр.11), которая не является рекурсивной. Разница лишь в том, что функция BinaryInt( ), получает результат на мониторе, в функция IntChar( ) – в массиве.

// Program C7

// Символьный вид положительного целого числа

// Рекурсивная функция

#include <stdio.h> // printf, scanf

#include <conio.h> // getch

#include <string.h> // strcat_s

void IntChar( unsigned int n, char* s )

{ if( n > 1 ) IntChar( n >> 1, s ); // поиск

( n & 1 ) == 0 ? strcat_s( s, 32, "0" )

: strcat_s( s, 32, "1" );

}

//---------------------------------------------------

void main( void )

{ unsigned int n; // для целого числа

char s[32] = { '\0' };// пустой символьный массив

printf( "n = " ); scanf( "%d", &n );// ввод числа

IntChar( n, s);//символьный массив двоичного кода

printf( "st = %s", s ); // монитор

getch(); // просмотр результата

}

Если при выполнении программы C7 ввести произвольное цело число, например 37, то следующие строки появляются на мониторе

n = 37

s = 100101

Функция IntChar( ) преобразует число типа unsigned int в символьный массив. Конструкция объявления параметров содержит исходное число unsigned int n и указатель на символьный массив char* s. Особенность преобразования в том, что символ для бита 0 в исходном числе должен быть последним в массиве. Для этого в теле функции IntChar( ) исходное число сдвигается на 1 бит влево и запоминается в стеке параметров следующего экземпляра выполнения рекурсивного вызова функции IntChar( ). Рекурсия выполняется до тех пор, пока очередной сдвинуты экземпляр исходного числа существует if( n > 1 ) IntChar( n >> 1, s ). В этом смысле рекурсивный вызов функции IntChar( ) осуществляет поиск старшей битовой 1 в исходном числе. Вместо сдвига можно применить деление if( n > 1 ) IntChar( n / 2, s ), но операция деления занимает больше времени, чем сдвиг, и хорошие компиляторы обязательно учитывают это.

Когда рекурсия приведет алгоритм к ситуации не выполнения условия n > 1, тогда все экземпляры функции IntChar( ) начнут выполнять следующую инструкцию, в которой бит 0 соответствующего сдвинутого экземпляра n содержит необходимую информацию, преобразуемую в соответствующий символ

( n & 1 ) == 0 ? strcat_s( s, 32, "0" )

: strcat_s( s, 32, "1" );

Системная функция strcat_s( ) присоединяет символ 0 или 1 в конец массива s, передвигая автоматически 0-окончание массива. Каждый переход к предыдущему экземпляру рекурсии IntChar( ) операционная система выполняет самостоятельно, разгружая стек параметров функций. Выполнение функции IntChar( ) завершено. Символьный массив s создан.

В следующей программе C8 положительное десятичное целое число вводится с клавиатуры в массив и затем преобразуется в двоичное число типа unsigned int. Идея алгоритма состоит в том, что каждая цифра десятичного числа умножается на соответствующий позиционный коэффициент , , и т. д. Коэффициенты можно получать путем умножения предыдущего коэффициента на 10. Получающиеся значения полиномиально складываются (1).

// Program C8

// Преобразование целого положительного десятичного

// числа из символьного вида в тип unsigned int

#include <stdio.h> // printf

#include <conio.h> // getch

unsigned int CharInt( char* s )

{ int i; // индекс символа

for( i = 0; s[i] != '\0'; i++ ); // конец строки

int n = 0; // для результата

int k = 1; // позиционный множитель

for( --i; i >= 0; i--)//просмотр от младшей цифры

{ int z = s[i] - 48; // цифра минус код '0'

n += k * z; // позиционное накопление числа

k *= 10; // множитель следующей позиции

}

return n; // результат

}

//---------------------------------------------------

void main( void )

{ char s[32];// для символьного представления числа

printf( "s = " ); scanf( "%s", s ); // ввод числа

printf( "s = %s", s ); // монитор

unsigned int n = CharInt(s);//char - unsigned int

printf( "\nn = %d", n ); // монитор

getch(); // просмотр результата

}

Если при выполнении программы C8 ввести произвольное число, например 37, то следующие строки появляются на мониторе

s = 37

s = 37

n = 37

Функция CharInt( ) возвращает число типа unsigned int. Конструкция объявления параметров содержит указатель на массив char* s, в котором находятся цифры-символы исходного десятичного целого положительного числа. В теле функции CharInt( ) используется переменная int i в качестве индекса символов массива s. 0-окончание массива s определяется в инструкции цикла for( i = 0; s[i] != '\0'; i++ ). Для результата преобразований отводится переменная unsigned int n = 0. Начальное значение позиционного множителя-коэффициента задается в переменной int k = 1.

Массив s просматривается в обратном порядке под управлением заголовка цикла for( --i; i >= 0; i-- ) для индексирования символов s[i]. В теле цикла вычисляется двоичный код z десятичных цифр int z = s[i] – 48. Константа 48 соответствует коду цифры 0. Получающееся число задается суммой слагаемых n += k * z полинома (1). Коэффициент множителя следующей позиции вычисляется как k *= 10. Тело цикла завершено.

В последней инструкции накопленная сумма return n возвращается как результат выполнения функции CharInt( )

В качестве самостоятельного упражнения рекомендуем создать аналогичные функции для преобразования вещественного числа типа float в символьный вид и наоборот. Некоторое мастерство придется проявить с поиском позиции дробной точки и раздельного преобразования целой и дробной части с последующим соединением в мантиссе. Двоичный вид дробной части можно получить, непосредственно используя алгоритм преобразования дроби (стр. 14).