- •Министерство образования и науки Российской Федерации
- •1. Модель рабочего стола
- •2. Интерфейс командной строки
- •3. Компиляция, компоновка и выполнение программы
- •4. Командные файлы
- •5. Вывод символьной информации
- •6. Операции с целыми числами
- •7. Операции с вещественными числами
- •8. Операторы
- •9. Символы и строки
- •10 Передача параметров в командной строке
- •Министерство образования и науки Российской Федерации
- •Министерство образования и науки Российской Федерации
5. Вывод символьной информации
В языке С для организации вывода используются стандартные функции. Тело стандартной функции написано на языке машинных кодов и входит в состав библиотеки – одного из файлов в директории Lib. Для того, чтобы компилятор мог её использовать, он должен знать её заголовок – имя функции, возвращаемое значение, количество и тип аргументов. Эта информация содержится в стандартных заголовочных файлах, которые находятся в директории Include. Скопируем в неё следующие файлы из директории Include пакета CBuilder:
C:\Test\Include
_defs.h
_nfile.h
_null.h
_stddef.h
stdio.h
Расширение h представляет собой сокращение слова header – заголовок. В тексте программы следует указать только один из файлов – stdio.h (standard input/output – стандартный ввод/вывод).
Создадим с помощью редактора notepad.exe в директории C:\Test\Apps файл с исходным текстом программы prog3.c:
/*prog3.c*/
#include <stdio.h>
main()
{
printf (“I am a student”);
return 0;
}
На первом этапе компиляции исходный текст программы обрабатывает специальный компонент компилятора, который называется препроцессором. Препроцессор изменяет программу так, чтобы её смог прочитать компилятор. В частности, он выполняет директивы, содержащиеся в исходном тексте. Каждая директива начинается с символа # - знака номера, или, как говорят программисты, «решётки». В отличие от команд, в конце директивы точка с запятой не ставится. Директива include имеет вид
#include <имя_файла>
Выполняя директиву include, препроцессор вставляет на её место содержимое указанного файла.
Стандартная функция printf (print – печатать, format – формат, способ представления данных) осуществляет вывод на экран содержимого строки – аргумента. Строка в языке С заключается в двойные кавычки.
Откомпилируем программу командой
bcc32.exe –I“C:\Test\Include” -L“C:\Test\Lib” prog3.c
Если программа составлена правильно, в директории Apps должен появиться файл prog2.exe. Запустив его, мы увидим на экране надпись “I am a student”.
Для того, чтобы функция printf не только выводила сообщения, но и осуществляла переход на новую строку, надо включить в строку управляющий символ \n:
printf (“I am a student\n”);
Если мы хотим отделить сообщение от последующих команд пустой строкой, то надо поставить два символа перевода строки:
printf (“I am a student\n\n”);
Вопросы для повторения:
Объясните, для чего нужна директива #include <stdio.h> в исходном тексте программы;
Что такое комментарии в исходном тексте программы? Объясните их назначение.
6. Операции с целыми числами
Базовыми понятиями любого языка программирования служат константы, переменные и выражения. Переменные – это имена запоминающих устройств, чаще всего – областей памяти, а выражения строятся из констант и знаков операций. Переменная, входящая в выражение, интерпретируется как синоним константы, которая хранится в соответствующей области памяти. Каждая константа и переменная относится к тому или иному типу, тип константы определяет ее представление в памяти и те операции, в которых она может участвовать. Связь между переменными и областями памяти устанавливают специальные команды - объявления переменных. Объявление состоит из имени типа, за которым следует список переменных. Рассмотрим простой пример:
/*prog4.c*/
#include <stdio.h>
main()
{
int x = 17, y = 18, z;
z = x * y;
printf(“17 * 18 = %d\n”, z);
return 0;
}
Первой командой тела функции main является объявление переменных целого типа x, y и z. Слово int (integer-целых) – это имя типа; объявление выделяет в памяти две ячейки для хранения целых чисел. При объявлении переменных x и y выполняется их инициализация – в ячейку х помещается значение 17, а в ячейку y – 18. В следующей строке – операция присваивания, значения переменных x и y перемножаются и результат помещается в ячейку z. Произведение x * y представляет собой выражение, перемножаются те значения, которые были присвоены переменным в ходе инициализации.
Результат работы программы – в нашем случае произведение чисел 17 и 18 – надо каким-то образом сообщить пользователю. Для этого используется функция printf. Теперь у нее два аргумента. Первый аргумент, как и прежде, строка, функция выводит ее на экран один ее символ за другим, пока не дойдет до знака %, он отмечает начало спецификации формата. Следующий за ним символ определяет представление второго аргумента функции - константы, переменной или выражения, d означает, что значение должно быть выведено в виде десятичного числа. Закончив вывод значения аргумента, функция printf продолжает выводить символы строки, пока не пройдет ее всю. Если в строке встретится новая спецификация формата, то она определит представление на экране следующего аргумента функции printf. После выполнения программы на экране должно появиться сообщение: 17 * 18 = 306.
Надо различать инициализацию переменной и присваивание значения. Инициализировать переменную можно лишь константным выражением, которое способен выполнить компилятор. Объявление
int x=17, y=17*18;
будет корректным, а выражение х * 18 можно использовать лишь в правой части команды присваивания, оно не является константным, так как требует обращения к содержимому переменной х:
int x = 17, y;
y = x * 18;
Для ввода данных с клавиатуры в программах, написанных на языке С, используют функцию scanf:
/*prog5.c*/
#include <stdio.h>
main()
{
int x, y, z;
scanf ( “%d %d”, &x, &y);
z = x * y;
printf ( “%d * %d = %d\n”, x, y, z );
return 0;
}
когда мы запустим исполняемый файл, полученный при компиляции этой программы, компьютер перейдет в состояние ожидания ввода данных. Наберем значения 17 18 и нажмем Enter (ввод). На экране снова появится сообщение 17 * 18 = 306. Но теперь мы можем перемножать и другие пары чисел, например, если мы введем 44 55, то получим 44 * 55 = 2420. Объявляя переменные x и y, мы их не инициализируем. Функция scanf должна содержать не менее двух аргументов – строку со спецификациями формата и ссылки на переменные. Спецификации формата у функций printf и scanf совпадают. Знак & (амперсанд) перед переменной означает операцию ссылки, т.е. определение адреса переменной. Когда переменная встречается в составе выражения (в частности, когда она служит аргументом функции), компилятор интерпретирует её как синоним значения, присвоенного ранее этой переменной. Рассмотрим снова фрагмент программы:
int x = 17, y = 18, z;
z = x * y;
printf ( “%d\n”, x );
После инициализации переменная х получила значение 17, а y – 18. при вычислении выражения х * у перемножаются именно эти значения. Новое присваивание помещает в ячейку z значение 306, его и выводит функция printf. Функция scanf помещает значение, которое ввел пользователь, в ячейку, именем которой служит х, выражение &х передает функции scanf адрес этой ячейки.
Первый аргумент функции scanf может содержать не только спецификации формата и пробелы, но и другие символы, которые функция scanf читает, но не сохраняет.
/*prog6.c*/
#include <stdio.h>
main()
{
int x, y;
scanf ( “х = %d у = %d”, &x, &y );
printf ( “%d * %d = %d\n”, x, y, x * y );
return 0;
}
Теперь пользователь должен ввести данные в таком виде:
х=17 у=18
Символы х, =, у, = функция прочитает, но сохранит лишь значения 17 и 18. Если пользователь вместо х, у, = наберёт другие символы, выполнение программы прекращается и на экране появляется сообщение об ошибке.
Значения типа int могут быть как положительными, так и отрицательными. Мы будем в основном работать с целыми неотрицательными числами. Они относятся к типу unsigned int – целых без знака. Каждый раз набирать в объявлении переменных оба слова неудобно, поэтому мы воспользуемся директивой препроцессора #define:
#define UINT unsigned int
Она заставляет препроцессор заменять в исходном тексте программы все вхождения параметра UINT директивы define словами unsigned int. Параметры директивы define всегда следует писать заглавными буквами.
Перечислим знаки основных арифметических операций над целыми числами:
+ сложить,
- вычесть,
* умножить,
/ выполнить целочисленное деление (деление с остатком)
% вычислить остаток от деления.
Как мы видим, символ % внутри первого аргумента функций printf, scanf интерпретируется как часть спецификации формата, а в арифметическом выражении – как знак операции вычисления остатка от деления одного числа на другое. Такие символы называются перегруженными. Значение перегруженного символа определяется его контекстом - той конструкцией, в состав которой он входит. Наличие перегруженных символов в языке программирования напоминает явление полисемии (многозначности) в естественном языке. Большая часть слов имеет не одно, а много значений: нос, коса, лист и т.п. Полисемия позволяет выражать самые разные мысли при помощи сравнительно небольшого запаса слов.
Спецификация формата %u, означает, что следует вводить и выводить целые числа без знака. Разность чисел х и у может быть как положительной, так и отрицательной, поэтому при её выводе следует сохранить спецификацию формата %d.
Напомним, что синтаксисом конструкции называется правило, в соответствии с которым её следует строить, семантикой – тот набор действий, который совершает компьютер, получив её перевод на язык машинных кодов, а функциональным назначением – её роль в программе: зачем она здесь нужна, для чего используется.
Вопросы для повторения:
приведите примеры констант, переменных, выражений, объясните их синтаксис и семантику;
объясните синтаксис и семантику объявления переменных и инициализации;
что такое спецификация формата? какие спецификации формата Вы знаете?
приведите примеры константных выражений и выражений, которые, по Вашему мнению, не являются константными. В чем разница между ними? Где используются константные выражения?
что такое операция ссылки на переменную? Объясните ее синтаксис и семантику. Где она применяется?
для чего применяется директива препроцессора #define?
Задание
Составьте программу, которая вычисляет квадрат целого числа, поступающего на её вход.