Внешнее представление числовых констант

В программах на языках C, C++ встречаются литеральные и именованные числовые константы целого или вещественного типа. Числовые константы, употребляемые в тексте программ в арифметических или логических выражениях, называют литеральными. Они представлены числовыми литерами – цифрами, знаками + или –, точками, отделяющими целую часть числа от дробной, показателями десятичного порядка. Например:

x=-25; //целочисленная константа -25

y=y+2.4; //вещественная константа в форме с фиксированной запятой

z=2.1e-6;// вещественная константа в форме с плавающей запятой

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

#define Nmax 100

const double eps=1e-6;

..................

int a[Nmax]

..................

for(i=0; i<Nmax; i++)

....................

if(abs(z)<eps)...

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

Под внешним представлением числовой информации мы подразумеваем способы записи данных, используемые в текстах программ, при наборе чисел, вводимых в ЭВМ по запросу программы, при отображении результатов на экране дисплея или на принтере.

Наличие в естественной записи числа точки (3.1415) или указателя десятичного порядка (314.159265e-02, 314.159265E-02) означает, что соответствующее значение представлено в ЭВМ в виде вещественного числа с плавающей запятой.

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

В алгоритмическом языке C активно используются как префиксы, так и суффиксы:

0x5,0X5 – шестнадцатеричное целое число (префикс – 0x или 0X);

05 – восьмеричное целое число (префикс – незначащий нуль в начале);

5H,5h – короткое целое число (суффикс – h или H от sHort)

5U,5u – целое число без знака (суффикс – u или U, от Unsigned);

5HU,5hu,5Hu,5hU – короткое целое число без знака;

5L ,5l – длинное целое число (суффикс – l или L, от Long);

5LU,5lu,5Lu,5lU – длинное целое число без знака;

5f,5F – короткое вещественное число (суффикс – f или F, от Fixed);

5LF,5FL,5fl,5lf,5Lf,5lF,5Fl,5fL – длинное вещественное число.

Входной язык системы визуального программирования BCB дополнительно позволяет использовать следующие суффиксы:

i8 – для однобайтовых целых чисел со знаком (например, 127i8)

i16 – для двухбайтовых целых чисел со знаком;

i32 – для четырехбайтовых целых чисел со знаком;

i64 – для восьмибайтовых целых чисел со знаком;

ui64 – для восьмибайтовых целых чисел без знака.

Параметры-константы

В заголовках некоторых функций можно встретить объявление формального параметра с добавлением служебного слова const. Это означает, что в теле программы значение формального параметра меняться не должно. Но ведь тот программист, который пишет тело функции, вряд ли захочет по собственной воле изменять значение параметра, зная, что компилятор предупредит такую ошибку. В чем же смысл объявления некоторых параметров константными?

Оказывается, в этом скрывается некоторая уловка – если параметр объявлен как константная ссылка, то в качестве фактического аргумента в этом случае можно задавать не только имя переменной, но и выражение. Таким образом, параметр-ссылка уподобляется параметру-значению. Правда, при этом значение фактического аргумента не попадает в стек. Оно вычисляется и помещается в некоторую скрытую переменную в теле вызывающей функции. А вызываемой функции сообщается адрес этой скрытой переменной, что не меняет логику работы со ссылками. Но запись по этому адресу будет блокирована.

Билет 10

Текстовые файлы в языке Си. Функции fprintf и fscanf.

Текстовые (строковые) файлы

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

Текстовые файлы относятся к файлам последовательного доступа, т.к. единицей хранения информации в них являются строки переменной длины. Каждая строка заканчивается специальным признаком, обычно его функцию выполняет пара символов 0D0A – "возврат каретки" и "перевод строки". Самым важным преимуществом текстовых файлов является универсальность формата хранения информации – числовые данные в символьном виде доступны на любом компьютере, при необходимости их может прочитать и человек. Однако это преимущество имеет и обратную сторону медали – преобразование числовых данных из машинных форматов в символьный вид при выводе и обратное преобразование при вводе сопряжено с дополнительными расходами. Кроме того, объем числовых данных в символьном формате занимает в несколько раз больше памяти по сравнению с их машинным представлением.

