- •Лабораторная работа.1. Простейшие программы и базовые операции ввода вывода
- •Задание 1 Приложение «Hello World!»
- •Элементы простейшей программы
- •Функция main()
- •Переменные
- •Индивидуальное задание №1
- •Операции присваивания
- •Приведение типа
- •Смешанные выражения
- •Поразрядные операции и сдвиги
- •Инкремент и декремент
- •Условная операция
- •Функции ввода и вывода в С
- •Спецификация преобразования
- •Задание 2 Возможности функции printf( )
- •Escape-последовательности
- •Индивидуальное задание №2
- •Функции ввода строки — scanf() и gets()
- •Функции getch() и getche()
- •Задание 3 Пример функции ввода информации пользователем
- •Индивидуальное задание №3
- •Индивидуальное задание №4
- •Лабораторная работа.2. Управляющие инструкции, массивы
- •Управляющие инструкции if и switch
- •Индивидуальное задание №1
- •Индивидуальное задание №2
- •Управляющие конструкции циклов
- •Индивидуальное задание №3
- •Индивидуальное задание №4
- •Массивы
- •Индивидуальное задание №5
- •Требования к отчетам по лабораторной работе №2
- •Лабораторная работа.3. Строки, функции, файлы
- •Символы и строки
- •Задание 1.
- •Пример программы 1:
- •Пример программы 2:
- •Функции ввода-вывода
- •Функции работы со строками
- •Индивидуальное задание №1
- •Функции
- •Задание 2.
- •Индивидуальное задание №2
- •Задачи повышенной сложности
- •Файлы
- •Задание 3.
- •Функции работы с файлами
- •Индивидуальное задание №3
- •Требования к отчетам по лабораторной работе №3
Основы создания программ в Си |
Page 1 of 68 |
|
|
|
|
Часть 1. Основы создания программ в Си
Лабораторная работа.1. Простейшие программы и базовые операции ввода вывода
Задание 1 Приложение «Hello World!»
Дается представление об элементарной функции.
С этого сакраментального восклицания начинают обучение все программисты. Вот код программы, который, если не лень, вы можете набрать в любом редакторе и сохранить (желательно в отдельном пустом каталоге, например каталоге D:\Student\ — это сейчас не имеет особого значения, но хорошо выработать у себя такую привычку) под именем hello.с.
Листинг Hello.c
#include <stdio.h> #include <conio.h> /*
** Печать простого сообщения. */
#pragma argsused
int main(int argc, char* argv[])
{
printf("Hello World!\n"); printf ("Press a key...\n"); getch();
return 0;
}
Далее полученный файл с кодом необходимо скомпилировать для получения исполняемого файла
*.exe.
На первых лабораторных для компиляции будем использовать простейший компилятор DJGPP, распространяемый по открытой лицензии GNU.
Сначала следует проверить доступность вызова команд компилятора из командной строки. Введите в командную строку следующее:
>gcc –v
В окне появится, например, такая информация:
Reading specs from c:/djgpp/lib/specs
gcc version 2.95.3 20010315/djgpp (release)
Это означает, что компилятор доступен.
Основы создания программ в Си |
Page 2 of 68 |
Возвращаясь к программe файле Hello.c, скомпилируем содержимое этого файла в исполняемый файл Hello.exe. Для начала необходимо установить текущую директорию в командной строке на D:\Student, для этого воспользуемся командой смены текущего диска и его каталога “cd”:
Команда смены диска – это просто указание его имени:
>D:
Команда смены каталога на текущем диске D:
D:\>cd Student
Итак, находясь в текущем каталоге (D:\Student), можно вызывать команды компилятора для файлов Си кода из этой директории. Способ вызова команды имеет следующий обобщенный вид:
>gcc имя_файла.с –o имя_исполняемого_файла.exe
Для нашего примера получится следующая команда:
>gcc Hello.c –o HelloApp.exe
После нажатия клавиши ENTER начнется работа компилятора. Если в нашей программе нет ошибок, то в файле HelloApp.ехе будет создан исполнимый код программы. Для ее исполнения достаточно набрать в командной строке:
>HelloApp.exe
Результат будет следующий:
Hello World!
Press a key...
Если в код закралась ошибка, компилятор сообщит о ней, например:
D:\Student>gcc Hello.c -o HelloApp.exe
Hello.c: In function `main':
Hello.c:10: parse error before ‘printf'
Это говорит о том что код не может быть разобран перед вызовом функции ‘ printf ' на строчке 10. В данном случае была пропущена точка с запятой после первого вызова функции ‘ printf ':
printf("Hello World!\n")
printf ("Press a key...\n");
По правилам синтаксиса языка: Каждый оператор в теле функции оканчивается точкой с запятой
(;).
Элементы простейшей программы
Наша программа при запуске в Windows с консоли (в «окне MS-DOS») напечатала приветствие «Hello World!», на следующей строчке «Press a key...» и после нажатия произвольной клавиши возвратила управление системе. Таков алгоритм её работы. Как это происходит… Первые две строки:
#include <stdio.h>
Основы создания программ в Си |
Page 3 of 68 |
|
|
|
|
#include <conio.h>
являются директивами препроцессора. Как и любые другие строки, начинающиеся со знака "#". Препроцессор в исторические времена был отдельной программой, выполнявшей т. н. препроцессорную обработку текста программы, т.е. процессорную — значит обработку кода до того, как его начнет обрабатывать собственно компилятор, т.е. программа, транслирующая текст на языке С в машинный или объектный код. В данном случае директивы #include означают, что каждую из них следует заменить на содержимое файла, имя которого указано в угловых скобках. Это необходимо для проверки корректности вызова библиотечных процедур. Вот те строчки (первая — из stdio.h, вторая — из conio.h), которые, собственно, нам здесь требуются:
int |
_RTLENTRY |
_EXPFUNC |
printf (const char * __format, . ..); |
int |
_RTLENTRY |
_EXPFUNC |
getch ( void ); |
|
|
|
|
Это, как говорят, прототипы функций, которые позволяют компилятору проверить правильность передачи параметров (то, что в скобках) и возврат корректных типов значений (они указываются слева от имени функции; здесь обе функции, если не вдаваться в подробности, возвращают значения типа int, т.е. целые значения).
Далее идут три строки, являющиеся комментарием. В языке С комментарий — это любой фрагмент текста программы, начинающийся символами "/*" и заканчивающийся литерами "*/".
В языке С++ введен новый стиль комментариев. Комментарий начинается двумя чертами дроби и продолжается до конца строи, например:
int main (int argc, char *argv[]) //Пример комментария C++
Стоит отметить, что использование редактора Notepad++ позволяет получить подсветку ключевых слов в синтаксисе языка Си в случае если имя файла имеет соответствующее расширение (*.с, *.h, *.cpp и др.).
Далее следует строка
#pragma argsused
Эта строка программы особого смысла не имеет. Вообще директивы #ргаgma, хотя и относятся формально к директивам препроцессора, на самом деле обращены к самому компилятору и не имеют к препроцессору особого отношения. Директив #pragma очень много и у разных компиляторов они разные. Данная директива должна означать, что компилятору не нужно выдавать предупреждающих сообщений (не сообщений об ошибке) о том, что параметры функции main внутри нее никак не используются.
Можно было бы написать заголовок функции main и так:
int main()
Основы создания программ в Си |
Page 4 of 68 |
И это было бы правильно, поскольку функцию main мы можем здесь задавать как угодно. Те параметры, что указаны в первоначальном коде — это аргументы командной строки, опционально передаваемые программе или командой, или директивой операционной системы.
Несколько забегая вперед, скажем, что int argc в заголовке main — это число аргументов командной строки, а char* argv [ ] — это массив самых аргументов в символьном (char*) виде. Однако функция main () дает нам возможность поговорить о функциях вообще.
Функция main()
После всех директив в программе расположено определение функции main (). Как уже говорилось, в строгом смысле любая программа на С содержит эту функцию, которая является ее входной точкой. Однако в среде Windows вместо main () часто используется winMain ().
Функция main () — это, конечно, частный случай функции вообще. Функции являются основными «строительными блоками» программы, или подпрограммами. Они, в свою очередь, строятся из операторов, составляющих тело функции. Каждый оператор оканчивается точкой с запятой (;).
В общем виде функция определяется таким образом:
возвращаемый_тип имя_функции(список_параметров)
{
//В фигурных скобках заключено тело функции,
//составленное из отдельных операторов. тело_функции
}
В нашем случае тело функции состоит из четырех операторов, первые три из которых являются, в свою очередь, вызовами функций. Значения, возвращаемые функциями, здесь игнорируются. Применяемые здесь функции содержатся в стандартной (исполнительной) библиотеке С. Первая выводит сообщение и переводит строку на консоли, вторая — выводит подсказку (не переводя строки), а третья, getch( ), ждет, пока пользователь не нажмет какую-нибудь клавишу.
Когда это произойдет, getch( ) возвратит управление в функцию main(), а оператор return возвратить управление операционной системе:
return 0;
Переменные
Отдельная единица данных должна обязательно иметь определенный тип. Для ее хранения во время работы программы мы должны, во-первых отвести соответствующее место в памяти, а вовторых, идентифицировать ее присвоив некоторое имя. Именованная единица памяти для хранения данных называется переменной.
Каждая переменная и каждое выражение (набор операций с переменными) обязаны иметь тип. Именно тип определяет операции, которые могут выполняться над ними. Например, в описании int inch;
говорится, что переменная с именем inch имеет тип int, т.е. inch является целой переменной.
Основы создания программ в Си |
Page 5 of 68 |
Объявление переменной - это оператор, который вводит имя в программу. В объявлении указывается тип переменной и её имя. Тип, в свою очередь, определяет, как правильно использовать переменную или строить выражения с нею.
short i; |
// объявление короткой целой переменной |
|
char quit = ‘Q’; |
// инициализация символьной переменной |
|
float f1, factor = 3.0, f2; // |
Три переменных типа float, |
|
|
// |
одна из которых инициализирована |
|
|
|
Основные типы, наиболее приближенные к "аппаратной реальности" машины, таковы: char
short int long
Они представляют целые числа. Следующие типы: float
double long double
представляют числа с плавающей точкой. Переменная типа char имеет размер, нужный для хранения одного символа на данной машине (обычно это один байт или 8 бит). Переменная int имеет размер, необходимый для целой арифметики на данной машине (обычно это одно слово 2 байта или 16 бит).
Встроенные типы данных представлены в Таблице 1 ниже:
Таблица 1 Встроенные типы данных
Следующие арифметические операции можно использовать над любым сочетанием перечисленных типов:
+ (плюс, унарный и бинарный) - (минус, унарный и бинарный) * (умножение)