Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3_Функции.doc
Скачиваний:
4
Добавлен:
10.02.2015
Размер:
235.52 Кб
Скачать

Int scanf(char*, … );

из файла stdio.h. Обязательным параметром является адрес строковой константы, называемой строкой форматирования. Многоточие означает, что у функции кроме обязательного параметра типа char* могут быть и другие параметры. Клавиатура обеспечивает представление информации в виде групп символов. Строка форматирования содержит указания о типах объектов, в которые следует преобразовать эти группы. Группы называются полями ввода. При вводе нескольких полей они отделяются друг от друга разделительными символами (или кратко разделителями). В качестве разделителей служат пробелы, символы горизонтального табулирования ‘\t’ и символы новой строки ‘\n’. Для каждого поля в строке форматирования должно присутствовать отдельное указание, которое называется командой или спецификацией форматирования. Спецификация форматирования начинается с символа % (процент) и содержит кроме него один обязательный символ, называемый символом форматирования. Именно символ форматирования указывает тип объекта, в который требуется преобразовать соответствующее поле. Объекты сохраняются в переменных, адреса которых перечисляются после запятой, следующей за строкой форматирования. Переменные должны быть определены до вызова функции scanf(). Каждое поле требует собственный адрес. Соответствие между символами форматирования и типами вводимых объектов приведено в нижеследующей таблице 3.2.

Завершение функции fscanf() наступает после выполнения последней команды форматирования или обнаружения противоречия (несоответствия) между командой форматирования и вводимым полем. Ее возвращаемым значением является количество введенных объектов.

Таблица 3.2 - Примеры символов форматирования функции scanf()

Представление вводимых полей

Символ форматирования

Тип

объекта

Целое в десятичной системе

d

int

Целое (десятичное, восьмеричное с префиксом 0 или шестнадцатеричное с префиксом 0x)

i

Целое в восьмеричной системе с префиксом 0 или без

o

целое в шестнадцатеричной системе с префиксом 0x или без

x

Число с плавающей точкой (присутствие десятичной точки или экспоненциальной части обязательно)

e, f или g

float

Число с плавающей точкой (присутствие десятичной точки или экспоненциальной части обязательно)

lf

double

Символ в объект типа char

c

char

Последовательность символов

s

char*

(строковая константа)

3.6 Область видимости идентификаторов и время жизни объектов

Использование идентификатора начинается с его определения. Оно содержит сведения, которые необходимы компилятору для контроля за правильностью его (идентификатора) использования в программе. В соответствии с правилами языка, определение действительно только в некоторой части программы, называемой областью видимости идентификатора. Для идентификатора, определенного в некотором блоке (фигурных скобках), область видимости начинается от места его определения и простирается до конца этого блока (правой фигурной скобки). Если идентификатор является формальным параметром функции или определяется в заголовке оператора for, то областью его видимости тело функции или тело цикла. Идентификатор, определенный указанными выше способами, называется локальным. Из сказанного следует, что один и тот же идентификатор может определяться в нескольких блоках совершенно по-разному. Рассмотрим пример на эту тему.

Пример 3.6 - Локальные идентификаторы

#include <stdio.h>

void main(void){

// Первый блок

{

// Определение переменной i

int i=0;

}

// Второй блок

{

// Еще одно определение i

int i=2;

int ii=i+3; // ii=5

// Вложенный блок

{

ii++;

printf("ii=%i\n", ii);

}

}

}

После выполнения этой программы на экране дисплея появится сообщение

ii=6

Если определение идентификатора не входит ни в один из блоков, образующих программу, и если он не является формальным параметром функции, то областью его видимости является вся программа, начиная от места определения. Такие идентификаторы называются глобальными.

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

Пример 3.7 - Сокрытие глобальных идентификаторов

// Глобальная переменная

float x=2.0f;

void main(void){

// Увеличение глобальной переменной

x+=1.1f; // x=3.1

// Определение локальной переменной

int x=2;

// Умножение локальной переменной на десять

x*=10; // x=20

}

В языке Си есть операция с названием “разрешение области видимости”. Она имеет наивысший (первый) приоритет и обозначается знаком “::”. Эта операция позволяет использовать глобальные идентификаторы в области видимости локальных. Пример по этому поводу.

Пример 3.8 - Разрешение области видимости

// Глобальная переменная

int x=0;

void main(void){

// Локальная переменная

int x=1;

// Увеличение глобальной переменной

::x+=2;

// Увеличение локальной переменной

x+=3;

// ...

}

Данные должны находиться в памяти до тех пор, пока в них имеется необходимость. Язык Си предоставляет программисту несколько способов для определения продолжительности хранения данных, которая называется временем жизни.

Для данных с локальными именами память выделяется при их создании. Такие данные хранятся только в течение времени необходимого для выполнения блока, в котором они определены, и называются автоматическими.

Данные, которые хранятся в памяти в течение всего времени выполнения программы, называются статическими. По определению, все данные с глобальными именами являются таковыми. Если данные с локальными именами нужно хранить до конца выполнения программы, то их определение должно начинаться со служебного слова static.

Все статические переменные должны при их определении ини­ци­а­лизироваться. Если программист не указывает начальные значения таких переменных, то за него это делает компилятор, присваивая статическим переменным нулевые значения. Такая инициализация называется неявной. Рассмотрим пример.

Пример 3.9 - Время жизни объектов

#include <stdio.h>

int a; // a=0

void f(void){

int b=0;

static int c=1;

a++;

b++;

c++;

printf(“a=%d b=%d c=%d\n”,a,b,c);

}

void main(void){

f(); // a=1, b=1, c=2

f(); // a=2, b=1, c=3

f(); // a=3, b=1, c=4

}

3.6 Проекты

Исходный текст большой программы удобно хранить в нескольких файлах. Совокупность таких файлов называется проектом. Если содержание файлов проекта удовлетворяет определенным требованиям, то их можно компилировать отдельно друг от друга. Это означает, что в случае изменения исходного текста повторно компилировать нужно только измененные файлы.

Каждый глобальный идентификатор должен определяться в программе только один раз. Поэтому его определение может находиться только в одном файле. Во все остальные файлы, в которых он используется, нужно поместить соответствующие предупреждения, называемые объявлениями глобальных идентификаторов. Объявление глобального идентификатора начинается со служебного слова extern. За ним следует тип идентификатора и он сам. Объявление не приводит к повторному выделению памяти для хранения значения глобального идентификатора.

Пример 3.10 - Глобальные идентификаторы и проекты

// Файл №1/2

#include <stdio.h>

// Определение глобальной переменной

int j=1;

// Прототип

int f(int);

void main(){

int r=f(3);

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

}

// Файл №2/2

// Глобальная переменная, определенная в другом файле

extern int j;

// Определение функции

int f(int i){

return j+i;

}

16