В строке форматов должно быть столько же спецификаторов полей вывода, сколько указано объектов. Спецификатор обязательно должен соответствовать типу объекта.
Пример распространенной ошибки:
int x;
float y;
. . .
printf (”Получено x = %f y = %f \n”, x , y);
Объекты int и float это объекты разных типов и должны иметь разные спецификаторы.
Пара символов \n, \r и т.п. называется управляющей последовательностью.
Назначение этих последовательностей следующее:
\n – переход на следующую строку;
\r – возврат каретки;
\t – табуляция;
\a – звонок;
\b – возврат на один шаг;
\f - перевод формата (страницы);
\ \ - вывод знака \ ;
\ ’ – вывод знака ’;
\ ’’- вывод знака ’’.
Функции вывода puts( ) и cputs()
Данные функции выводят строку символов на экран. Строка символов может быть определена в программе в виде константы путем заключения последовательности символов в двойные кавычки.
Например:
“Система Borland C”
Функция puts() выводит строку символов, а затем выполняет переход к следующей строке поля экрана.
Пример простой программы:
# include <stdio.h> / / Подключение функций ввода/вывода
# include <conio.h >
void main (void) / / Главная функция
{
printf(“Система Borland C\n”) ; / / Печать строки
puts(“Система Borland C”); / / Печать строки
cputs(“Система Borland C\n\r”); / / Печать строки
}
Задание окна вывода
Большинство программ связано с окнами (windows), а не со всем экраном. Окно – это прямоугольная область экрана, которую программа использует для выдачи сообщения.
Borland C++ позволяет устанавливать размер и местоположение окон на экране. Окном может быть весь экран или его маленькая область. По умолчанию областью вывода является весь экран. Если требуется установить окно меньшего размера нужно использовать функцию window(), а для очистки окна – функцию clrscr().
Приведем пример простой программы и рассмотрим ее более подробно:
Пример:
#include <conio.h>
int main (void)
{
clrscr( ); /* очистка текстового окна*/
window(10,10,60,20,); /* задание нового окна */
cputs (“Это текст \r\n”); /* вывод текста */
getch( ); /* ждать нажатия клавиши */
retrn 0;
}
Рассмотрим каждую строку:
1. #include <conio.h> - директива препроцессора (текстового процессора), требующая подключить файл conio.h к нашей программе. Любая директива препроцессора начинается с символа # (номер).
2. int main (void) – здесь int - тип значения, возвращаемого функцией main, т.е. целое число;
main – имя функции;
(void) – означает отсутствие параметров у функции.
3. { - открывающая скобка – означает начало описания функции.
4. /* это комментарий */ - игнорируется компилятором.
5. clrscr ( ) - функция, очищающая текущее текстовое окно. Первоначально текстовое окно занимает все поле экрана.
6. window(10,10,60,20),
window(x1,y1,x2,y2) - функция, определяющая координаты текущего текстового окна. Окно задается координатами левого верхнего угла (x1,y1) и правого нижнего угла (x2,y2). В обычном режиме (С80) эти координаты задаются пределами: 1<= x <= 80; 1<= y <= 25.
7. cputs() – выводит строку текста, заключенную в двойные кавычки. \r\n -управляющие последовательности (см. табл.1.3).
8. getch( ) – функция, ожидающая нажатия любой клавиши; используется для временной остановки программы.
9. return 0 - оператор, с помощью которого функция возвращает в точку вызова некоторое значение.
10. } - закрывающая скобка функции main ().
Число открывающих и закрывающих скобок в программе должно быть всегда одинаковым.
Операции над адресами
Любое данное размещается в памяти ЭВМ и, следовательно, имеет некоторый адрес, обращаясь по которому можно извлечь данное из памяти. В языке Си определены две основные операции над адресами:
&- определение адреса операнда;
* - обращение по адресу.
Например, если bip – переменная типа int, то &bip – адрес переменной, по которому она расположена в памяти;
Если char *prt –указатель на данное типа char, то *prt – это само данное типа char (символ).
Пример операции над адресами:
# include <conio.h>
void main (void)
{
int bip;
char *prt;
bip = 2+3;
prt = ‘’Язык Turbo C\n’’
cprintf (‘’bip = %d &bip = %p\n\r’’, bip, &bip);
cprintf (‘’*prt = %c prt = %p\n\r’’, *prt, prt);
}
В результате выполнения этой программы в первой строке будет выведено значение переменной bip, равное 5 и адрес, по которому это значение размещено в памяти. Во второй строке будет выведен символ ''Я'', т.е. первый символ и адрес, по которому этот символ расположен в памяти.
Для того, чтобы более четко уяснить механизм адресации к строке символов, рассмотрим этот вопрос более подробно.
Определение местоположения строки символов и адресация к ней осуществляется с помощью указателя.
Символьные массивы (строки). Вспомним, что в языке Си переменная типа указатель объявляется следующим образом:
int *a; char *b; и т.п.
После таких объявлений а и в трактуются как переменные - указатели на соответствующий тип, a *a и *b – как сами переменные данного типа.
Переменные типа указатель содержат адрес операнда, на который они ссылаются:
Пример:
# include <conio.h>
void main (void)
{
char *st;
st = ”Язык программирования C\n”
cputs (st);
}
В результате обработки строки программы:
st =”Язык программирования C\n”
компилятор создает в тексте объектного кода машинный эквивалент этой строки, а переменной - указателю st присвоит адрес первого символа строки, т.е. адрес символа “Я”. Машинный код строки завершается специальным символом - терминатором или нулевым символом '\О'.
Команда cputs(st) воспроизведет строку символов на экране дисплея, начиная с того, который адресуется переменной st, вплоть до символа - терминатора.
Помимо определения строки символов в форме указателей существует и другая форма задания строки: в форме массива символов.
Пример:
# include <conio.h>
# include <string.h> /* файл заголовка функций, оперирующих со строками*/
void main (void)
{
char mas [24];/* описание массива из 24 символов */
strcpy (mas,’’Язык программирования С ''); /*копирование строки в массив */
cputs (mas);
}
По команде char mas [24] компилятор зарезервирует область памяти для 23 символов строки и еще один байт для размещения символа- терминатора '\О'.
Переменная mas несет информацию об адресе первого символа (нулевого элемента массива, т.к. массивы в Си нумеруются с 0: mas [0], mas[1],.. и т.д.).
Функция cputs() выведет на экран посимвольно все элементы массива. При этом каждый раз будет осуществляться проверка: не является ли очередной символ символом-терминатором.
Вот почему при размещении строки в массиве всегда необходимо отводить как минимум на один элемент больше для '\О', или определяйте необходимый размер в памяти по умолчанию:
char mas[]=’’Строка символов''; /* Размер массива не задан */.
Отметим, что функция cputs() и strcpy() работают с формальными параметрами типа указатель. Их прототипы имеют следующий вид:
int cputs (char* string);
char strcpy (char*dest, char* sours).
Это значит, что при вызове этих функций им должны в качестве фактических параметров передаваться адреса. Но в нашей программе нигде не встречается символ &. В чем же дело?
В том, что при описании массива его имя трактуется как указатель на его первый элемент, т.е.
mas эквивалентно & mas[0] |
Ввод данных в языке СИ
Основные функции, осуществляющие ввод данных представлены в табл.2.5.
Таблица 2.5
Функции ввода
Имя Функции | Описание | Файл, содержащий прототип |
Scanf() Gets() Getchar() Cscanf() Cgets() Getch() | Выполняет форматный ввод из потока stdin Получает строку символов из потока stdin Вводит символ из потока stdin Выполняет форматный ввод с клавиатуры Считывает строку символов с клавиатуры Вводит символ с клавиатуры без эхо-печати | stdio.h stdio.h stdio.h conio.h conio.h conio.h |
Рассмотрим краткое описание этих функций.
Функции scanf() и cscanf() используются для интерактивного ввода. Обобщенная форма записи этих функций следующая:
(с)scanf (“строка форматов'', адрес, алрес,…);
В строке форматов применяются те же спецификаторы, которые были рассмотрены ранее для функции printf(): %d, %f, %c, %s (табл.2.4).
В отличие от функций printf() функция (с)scanf() требует указания в списке ввода не данных, а их адресов.
Пример:
/* ввод двух целых чисел в ячейки памяти ''а'' и ''b''*/
(с)scanf (“%d %d”, &a, &b);
где &a &b- адреса операндов ''a'' и ''b''.
Пример:
/* ввод строки символов, представленных массивом */
#include <conio.h>
void main (void)
{
clrscr ( );
char im [10];
cprintf (“Введите имя:” );
cscanf (”%s”, im) ;
cprintf (”\n\r Ваше имя : %s \n\r”, im);
}
Вспомним, что имя массива указывает на его первый элемент, поэтому перед im не ставится символ &.
Входной поток разбивается на отдельные поля с помощью специальных знаков: пробелов, символов табуляции.
Внимание: Для ввода строки, содержащей пробелы, функцию (с)scanf () не используют. Для этой цели предназначена функция (с)gets().
Функции gets() и cgets() читают строку символов, оканчивающуюся символом перевода строки. Символ перевода строки заменяется на символ -терминатор ’\0’.
Пример:
# include <stdio.h>
#include <conio.h>
void main (void)
{
clrscr ();
char string [40];
printf (”Введите строку : ”);
gets (string);
printf (”Строка = %s \n”, string);
getch ( );
}
Функции getchar() и getch(). Функция getchar() предназначена для ввода одиночного символа. Возвращает считанный символ, преобразованный в целое число. Так как буфер stdin имеет размер в одну строку, то функция ничего не возвращает, пока не нажата клавиша ”Enter”.
Пример:
# include <stdio.h>
int main (void)
{
char c;
while ((c=getchar())!=’\n’)
printf (”%c”, c);
return 0;
}