Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебно-практическое пособие ПРОГ.doc
Скачиваний:
38
Добавлен:
20.11.2019
Размер:
5.63 Mб
Скачать

3.1.6.Указатели

Указатели - это переменные, которые хранят адреса объектов. При описании указателя надо задать тип объектов, адреса которых будут содержаться в нем. Перед именем указателя при описании ставится звездочка, чтобы отличить его от обычной переменной. Примеры описаний указателей:

int *a, *b, c, d;

char *e;

В первой строке описаны указатели a и b на тип int и простые переменныe c и d типа int.

Для указателей определены две унарные операции:

  1. присвоить указателю адрес некоторой переменной. Для этого используется операция взятия адреса, которая обозначается амперсендом &. Например, строка a = &c; указателю a присваивает значение адреса переменной c;

  2. получить объект, адрес которого содержится в указателе; для этого используется операция звездочка '*', которая записывается перед указателем. (Заметим, что звездочкой обозначается также операция умножения.) Например, строка d = *a; присваивает переменной d значение целочисленной переменной, адрес которой содержится в a. Так как ранее указателю a был присвоен адрес переменной c, то в результате переменной d присваивается значение c, т.е. данная строка эквивалентна следующей: d = c;

3.1.7.Указатели и массивы

Между указателями и массивами существует тесная связь. Имя массива a является указателем на его первый элемент, т.е. выражения a и &(a[0]) эквивалентны. Подробнее связь между массивами и указателями будет рассмотрена в дальнейшем.

3.1.8.Внешние и внутренние переменные

В языке СИ все переменные должны быть объявлены до их использования.

Переменные объявленные внутри функции main являются внутренними (локальными), переменными. Поскольку они объявлены внутри функции main, никакие другие функции не могут обращаться к ним напрямую. Это утверждение верно и применительно к переменным других функций. Например, переменная i в некоторой функции F1 не имеет никакого отношения к переменной i в функции F2. Каждая локальная переменная функции создается в момент обращения к этой функции и исчезает после выхода из нее. По этой причине такие переменные еще называют автоматическими. Так как автоматические переменные создаются при входе в функцию и исчезают при выходе из нее, они не сохраняют своих значений от вызова к вызову и должны явно инициализироваться при каждом новом обращении к функции.

В качестве альтернативы внутренним (локальным) переменным можно определить переменные, которые будут внешними по отношению ко всем функциям (глобальными), и к таким переменным можно обращаться по имени из любой функции. Внешние переменные существуют постоянно, а не возникают на период исполнения функции. Внешняя переменная должна быть определена, причем только один раз, вне текста любой функции.

3.2.Стандартные функции ввода-вывода

Рассмотренные в предыдущих разделах примеры простейших программ, с помощью директивы #include <stdio.h> была подключена стандартная библиотека ввода-вывода. В самих программах для ввода использовалась стандартная функция scanf, а для вывода - printf. В языке Си существуют и другие функции, позволяющие осуществлять ввод и вывод данных. Однако на начальных этапах изучения языка достаточно знать только эти две функции. Рассмотрим их более подробно.

У обеих этих функций число аргументов переменное, первым аргументом всегда является форматная строка. В случае функции printf обычные символы форматной строки просто выводятся на экран терминала. Например, вывод текста "Hello, World!" на экран осуществляется с помощью строки прoграммы

printf("Hello, World!\n");

Здесь '\n' - символ конца строки, т.е. перевода курсора в начало следующей строки. Единственным аргументом функции printf в данном случае служит форматная строка.

Кроме обычных символов, форматная строка может включать символы формата, которые при выводе заменяются значениями остальных аргументов функции printf, начиная со второго аргумента. Для каждого типа данных Си имеются свои форматы. Формат начинается с символа процента '%'. После процента идет необязательный числовой аргумент, управляющий представлением данных. Наконец, далее идет одна или несколько букв, задающих тип выводимых на печать данных. Для вывода чисел можно использовать следующие форматы:

%d вывод целого числа типа int (d - от decimal)

%f вывод вещ. числа типа float (f - от float)

%lf вывод вещ. числа типа double (lf - от long float)

Например, для печати целого числа n можно использовать строку

printf("n = %d\n", n);

Здесь формат "%d" будет заменен на значение переменной n. Пусть, к примеру, n = 15. Тогда при выполнении функции printf будет напечатана строка

n = 15

При печати вещественного числа компьютер сам решает, сколько знаков после десятичной точки следует напечатать. Если нужно повлиять на представление числа, следует использовать необязательную часть формата. Например, формат %.3lf применяется для печати значения вещественного числа в форме с тремя цифрами после десятичной точки. Пусть значение вещественной переменной x равно единице. Тогда при выполнении функции

printf("ответ = %.3lf\n", x);

будет напечатана строка

ответ = 1.000

При вызове функции форматного ввода scanf форматная строка должна содержать только форматы. Этим функция scanf отличается от printf. Вместо значений печатаемых переменных или выражений, как в функции printf, функция scanf должна содержать указатели на вводимые переменные. Необходимо запомнить: функции scanf нужно передавать адреса переменных, в которые надо записать введенные значения. Если вместо адресов переменных передать их значения, то функция scanf все равно проинтерпретирует полученные значения как адреса, что при выполнении вызовет попытку записи по некорректным адресам памяти и, скорее всего, приведет к ошибке. Пример: пусть нужно ввести значения трех вещественных переменных a, b, c. Тогда следует использовать фрагмент

scanf("%lf%lf%lf", &a, &b, &c);

Ошибка, которую часто совершают начинающие: передача функции scanf значений переменных вместо адресов:

scanf("%lf%lf%lf", a, b, c); // Ошибка! Передаются значения вместо указателей