Текстовый файл может быть создан путем записи на диск символьных и/или числовых данных по заданному формату с помощью оператора fprintf. В качестве признака конца строки здесь заносятся те же самые байты 0D0A , которые появляются на диске в результате вывода управляющего символа \n.

Для инициализации текстового файла необходимо завести указатель на структуру типа FILE и открыть файл по оператору fopen в одном из нужных режимов – "rt" (текстовый для чтения), "wt" (текстовый для записи), "at" (текстовый для дозаписи в уже существующий набор данных):

FILE *f1;

.........

f1=fopen(имя_файла, "режим");

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

fscanf(f1,"список_форматов", список_ввода);

fprintf(f1,"список_форматов \n",список_вывода);

Если очередная строка текстового файла формируется из значения элементов символьного массива str, то вместо функции fprintf проще воспользоваться функцией fputs(f1, str). Чтение полной строки из текстового файла удобнее выполнить с помощью функции fgets(str,n,f1). Здесь параметр n означает максимальное количество считываемых символов, если раньше не встретится управляющий байт 0A.

Библиотека C предусматривает и другие возможности для работы с текстовыми файлами – функции open, creat, read, write.

Пример 1. Рассмотрим программу, которая создает в текущем каталоге (т.е. в каталоге, где находится наша программа) текстовый файл с именем c_txt и записывает в него 10 строк. Каждая из записываемых строк содержит символьное поле с текстом "Line" (5 байт, включая нулевой байт – признак конца строки), пробел, поле целочисленного значения переменной j, пробел и поле вещественного значения квадратного корня из j. Очевидно, что числовые поля каждой строки могут иметь разную длину. После записи информации файл закрывается и вновь открывается, но уже для чтения. Для контроля содержимое записываемых строк и содержимое считанных строк дублируется на экране.

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <conio.h>

main( )

{

FILE *f; //указатель на блок управления файлом

int j,k;

double d;

char s[]="Line";

f=fopen("c_txt","wt"); //создание нового или открытие существующего

// файла для записи

for(j=1;j<11;j++)

{

fprintf(f,"%s %d %lf\n",s,j,sqrt(j)); //запись в файл

printf("%s %d %lf\n",s,j,sqrt(j)); //вывод на экран

}

fclose(f); //закрытие файла

printf("\n");

f=fopen("c_txt","rt"); //открытие файла для чтения

for(j=10; j>0; j--)

{

fscanf(f,"%s %d %lf",s,&k,&d); //чтение из файла

printf("%s %d %lf\n",s,k,d); //вывод на экран

}

getch();

}

//== Результат работы ===

Line 1 1.000000

Line 2 1.414214

Line 3 1.732051

Line 4 2.000000

Line 5 2.236068

Line 6 2.449490

Line 7 2.645751

Line 8 2.828427

Line 9 3.000000

Line 10 3.162278

Line 1 1.000000

Line 2 1.414214

Line 3 1.732051

Line 4 2.000000

Line 5 2.236068

Line 6 2.449490

Line 7 2.645751

Line 8 2.828427

Line 9 3.000000

Line 10 3.162278

Обратите внимание на возможную ошибку при наборе этой программы. Если между форматными указателями %s и %d не сделать пробел, то в файле текст "Line" склеится с последующим целым числом. После этого при чтении в переменную s будут попадать строки вида "Line1", "Line2", , "Line10", в переменную k будут считываться старшие цифры корня из j (до символа "точка"), а в переменной d окажутся дробные разряды соответствующего корня. Тогда результат работы программы будет выглядеть следующим образом:

Line1 1.000000

Line2 1.414214

Line3 1.732051

Line4 2.000000

Line5 2.236068

Line6 2.449490

Line7 2.645751

Line8 2.828427

Line9 3.000000

Line10 3.162278

Line11 0.000000

Line21 0.414214

Line31 0.732051

Line42 0.000000

Line52 0.236068

Line62 0.449490

Line72 0.645751

Line82 0.828427

Line93 0.000000

Line103 0.162278

При считывании данных из текстового файла надо следить за ситуацией, когда данные в файле исчерпаны. Для этой цели можно воспользоваться функцией feof:

if(feof(f1))... //если данные исчерпаны

Наши рекомендации