- •Кетков ю.Л.
 - •Раздел 5. Системные данные текстового типа 33
 - •Раздел 6. Основные синтаксические конструкции языка c 46
 - •Раздел 7. Указатели и ссылки 59
 - •Раздел 8. Функции и их аргументы 62
 - •Раздел 9. Работа с массивами. 74
 - •Раздел 10. Пользовательские типы данных. 95
 - •Раздел 11. Работа с файлами 104
 - •Раздел 12. Библиотеки стандартных и нестандартных функций 118
 - •Раздел 15. Классы. Создание новых типов данных 131
 - •Раздел 16. Классы как средство создания больших программных комплексов 150
 - •Раздел 17. Прерывания, события, обработка исключений 167
 - •Введение
 - •Раздел 1. Немного истории
 - •Раздел 2. Структура программы на языке c
 - •Раздел 3. Среда программирования
 - •Раздел 4. Системные данные числового типа
 - •4.1. Типы числовых данных и их представление в памяти эвм
 - •4.1.1. Внутреннее представление целочисленных данных
 - •4.1.2. Однобайтовые целочисленные данные
 - •4.1.3. Двухбайтовые целочисленные данные
 - •4.1.4. Четырехбайтовые целочисленные данные
 - •4.1.5. Восьмибайтовые целочисленные данные
 - •4.2. Внутреннее представление данных вещественного типа
 - •4.3. Внешнее представление числовых констант
 - •4.4. Объявление и инициализация числовых переменных
 - •4.5. Ввод числовых данных по запросу программы
 - •4.5.1. Потоковый ввод данных числового типа
 - •4.5.2. Форматный ввод
 - •4.6. Вывод числовых результатов
 - •4.6.1. Форматный вывод
 - •4.6.2. Потоковый вывод
 - •4.7. Примеры программ вывода числовых данных
 - •4.8. Операции над числовыми данными целого типа
 - •4.9. Операции над числовыми данными вещественного типа
 - •Раздел 5. Системные данные текстового типа
 - •5.1. Символьные данные и их представление в памяти эвм
 - •5.2. Строковые данные и их представление в памяти эвм
 - •5.3. Ввод текстовых данных во время работы программы
 - •5.3.1. Форматный ввод
 - •5.3.3. Потоковый ввод
 - •5.3.4. Специальные функции ввода текстовых данных
 - •5.4. Вывод текстовых данных
 - •5.4.1. Форматный вывод
 - •5.5.2. Операции над строковыми данными
 - •5.6. Управление дисплеем в текстовом режиме
 - •Раздел 6. Основные синтаксические конструкции языка c
 - •6.1. Заголовок функции и прототип функции
 - •6.2. Объявление локальных и внешних данных
 - •6.3. Оператор присваивания
 - •6.4. Специальные формы оператора присваивания
 - •6.5. Условный оператор
 - •6.6. Оператор безусловного перехода
 - •6.7. Операторы цикла
 - •6.8. Дополнительные операторы управления циклом
 - •6.9. Оператор выбора (переключатель)
 - •6.10. Обращения к функциям
 - •6.11. Комментарии в программах
 - •Раздел 7. Указатели и ссылки
 - •7.1. Объявление указателей
 - •7.2. Операции над указателями
 - •7.3. Ссылки
 - •Раздел 8. Функции и их аргументы
 - •8.1. Параметры-значения
 - •8.2. Параметры-указатели
 - •8.3. Параметры-ссылки
 - •8.4. Параметры-константы
 - •8.5. Параметры по умолчанию
 - •8.6. Функции с переменным количеством аргументов
 - •8.7. Локальные, глобальные и статические переменные
 - •8.8. Возврат значения функции
 - •8.9. Рекурсивные функции
 - •8.10. Указатели на функцию и передача их в качестве параметров
 - •8.11. "Левые" функции
 - •Раздел 9. Работа с массивами.
 - •9.1. Объявление и инициализация массивов.
 - •9.2. Некоторые приемы обработки числовых массивов
 - •9.2. Программирование задач линейной алгебры
 - •9.2.1. Работа с векторами
 - •9.2.2.Работа с матрицами
 - •9.3. Поиск
 - •9.3.1. Последовательный поиск
 - •9.3.2. Двоичный поиск
 - •9.4. Сортировка массивов.
 - •9.4.1. Сортировка методом пузырька
 - •9.4.2. Сортировка методом отбора
 - •9.4.3. Сортировка методом вставки
 - •9.4.4. Сортировка методом Шелла
 - •9.4.5.Быстрая сортировка
 - •9.5. Слияние отсортированных массивов
 - •9.6. Динамические массивы.
 - •Раздел 10. Пользовательские типы данных.
 - •10.1. Структуры
 - •10.1.1. Объявление и инициализация структур
 - •10.1.2. Структуры – параметры функций
 - •10.1.3.Функции, возвращающие структуры
 - •10.2. Перечисления
 - •10.3. Объединения
 - •Раздел 11. Работа с файлами
 - •11.1.Файлы в операционной системе
 - •11.1. Текстовые (строковые) файлы
 - •11.2. Двоичные файлы
 - •11.3. Структурированные файлы
 - •11.4. Форматные преобразования в оперативной памяти
 - •11.5. Файловые процедуры в системе bcb
 - •11.5.1. Проверка существования файла
 - •11.5.2. Создание нового файла
 - •11.5.3. Открытие существующего файла
 - •11.5.4. Чтение из открытого файла
 - •11.5.5. Запись в открытый файл
 - •11.5.6. Перемещение указателя файла
 - •11.5.7. Закрытие файла
 - •11.5.8. Расчленение полной спецификации файла
 - •11.5.9. Удаление файлов и пустых каталогов
 - •11.5.10. Создание каталога
 - •11.5.11. Переименование файла
 - •11.5.12. Изменение расширения
 - •11.5.13. Опрос атрибутов файла
 - •11.5.14. Установка атрибутов файла
 - •11.5.15. Опрос и изменение текущего каталога
 - •11.6. Поиск файлов в каталогах
 - •Раздел 12. Библиотеки стандартных и нестандартных функций
 - •12.2. Организация пользовательских библиотек
 - •12.3. Динамически загружаемые библиотеки
 - •13.1. Препроцессор и условная компиляция
 - •13.2. Компилятор bcc.Exe
 - •13.3. Утилита grep.Com поиска в текстовых файлах
 - •14.1. Переопределение (перегрузка) функций
 - •14.2. Шаблоны функций
 - •Раздел 15. Классы. Создание новых типов данных
 - •15.1. Школьные дроби на базе структур
 - •15.2. Школьные дроби на базе классов
 - •15.3. Класс на базе объединения
 - •15.4. Новые типы данных на базе перечисления
 - •15.5. Встраиваемые функции
 - •15.6. Переопределение операций (резюме)
 - •15.8. Конструкторы и деструкторы (резюме)
 - •Раздел 16. Классы как средство создания больших программных комплексов
 - •16.1. Базовый и производный классы
 - •16.1.1.Простое наследование
 - •16.1.2. Вызов конструкторов и деструкторов при наследовании
 - •16.1.3. Динамическое создание и удаление объектов
 - •16.1.4. Виртуальные функции
 - •16.1.5. Виртуальные деструкторы
 - •16.1.6. Чистые виртуальные функции и абстрактные классы
 - •16.2. Множественное наследование и виртуальные классы
 - •16.3. Объектно-ориентированный подход к созданию графической системы
 - •Раздел 17. Прерывания, события, обработка исключений
 - •17.1. Аппаратные и программные прерывания
 - •17.2. Исключения
 
