- •Кетков ю.Л.
- •Раздел 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. Исключения
6.4. Специальные формы оператора присваивания
Следующая группа операторов присваивания обязана своим происхождением формату машинных команд в двухадресных машинах:
COD A1,A2
Здесь COD – код машинной операции;
A1,A2 – адреса ячеек оперативной памяти и/или арифметических регистров.
Результат выполнения такой операции над содержимым A1 и A2 записывается по адресу A1 (A1=A1A2). По аналогии с такой записью в языках C, C++ появилась следующая синтаксическая конструкция:
v = exp; //вместо v = v exp;
Здесь символ обозначает один из следующих знаков двухместных операций:
+,-,*,/,%,<<,>>,&,|,^
Например:
x += 2; //вместо x=x+2;
z /= 1.5; //вместо z=z/1.5;
Довольно экзотически выглядит оператор присваивания, в правой части которого через запятую задана последовательность некоторых действий. Например:
x=(y=sin(a+b),z=cos(a-b),max(y,z));
Действия в скобках выполняются слева направо, т.е. сначала будет вычислено значение sin(a+b), которое занесут в переменную y, затем будет вычислено значение переменной z. Окончательным результатом скобки, которое будет присвоено переменной x, станет вычисление значения функции max(y,z).
6.5. Условный оператор
С помощью условного оператора в программе можно создать две альтернативные цепочки операторов, выполнение каждой из которых происходит в зависимости от истинности или ложности заданного условия:
if(условие) {S1; S2;...} [else {Q1;Q2;...}]
Если условие, указанное в круглых скобках истинно, то выполняется цепочка операторов S1, S2,… . В противном случае выполняется цепочка операторов Q1,Q2,… . Альтернативная ветвь вместе со служебным словом else может отсутствовать. И тогда речь идет о выполнении или обходе цепочки операторов S1,S2,… .
Простейшие условия задаются в виде проверки соотношения двух однотипных выражений:
if(a>b) cout<<a; else cout<<b;
if(x>=0) y=sqrt(x);
Напомним, что операции отношения в языках C, C++ обозначаются следующими символами и их комбинациями:
== |
равно |
!= |
не равно |
> |
больше |
>= |
больше или равно |
< |
меньше |
<= |
меньше или равно |
Более сложные условия могут составляться из элементарных соотношений с помощью логических операций "ИЛИ" (||), "И" (&&), "НЕ" (!). Например, проверка принадлежности x диапазону [a,b] выглядит следующим образом:
if(a<=x && x<=b) ...
В качестве логического условия иногда можно встретить в круглых скобках обычное арифметическое выражение:
if(a)...
В языке C логические переменные отсутствуют. Вместо этого действует соглашение о том, что ложь эквивалентна нулевому значению числового выражения, а истина – не нулевому значению. Поэтому приведенная выше проверка эквивалентна соотношению:
if(a != 0)...
6.6. Оператор безусловного перехода
Перед любым исполняемым оператором программы может находиться символьная метка, отделяемая от оператора двоеточием:
m5: printf("\nx=%f",x);
На помеченный таким образом оператор может быть передано управление с помощью оператора goto m5. Но такие переходы допустимы только внутри функции. Переход из одной функции в другую по оператору goto недопустим.
В ряде книг можно встретить утверждение, что пользоваться этим оператором ни в коем случае нельзя. Однако это не так. Оператором goto пользоваться можно, а вот злоупотреблять им действительно не рекомендуется. Бездумное и неумеренное использование операторов goto приводит к появлению программ трудных для понимания, обладающих запутанной логикой, мало пригодных к внесению изменений.
Рассмотрим две реализации программы, которая вводит три целочисленных значения и выводит максимальное из них. В первой из них (программа-спагетти) на 10 исполняемых строк приходится 5 операторов goto. Во второй реализации потребовалось всего 5 исполняемых строк и ни одного оператора goto.
Пример 6.1. Программа-спагетти.
#include <stdio.h>
#include <conio.h>
void main()
{ int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(a>b) goto m1;
if(b>c) goto m2;
m3: printf("max=%d",c);
goto m5;
m1: if(c>a) goto m3;
m4: printf("max=%d",a);
goto m5;
m2: printf("max=%d",b);
m5: getch();
}
Пример 6.2. Пример прозрачной логики
#include <stdio.h>
#include <conio.h>
void main()
{ int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(b>a) a=b;
if(c>a) a=c;
printf("max=%d",a);
getch();
}
Одним из случаев, когда применение оператора goto приводит к более простой и более эффективной программе является необходимость выйти из внутреннего цикла за пределы внешнего цикла:
int i,j;
for(i=0; i<n; i++) {...
for(j=0; j<20; j++) {...
if(условие_выхода) goto mm;
}
}
mm:
Конечно, можно придумать более запутанную схему, не используя goto:
int i,j,k=1;
for(i=0; i<n && k; i++) {...
for(j=0; j<20 && k; j++) {...
if(условие_выхода) {k=0; break;}
}
}
Применяя оператор goto, стоит следовать следующим рекомендациям:
не входить внутрь блока извне, особенно если в начале этого блока присутствуют объявления локальных переменных с инициализацией;
не входить в цикл извне, ибо это приведет к неправильной работе цикла;
не передавать управление внутрь условного оператора;
не передавать управление внутрь переключателя.