
- •Часть 1
- •Общие сведения Сведения об эумк
- •Методические рекомендации по изучению дисциплины
- •Рабочая учебная программа
- •Учреждение образования
- •«Белорусский государственный университет
- •Информатики и радиоэлектроники»
- •Часть 2 __184__
- •Содержание дисциплины
- •1. Индивидуальные практические занятия, их характеристика
- •2. Контрольные работы, их характеристика
- •3. Курсовой проект, его характеристика
- •4. Литература
- •4.1. Основная
- •4.2. Дополнительная
- •5. Перечень компьютерных программ, наглядных и других пособий, методических указаний и материалов и технических средств обучения
- •Протокол согласования учЕбной программы по изучаемой учебной дисциплине с другими дисциплинами специальности
- •Теоретический раздел Введение
- •1. Основные типы данных
- •1.1. Общие сведения
- •1.2. Данные типа int
- •1.3. Данные типа char
- •1.4. Модификаторы доступа const и volatile
- •1.5. Данные вещественного типа (с плавающей точкой)
- •1.6. Элементарный ввод-вывод
- •1.7. Структура простой программы на языке Си
- •2. Операции и выражения
- •2.1. Выражение и его интерпретация
- •2.2. Основные операции
- •2.2.1. Арифметические операции
- •2.2.2. Побитовые логические операции
- •2.2.3. Операции сдвига
- •2.2.4. Операция присваивания
- •2.2.5. Операция sizeof
- •2.2.6. Преобразование типов в выражениях
- •2.2.7. Операция преобразования типов
- •2.2.8. Приоритеты в языке Си
- •3. Операторы управления вычислительным процессом
- •3.1. Оператор if
- •3.2. Операции отношения
- •3.3. Логические операции
- •3.4. Операция запятая
- •3.5. Операция условия ?:
- •3.6. Оператор безусловного перехода goto
- •3.7. Оператор switch
- •`` ` `3.8. Операторы цикла
- •3.8.1. Оператор for
- •3.8.2. Оператор while
- •3.8.3. Оператор do...While
- •3.9. Оператор break
- •3.10. Оператор continue
- •4. Массивы и указатели
- •4.1. Одномерные массивы и их инициализация
- •4.2. Многомерные массивы и их инициализация
- •4.3. Объявление указателей
- •4.4. Операции над указателями
- •1) Взятие адреса
- •2) Косвенная адресация или разыменование указателя
- •3) Увеличение или уменьшение значения указателя на целое число
- •4) Разность указателей
- •5) Сравнение указателей
- •6) Присваивание указателей друг другу
- •4.6. Связь между указателями и массивами
- •4.7. Динамическое распределение памяти
- •4.8. Массивы указателей
- •5. Функции
- •5.1. Общие сведения
- •5.2. Область видимости переменных
- •5.2.1. Локальные переменные
- •5.2.2. Глобальные переменные
- •5.3. Передача параметров в функцию
- •5.4. Рекурсивные функции
- •5.5. Использование функций в качестве параметров функций
- •5.6. Указатели на функции
- •5.7. Структура программы на Си
- •5.8. Передача параметров в функцию main()
- •6. Строки
- •7. Классы хранения и видимость переменных
- •7.1. Общие сведения
- •7.2. Автоматический класс хранения (auto)
- •7.3. Регистровый класс хранения (register)
- •7.4. Статический класс хранения (static)
- •7.5. Внешний класс хранения (extern)
- •7.6. Заключение
- •8. Структуры, объединения и перечисления
- •8.1. Общие сведения
- •8.2. Инициализация структурных переменных
- •8.3. Вложенные структуры
- •8.4. Указатели на структуры
- •8.5. Массивы структурных переменных
- •8.6. Передача функциям структурных переменных
- •8.7. Оператор typedef
- •8.8. Поля битов в структурах
- •8.9. Объединения
- •8.10. Перечисления
- •9. Динамические структуры данных
- •9.1. Общие сведения
- •9.2. Связные списки
- •9.2.1. Односвязные списки
- •9.2.2. Двусвязные списки
- •9.2.3. Циклические списки
- •9.3. Стеки
- •9.4. Очереди
- •9.5. Деревья
- •9.5.1. Понятие графа
- •9.5.2. Бинарные деревья
- •10. Файлы
- •10.1. Общие сведения
- •10.2. Открытие и закрытие файлов
- •10.3. Функции ввода-вывода для работы с текстовыми файлами
- •10.4. Произвольный доступ к файлу
- •10.5. Функции ввода-вывода для работы с бинарными файлами
- •11. Директивы препроцессора
- •11.1. Основные понятия
- •11.2. Директива #include
- •11.3. Директивы препроцессора #define и #undef
- •11.3.1. Символические константы
- •11.3.2. Макросы с параметрами
- •11.3.3. Директива #undef
- •11.4. Условная компиляция
- •11.5. Директивы # и ##
- •12. Модульное программирование
- •13. Введение в объектно-ориентированное программирование
- •13.1. Постановка задачи
- •13.2. Решение задачи средствами Си
- •13.5. Наследование
- •13.6. Перегрузка
- •13.7. Ссылочный тип
- •Литература
- •Приложение 1. Рекомендации по оформлению текстов программ
- •Тесты к теоретическому разделу Вопросы к разделу 1. Основные типы данных
- •Вопросы к разделу 2. Операции и выражения
- •Вопросы к разделу 3. Операторы управления вычислительным процессом
- •Вопросы к разделу 4. Массивы и указатели
- •Вопросы к разделу 5. Функции
- •Вопросы к разделу 6. Строки
- •Вопросы к разделу 7. Классы хранения и видимость переменных
- •Вопросы к разделу 8. Структуры, объединения и перечисления
- •Вопросы к разделу 9. Динамические структуры данных
- •Вопросы к разделу 10. Файлы
- •Вопросы к разделу 11. Директивы препроцессора
- •Вопросы к разделу 12. Модульное программирование
- •Вопросы к разделу 13. Введение в ооп
- •Правильные ответы на вопросы тестов к теоретическому разделу
- •Вопросы к теоретическому зачету
- •Варианты индивидуальных заданий
- •Контрольная работа №2
- •Варианты индивидуальных заданий
- •Индивидуальные практические работы Указания к выбору варианта индивидуальных практических работ
- •Индивидуальная практическая работа № 1. Массивы и строки
- •Варианты индивидуальных заданий
- •Индивидуальная практическая работа № 2. Динамические структуры данных
- •Варианты индивидуальных заданий
Литература
1. Бахтизин В.В., Глухова Л.А. и др. Методические указания по вычислительной практике и самостоятельной работе по курсам "Программирование" и "Конструирование программ и языки программирования" для студентов специальности "Вычислительные машины, комплексы, системы и сети", "Программное обеспечение ЭВМ и автоматизированных систем", Части 1, 2, 3, 4. - Мн.: МРТИ, 1989-1992.
2. Бахтизин В.В., Глухова Л.А. Лабораторный практикум по курсам "Конструирование программ и языки программирование" и "Программирование". Часть 3. Программирование на языке Си в среде Турбо для ПЭВМ. - Мн.: БГУИР, 1993.
3. Берри Р., Микинз Б. Язык Си. Введение для программистов. - М.: Финансы и статистика, 1988.
4. Болски М.И. Язык программирования Си. - М.: Радио и связь, 1988.
5. Касаткин А.И., Вальвачев А.И. От Turbo C к Borland C++. - Мн.: Высш. школа, 1992.
6. Керниган Б., Ритчи Л., Фьюер А. Язык программирования Си. Задачи по языку СИ. - М.: Финансы и статистика, 1985.
7. Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: Построение и анализ. – СПб, 2003.
8. Универ Р. Язык Тurbo C. - М.: Мир, 1991.
9. Уэйт М., Прата С., Мартин Д. Язык СИ. - М., 2002.
10. Хенкок Я., Кригер М. Введение в программирование на языке Си. - М.: Радио и связь. - М.: Мир, 1993.
11. Шелест В.Д. Программирование: Структурный подход. Алгоритмы. Turbo Pascal. Borland C++. Современный Fortran. – СПб, 2003.
12. Юлин В.А., Булатова И.Р. Приглашение к Си. - Мн.: Выш. школа, 1990.
Приложение 1. Рекомендации по оформлению текстов программ
Создание программных средств представляет собой сложный процесс, состоящий из множества этапов. На каждом из этих этапов есть свои факторы, влияющие на качество получаемого продукта. Например, при проектировании программного средства важную роль играет квалификация разработчика, его опыт работы в соответствующей сфере, владение теоретическими сведениями из предметной области. При написании кода программы требуется умение грамотно реализовывать заранее продуманные алгоритмы на выбранном для разработки языке программирования. Когда речь заходит о сопровождении программного средства, на передний план выходит качество сопроводительной документации.
Таким образом, получается довольно широкий список требований, которым должен удовлетворять программист для создания качественного продукта. Для больших проектов этот список также пополняется рядом психологических качеств, таких как, например, умение работать в команде. Однако, как показывает практика, даже если над проектом работают высококлассные специалисты, идеально удовлетворяющие нашему «портрету», – это необязательно означает, что их сотрудничество будет продуктивным. Не говоря уже о программах, над которыми работает один человек.
Чтобы хотя бы частично решить эту проблему, в различных компаниях, занимающихся разработкой ПО, а также внутри отдельных групп разработчиков принимаются единые требования к оформлению исходного кода программ. Эти требования представляют собой набор правил, регламентирующих то, как должны быть оформлены отдельные языковые конструкции и их совокупности, каким образом следует выделять те или иные части программы и т.п. На выбор правил оказывает влияние множество объективных и субъективных факторов, поэтому единых правил до сих пор не существует, а на просторах сети Internet не утихают споры по отдельным вопросам оформления кода.
В этом методическом пособии читателю предлагается один из возможных стилей оформления кода программы. Приведённые далее и используемые во всём методическом пособии правила были подобраны таким образом, чтобы
а) не зависеть от конкретной среды разработки;
б) максимально полно отражать семантику языковых конструкций;
в) способствовать повышению читаемости исходного кода.
Несмотря на то, что правила сформулированы с использованием слов «должны», «следует», они носят лишь рекомендательный характер.
Комментарии
Для записи комментариев в исходном коде программ допускаются оба варианта: /**/ и //. Между тем, чаще всего используются однострочные комментарии //, что обусловлено необходимостью введения пояснений для небольших участков кода.
При комментировании фрагментов программ, содержащих операторы языка Си, рекомендуется использовать многострочный вариант /**/. Это позволяет, например, сократить реально компилируемый код до минимального размера, а затем, постепенно снимая комментарии с отдельных блоков кода, отслеживать момент появления ошибок времени выполнения, т.е. позволяет упростить отладку программы.
Основные операции
В общем случае используется свободная форма записи выражений. Между тем, рекомендуется и встречается чаще вариант с использованием пробелов для отделения знака операции от операндов, поскольку это в ряде случаев позволяет повысить читаемость кода.
a = b * x;
В типичных фрагментах программы, не содержащих логически сложных выражений, это правило может не соблюдаться.
for (i=1; i<=10; i++) ...
Число пробелов, предваряющих бинарный оператор, должно в точности совпадать с числом пробелов, следующих за ним. Рекомендуется применять 1 пробел.
В ряде случаев отдельные части выражения могут не содержать пробелов, например, при записи математической формулы, описывающей многочлен n-го порядка операция умножения коэффициента на степень аргумента может быть записана так:
y = 9*x*x + 5*x + 3;
Разбиение выражения на несколько строк допускается лишь в случае записи длинных выражений, не помещающихся целиком на экране. При этом следует вводить разрыв в той части выражения, где имеется наименьшая вложенность скобок.
Неудачный вариант |
Предпочтительный вариант |
a = b - (c + 5 / d) – (e + f / h * j)); |
a = b - (c + 5 / d) – (e + f / h * j)); |
При разрыве выражения в правой части оператора присваивания рекомендуется продолжать выражение в следующей строке начиная с позиции под первым символом выражения в предыдущей строке (см. предпочтительный вариант выше).
Кроме того, не рекомендуется разрыв выражения вблизи оператора деления /, поскольку в таком применении его можно перепутать с обратным слешем \, используемым для разрыва строк.
Скобочные выражения
Выражение, заключённое в скобки, представляет собой единую конструкцию, которая в дальнейшем может рассматриваться как одиночный операнд. Таким образом, выделение пробелами для скобочных выражений ничем не отличается от описанного выше.
Внутреннее выражение от скобок пробелами не отделяется. Таким образом подчёркивается взаимосвязь скобок с их содержимым и независимость значения содержимого скобок от операндов и операций, расположенных за скобками.
Неудачный вариант |
Предпочтительный вариант |
a = b + ( c * d ) – ( e / f ) |
a = b + (c * d) – (e / f) |
Условный оператор
Условный оператор if-else предполагает наличие одного или двух «подчинённых» операторов. «Подчинённые» операторы записываются с дополнительным отступом от левого края экрана.
if (x < 0)
y = -x;
else
y = x;
Для сокращённой формы оператора (без else-блока) оформление отступов сохраняется.
При использовании составных операторов операторные скобки записываются в отдельных строках. Операторные скобки {} дополнительным отступом не предваряются. Введение дополнительных отступов одновременно для операторных скобок и операторов, составляющих блок, не способствует повышению читаемости, но при этом приводит к излишнему смещению значимых фрагментов кода вправо.
Неудачные варианты |
Предпочтительный вариант |
if (a == b) { printf(“Equal\n”); x = a + b; } else { printf(“Not equal\n”); x = b + 3*a; }
|
if (a == b) { printf(“Equal\n”); x = a + b; } else { printf(“Not equal\n”); x = b + 3*a; } |
if (a == b) { printf(“Equal\n”); x = a + b; } else { printf(“Not equal\n”); x = b + 3*a; }
|
|
if (a == b) { printf(“Equal\n”); x = a + b; } else { printf(“Not equal\n”); x = b + 3*a; }
|
|
if (a == b) { printf(“Equal\n”); x = a + b; } else { printf(“Not equal\n”); x = b + 3*a; } |
В столбце «Неудачный вариант» приведено несколько вариантов, не рекомендуемых к применению.
Операторы циклов
Оператор while записывается по тем же правилам, что и условный оператор if без else-блока.
a = 1;
while (a < 3)
printf(“%d\n”,a++);
a = 1;
while (a < 3)
{
printf(“%d\n”,a);
a++;
}
Оператор do-while от while отличается тем, что, фактически, представляет собой операторные скобки. Тем самым, этот оператор выбивается из общего ряда операторов. Тем не менее, рекомендуется следующий вариант оформления цикла do-while.
i = 1;
do
{
printf(“%d\n”,i);
i++;
}
while (i > 3);
Цикл for оформляется аналогично while, за исключением заголовочной части. Заголовок цикла for рекомендуется записывать следующим образом:
for (i=100, j=3; i<2, j>5; i--, j++)
printf(“%d %d\n”,i,j);
Объявления переменных
При объявлении переменных отступ слева устанавливается таким же, как и для операторов данного уровня вложенности. Допускается отдельное выравнивание типов переменных и их имен.
int intVar;
char charVar;
float floatVar;
double doubleVar;
long int longVar;
При объявлении указателей символ * «прижимается» к имени переменной, а не к типу. Это позволяет избежать проблем, связанных с объявлением нескольких указателей в одной строке.
char *s1, *s2;
int *n;
Функции
Прототип функции рекомендуется записывать в полной форме, с указанием имён параметров, т.к. это позволяет упростить использование модуля, содержащего функцию, другими программистами, а также способствует самодокументированию кода.
Скобки, содержащие список параметров, «прижимаются» к имени функции. Этим подчёркивается тесная связь параметров функции и её имени.
Если функция возвращает указатель, то символ * по отношению к имени функции размещается так же, как и по отношению к имени переменной при объявлении указателя.
void *my_malloc(int blockSize);
Аналогичным образом оформляется и вызов функции: пробел перед скобками с параметрами функции не ставится.
int *p;
p = my_malloc(500);
Вызов функции может рассматриваться как одиночный операнд и встраивается в выражение соответствующим образом.
Код функции является составным оператором и оформляется соответствующим образом.
int myFunc()
{
static i = 0;
return i++;
}
Правила именования
При именовании переменных и функций используется т.н. camel-style, т.е. способ записи имён функций и переменных, в котором первая буква каждого слова, входящего в имя, записывается как заглавная. Исключение – для первого слова.
void myPrintSomeText();
int someVariable;
Символические константы записываются целиком в верхнем регистре.
#define MAX_INDEX 2000
Имена структурных типов данных (структур, объединений и перечислений) состоят только из строчных букв (нижний регистр). При этом для списка полей применяются те же правила форматирования, что и для объявлений переменных.
struct mystruct
{
int field1;
char *field2;
} structvar;
union pole
{
int n;
float m;
char s;
} unionvar;
enum weekday {Sun,Mon,Tue,Wed,Thu,Fri,Sat};
Массивы
Элементы массивов представляют собой индексированные переменные. Поэтому в выражения они включаются по тем же правилам, что и обычные переменные. Индекс элемента помещается в квадратные скобки без выделения пробелами, сами квадратные скобки от имени массива пробелом не отделяются.
int mas[1000];
printf(“%d\n”,2 * mas[5] + 3);
Многомерные массивы индексируются следующим образом:
a = c + mas[5][13] * 84;
Отступы
Отступ от левого края экрана для данной строки определяется степенью её вложенности в различные операторные блоки. Для каждого уровня вложенности добавляется по 2 пробела. Блоки с наименьшей степенью вложенности записываются без отступа.
Рекомендуется также разделять отдельные блоки программы между собой одной или несколькими пустыми строками. Такими блоками могут быть: блок подключения модулей, блок объявления типов, блок объявления глобальных переменных, реализации функций.
#include <stdio.h>
int n = 10;
int main()
{
printf(“%d\n”,n);
}
Приложение 2. Borland C++ 3.1
Одной из распространенных сред разработки программ на языке Си является Borland C++ 3.1. IDE (интегрированная среда разработки) представляет собой программу, совмещающую в себе специализированный редактор исходных текстов программ, компилятор Си и C++, отладчик. Эта программа разработана для операционной системы MS DOS, однако может быть запущена в Windows.
Во время установки в корневой папке IDE (в нашем примере W:\TCpp) создаются подпапки, основными из которых являются:
Bgi |
Содержит драйверы видеоадаптера и наборы шрифтов. |
Bin |
Содержит файлы программ и используемых ими библиотек |
Include |
Содержит заголовочные файлы |
Lib |
Содержит откомпилированные файлы библиотек |
В папке Bin содержатся файлы программ. Наиболее часто используемыми являются:
Tlink.exe |
Линковщик |
Сpp.exe |
Препроцессор |
Tc.exe |
IDE (интегрированная среда разработки) |
Tcc.exe |
Компилятор |
Хотя исходный текст программы можно набрать в любом редакторе, а затем, воспользовавшись препроцессором, компилятором и компоновщиком, получить исполняемый файл, намного удобнее работать с IDE. Для того, чтобы открыть ее, запустите Tc.exe.
Перед началом работы необходимо настроить некоторые параметры среды. В частности необходимо указать директории, в которых расположены заголовочные файлы и файлы библиотек. Выберите пункт меню Options -> Directories и, в появившемся окне, в полях “Include Directories” и “Library Directories” введите пути к соответствующим директориям, например, “W:\TCpp\Include” и “W:\TCpp\Lib”. Кроме того, нужно указать компилятору, какого рода исполнимый файл следует создавать, для этого выберите пункт меню Options -> Application и нажмите на кнопку, с надписью “DOS Standard”. Т.к. описываемая IDE предназначена также для создания программ на C++, необходимо позаботиться о том, чтобы создаваемые вами программы компилировались в Си. Для этого выберите пункт меню Options -> Compilers -> C++ options и установите переключатель “Use C++ Compiler” в положение “CPP extension”. Это означает, что в C++ будут компилироваться только программы, исходный текст которых находится в файлах с расширением “cpp”. Из этого следует, что создаваемые вами программы должны иметь расширение “c”.
Кроме описанных выше установок, большинство программистов предпочитают установить режим автоматического сохранения исходного текста программ и среды окружения при каждой компиляции. Это можно сделать, установив галочки напротив всех пунктов блока Auto-Save в окне Options -> Environment -> Preferences.
Теперь IDE готова к работе. Чтобы начать работу, создайте новый файл или откройте уже существующий (меню File) и, набрав исходный текст программы, нажмите ctrl+F9, для того, чтобы запустить процесс компиляции. Если исходный текст программы не содержал ошибок, программа будет запущена на выполнение.
Исходный текст вашей первой программы может иметь приблизительно следующий вид:
#include <stdio.h>
void main()
{
printf("Hello world!");
}
После того, как программа закончит свою работу, можно просмотреть ее вывод, нажав комбинацию клавиш Alt+F5.
Приложение 3. Microsoft Visual C++
Другим средством разработки программ является пакет Microsoft Visual C++. Он разработан для операционных систем семейства Windows. Несмотря на то, что эта IDE предназначена для разработки программ на C++, в ней также можно разрабатывать программы на Си. Установка пакета производится в полностью автоматическом режиме, и требует от пользователя лишь указания пути на диске и, если в этом есть необходимость, выбора компонент пакета для установки.
После того, как установка завершена, запустите программу (обычно это можно сделать, выбрав пункт Microsoft Visual C++ в меню «Пуск»), и выберите в меню пункт File -> New… В открывшемся окне выберите вкладку Projects и в поле Project Name введите название проекта. Это имя будет присвоено файлу, содержащему исходный текст программы. Далее, в списке слева выберите пункт Win32 Console Application, и нажмите кнопку “OK”. IDE Microsoft Visual C++ может создать стандартный каркас программы. Для этого, в появившемся окне установите переключатель в положение “A “Hello, world!” application”.
Теперь, когда тестовый проект создан, слева, в панели “workspace”, выберите файл с названием проекта и расширением cpp, чтобы открыть окно с исходным кодом. Будет открыт примерно такой файл:
// test.cpp : Defines the entry point for the console
// application
#include "stdafx.h"
int main(int argc, char* argv[])
{
printf("Hello World!\n");
return 0;
}
Для того чтобы откомпилировать, слинковать и запустить на выполнение программу, нажмите F5. Т.к. созданная программа запускается в отдельном окне и не ожидает никакого ввода пользователя, а лишь выводит строку “Hello, World!”, просмотреть вывод программы не удастся. Для того чтобы программа ожидала ввода, не завершаясь, дополните код программы вызовом стандартной функции:
int main(int argc, char* argv[])
{
printf("Hello World!\n");
getc(stdin); // Ждет нажатия любой клавиши
return 0;
}
Подключение заголовочных файлов можно производить в двух местах. Microsoft рекомендует подключать заголовочные файлы стандартных библиотек в StdAfx.h. Изначально, при создании проекта, именно там была подключена библиотека стандартного ввода-вывода stdio.h, которая нужна для printf. Вот как выглядит stdafx.h:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used
// frequently, but are changed infrequently
// ...
// Windows headers
#include <stdio.h>
#include <string.h>
// TODO: reference additional headers your program requires
// here Microsoft Visual C++ will insert additional
// declarations immediately before the previous line.
// ...
Если вам понадобиться подключать другие библиотеки, вы можете сделать это непосредственно возле строки, в которой подключен stdio.h, как это показано в примере.
Как видно из содержимого stdafx.h, заголовочные файлы можно подключать и непосредственно после строки «#include "stdafx.h"» в основном файле, например, так:
// test.cpp : Defines the entry point for the console
// application
#include "stdafx.h"
#include <string.h>
int main(int argc, char* argv[])
{
printf("Hello World!\n");
return 0;
}