- •Структура программы на языке Си. Этапы выполнения программы
- •1.1. Алфавит языка Си
- •1.3. Идентификаторы и ключевые слова
- •1.4. Знаки операций
- •2. Переменные и константы. Типы данных
- •2.1. Основные типы данных
- •2.2. Декларация (объявление) объектов
- •2.4. Целочисленные константы
- •2.5. Константы вещественного типа
- •2.6. Символьные константы
- •2.7. Строковые константы
- •3. Обзор операций
- •3.2. Арифметические операции
- •3.3. Операции сравнения
- •3.4. Логические операции
- •4.1. Операция присваивания
- •Примеры недопустимых выражений:
- •4.2. Сокращенная запись операции присваивания
- •4.3. Преобразование типов операндов бинарных операций
- •4.4. Преобразование типов при присваивании.
- •4.5. Операция явного приведения типа
- •4.6. Операция «,» (запятая)
- •5.3. Консольные функции вывода данных на экран
- •5.4. Консольные функции ввода информации
- •6. Операторы языка с.
- •7.1. Условные операторы
- •If (выражение) оператор;
- •If (выражение) оператор 1 ;
- •If (выражение 1) оператор 1;
- •If (выражение 2) оператор 2;
- •If (выражение 3) оператор 3;
- •7.2. Оператор выбора альтернатив (переключатель)
- •7.3. Условная операция «? :»
- •8. Составление циклических алгоритмов
- •8.1. Оператор с предусловием while
- •8.2. Оператор цикла с постусловием do – while
- •8.3. Оператор цикла с предусловием и коррекцией for
- •9. Операторы передачи управления.
- •9.1. Оператор безусловного перехода goto
- •9.2. Операторы continue, break и return
- •10. Массивы
- •10.1. Одномерные массивы
- •10.2. Примеры алгоритмов, использующих одномерные массивы.
- •10.3. Многомерные массивы
- •11.5. Операция sizeof
- •11.6. Побитовые логические операции. Операции над битами
- •12.1. Строки как нуль-терминированные массивы char.
- •12.4. Преобразования строковых типов.
- •13. Функции пользователя и классы памяти.
- •13.1. Сущность и предназначение функций.
- •13.2. Определение и вызов функции.
- •13.3. Прототип функции.
- •13.4. Область видимости.
- •13.5. Классы памяти объектов в языке Cи.
- •13.6. Разбиение программы на модули.
- •14. Структуры и объединения
- •14.1. Понятие структуры
- •14.2. Декларация структурного типа данных
- •14.3. Объявление структурных переменных
- •14.4. Обращение к полям структуры
- •14.5. Операции со структурой как единым целым
- •14.6. Вложенные структуры
- •14.7. Массивы структур
- •14.8. Размещение структурных переменных в памяти
- •14.10. Объединения
- •16. Файлы в языке с
- •16.1. Типы файлов.
- •16.2. Открытие файла
- •16.3. Закрытие файла
- •16.4. Запись - чтение информации
- •А) Посимвольный ввод-вывод
- •Б) Построчный и форматированный ввод-вывод
- •В) Блоковый ввод-вывод
- •Int fflush(file *stream);
- •16.5. Текстовые файлы
- •16.6. Перенаправление стандартного ввода-вывода
- •16.7. Бинарные файлы
- •16.8. Дополнительные полезные функции
- •16.9. Простейший пример создания собственной базы данных
- •17. Указатели
- •17.1. Определение указателей
- •17.2. Связь указателей и массивов.
- •17.3. Операции над указателями (косвенная адресация)
- •17.4. Операции над указателями (косвенная адресация)
- •17.5. Массивы указателей.
- •17.6. Указатели на указатели.
- •17.7 . Указатели как параметры функций.
- •Void f1(int, const double *);
- •17.8 . Указатели на структуры
- •17.10. Указатели на функции
- •Id_функции(список аргументов);
- •18.1. Динамическое выделение и освобождение памяти.
13.3. Прототип функции.
Функции могут располагаться в исходном файле в любом порядке. А сама исходная программа, как отмечалось вначале, может размещаться в нескольких файлах.
При этом, однако, может возникнуть ошибка компиляции, если компилятор встретит вызов функции раньше, чем ее объявление. Для устранения этого используют описания (прототипы) функций.
Описание функции заключается в приведении в начале программного файла ее прототипа (заголовка). Прототип функции сообщает компилятору о том, что далее в тексте программы будет приведено ее полное определение: в текущем или другом файле исходного текста, либо в библиотеке, содержащей ее скомпилированный (объектный) код.
Прототип функции имеет вид:
тип_результата имя_функции (список) ;
В списке перечисляются типы параметров данной функции, причем имена этих параметров в круглых скобках прототипа указывать не обязательно. Прототип завершается точкой с запятой, в то время как в определении функции за списком параметров идет не точка с запятой, а фигурные скобки с телом функции. Это позволяет компилятору различать их. Описание дает возможность компилятору проверить соответствие типов и количества параметров при фактическом вызове этой функции. В определении и в описании одной и той же функции типы и порядок следования параметров должны совпадать. Тип возвращаемого значения и типы параметров совместно определяют тип функции.
Пример описания функции fun, которая имеет три параметра типа int, один параметр типа double и возвращает результат типа double:
double fun(int, int, int, double);
Пример описания для вышеприведенной функции Min:
int Min (int x, int y);
либо
int Min (int, int);
13.4. Область видимости.
Область видимости (действия) объекта (переменной и др.) – это та часть кода (текста) программы, в которой его можно использовать.
В сложных программах ограничение этой области помогает избежать путаницы, вызванной использованием одинаковых имен в разных местах для разных целей. Например, количество чего-либо удобно обозначать буквой n. При этом в одной функции n может означать количество символов, а в другой - количество штук товара на складе. Присвоение n значения в одной функции тогда может испортить работу второй функции; но если в каждой функции своя, независимая переменная с именем n, такой проблемы не возникнет.
Основное правило видимости в языке Си: объект, объявленный внутри блока (участка программы, заключенного в фигурные скобки), как правило, виден, начиная с места его объявления и заканчивая концом этого блока ( } ). Если объявление данных лежит внутри нескольких входящих друг в друга блоков, оно считается расположенным в самом внутреннем из них. Если же нужно сделать объект видимым за пределами блока, нужно объявить его вне блока. Можно, например, объявить переменные вне всех функций; такие переменные называются глобальными, в отличие от переменных, объявленных внутри функции, называемых локальными и видимых только в пределах своей функции.
Область действия локальных данных – от точки декларации (объявления) до конца функции (блока), в которой произведено их объявление, включая все вложенные в него блоки.
Областью действия глобальных данных считается файл, в котором они определены, от точки описания до его окончания.
Если некоторое место программы входит в область видимости двух и более переменных с одинаковыми именами, объявленных на разном уровне вложенности блоков, действует та из них, которая объявлена на самом глубоком уровне. Объявление в одном и том же блоке на одном и том же уровне (или глобально - в одном и том же файле) переменных с одинаковыми именами вызывает ошибку компиляции.
Сказанное иллюстрирует пример:
void fun(void);
void fun2(int a);
int a=10;
void main(){
cout<<a<<endl; // a=10
int a=20;
cout<<a<<endl; // a=20
do{
int a=30;
cout<<a<<endl; // a=30
} while(0);
cout<<a<<endl; // a=20
for (int i=0; i<1; i++) {
int a=40;
cout<<i<<endl; // i=0
cout<<a<<endl; // a=40
}
cout<<a<<endl; // a=20
fun();
fun2(a);
}
void fun(void){
cout<<a<<endl; // a=10
}
void fun2(int a){
cout<<a<<endl; // a=20
}
Некоторые уточнения:
Параметры функции являются локальными переменными, их область действия - вся функция;
Если переменная объявлена внутри круглых скобок какого-либо оператора (например, for (int i=0; i<n: i++) { … } ), то областью ее действия одни компиляторы считают этот оператор (вместе с его телом), а другие - весь блок, в котором он находится. Рекомендуется поэтому использовать подобное место объявления, только если это не может привести к двусмысленности.
Область действия метки - вся функция (даже если метка лежит во вложенном блоке).
Функции не могут быть объявлены внутри других функций; поэтому они, как правило, являются глобальными. (При необходимости их область видимости можно ограничить с помощью не рассматриваемого здесь оператора namespace).
Замечание. Некоторые компиляторы не допускают переход с помощью goto внутрь области видимости переменной извне ("перескакивая" ее объявление), даже если сама эта переменная при этом не используется, т.к. это мешает им распределять память:
goto M;
int i;
M: // Может вызвать ошибку компиляции
Связь между функциями осуществляется через аргументы и возвращаемые функциями значения. Ее можно осуществить также через внешние, глобальные переменные.
Глобальные переменные доступны всем функциям, где они не описаны как локальные переменные. Использовать их для передачи данных между функциями довольно просто: значение, присвоенное глобальной переменной в одной функции, доступно в другой функции. Тем не менее, без нужды этого делать не рекомендуется. Необходимо стремиться к тому, чтобы функции в программе были максимально независимыми, и чтобы их интерфейс полностью определялся прототипами этих функции.