5.2. Строковые данные и их представление в памяти эвм
В языке C среди базовых типов данных строк как таковых не оказалось. Вместо этого язык C предлагает использовать одномерные символьные массивы, в которых хранятся те же строки в виде последовательности однобайтовых символов, завершающихся байтом с нулевым кодом. Для этого признака конца строки в состав Escape-последовательностей включен специальный код '\0', хотя можно было бы воспользоваться и другой комбинацией – '\0x0'.
В языке C++ появился гораздо более удобный класс строковых данных string. Но знакомство с этим классом мы отложим на более поздний срок.
Значения строковых констант или начальные значения строковых "переменных" в отличие от символьных данных заключаются в двойные кавычки:
const char c1[]="ABCDEFGH";
char str1[]="1234";
char letter[]="a";
char symbol='a';
Байт с нулевым кодом система автоматически добавляет вслед за последним символом строки. Поэтому для символьного массива c1 будет выделено 9 байтов, а для символьного массива str1 – 5 байтов. Обратите внимание на то, что массив letter занимает в памяти 2 байта, тогда как символьная переменная symbol – 1 байт. Так как строка представлена одномерным массивом символов, то доступ к каждому ее символу осуществляется самым обычным способом:
c1[3] – четвертый символ в массиве c1 (т.е. буква 'D')
str1[0] – первый символ в массиве str1 (т.е. цифра '1')
Значение любого символа в строковой "переменной" можно изменить во время работы программы:
str1[3]='L';
Запись за пределы строки может непредсказуемым образом повлиять на последующую работу программы:
str1[4]=5; //Байт с признаком конца строки испорчен
str1[5]=6; //Испорчен байт с какими-то данными
5.3. Ввод текстовых данных во время работы программы
5.3.1. Форматный ввод
Список форматных указателей функции scanf предусматривает возможность ввода значений односимвольных (%c) и многосимвольных (%s) переменных:
#include <stdio.h>
void main()
{ char ch1,ch2;
char str1[10];
scanf("%c %c",&ch1,&ch2);
scanf("%s",str1);
....................
Обратите внимание на то, что для ввода данных в скалярные переменные ch1 и ch2 в списке ввода необходимо указывать их адреса (&ch1, &ch2), а при вводе в массив str1 – достаточно написать его имя. Дело в том, что имя массива одновременно выполняет роль адреса своего первого элемента. Поэтому str1 и &str1[0] указывают на один и тот же адрес.
Ввод значений символьных переменных ch1 и ch2 можно организовать одним из двух способов. Во-первых, в строке ввода можно набрать два требуемых символа либо слитно, либо разделяя их хотя бы одним пробелом и нажать клавишу Enter. Во-вторых, можно набрать первый символ, предназначенный для переменной ch1, и нажать клавишу Enter. Затем повторить аналогичным образом ввод следующего символа.
Значение, предназначенное для строковой "переменной" str1, не должно содержать более 9 символов (признак конца строки система добавляет автоматически) и среди них не должен присутствовать пробел. Дело в том, что пробел при форматном вводе воспринимается как разделитель данных. Это не означает, что среди символов строки пробел вообще не допустим, просто для организации ввода в строку нескольких слов надо использовать другие средства.
Довольно неожиданно, но с помощью задания ширины поля ввода и одного форматного указателя %с можно за один прием ввести несколько символов в элементы символьного массива:
char q[20];
............
scanf("%20c",q); //ввод 20 символов в массив q
В отличие от ввода по форматному указателю %s в массив q здесь не записывается признак конца строки – вводятся только запрашиваемые символы, которые набираются в одной строке с последующим нажатием клавиши Enter.
Функция scanf предусматривает еще два интересных форматных указателя, которые обеспечивают ввод либо тех символов, которые указаны в заданном множестве, либо всех символов, которые не принадлежат заданному множеству. Например, для ввода цифр из диапазона от 0 до 9 такой указатель имеет вид %[0-9], а для ввода символов, не являющихся цифрами – %[^0-9]. Рассмотрим следующий пример, который не только демонстрирует ввод по таким форматным указателям, но и содержит непредвиденный пассаж, связанный с использованием "грязного" буфера ввода.
#include <stdio.h>
#include <conio.h>
void main()
{ char str[10];
int j;
printf("Enter 123ABC\n");
scanf("%[0-9]",str);
printf("str=%s\n",str);
for(j=0; j<10; j++)
printf("%3x",str[j]);
printf("\nEnter DEF123\n");
scanf("%[^0-9]",str);
printf("str=%s"\n,str);
for(j=0; j<10; j++)
printf("%3x",str[j]);
getch();
}
//=== Результат работы ===
Enter 123ABC
str=123
31 32 33 0 0 1 0 0 1 0
Enter DEF123
str=ABC
DEF
41 42 43 a 44 45 46 0 1 0
После ввода первой строки программе были переданы символы '123', вслед за которыми в массив str был записан нулевой байт – признак конца строки. Однако в буфере ввода остались невостребованными символы 'ABC' и код клавиши Enter (код 0xa). После набора второй строки к содержимому буфера ввода добавились еще три символа 'DEF' и т.к. все семь первых символов не являются кодами цифр, то все они были переданы в массив str. При выводе первые три отобразились в одной строке, затем сработал управляющий код 0xa и три следующие символа были выведены в следующей строке. Для наглядности содержимое массива после каждого вывода по формату %s отображалось еще и в шестнадцатеричном формате.
Чтобы не пострадать от непредвиденного ввода символов, задержавшихся в буфере ввода, рекомендуется после обращения к функции scanf чистить буфер ввода с помощью функции fflush(stdin). Если бы мы включили в предыдущий пример обращение к функции fflush, то после ввода второй строки в массиве str оказались бы только символы 'DEF' .
