- •Введення
- •1. Структура та обсяг дисципліни
- •2. Основи програмування на мові с
- •2.1 Найпростіші конструкції мови
- •2.2 Типи даних
- •2.4 Операції мови с
- •2.5 Структура простої с програми
- •2.6 Організація введення-виведення
- •2.7 Компіляція в системі Linux
- •2.8 Організація розгалужень в програмі
- •2.9 Організація циклів
- •2.10 Оператор break
- •2.11 Оператор continue
- •2.11 Масиви
- •2.12 Функції
- •2.13 Вызов функции с переменным числом параметров
- •2.14 Рекурсивні функції
- •2.15 Читання і запис текстових файлів
- •2.16 Структури даних
- •2.17 Перелік|перерахування| (enumeration)
- •2.18 Об'єднання (union)
- •3. Операційні системи і системне програмування
- •3.1. Поняття операційної системи
- •4. Корисні команди Linux
- •4.1. Загальні|спільні| команди
- •4.1.1. Команда arch – виведення архітектури комп'ютера
- •4.1.2. Команда clear – очищення екрану
- •4.1.3. Команда date
- •4.1.9. Команда uptime – інформація про роботу системи
- •4.1.10. Команда users – інформація про користувачів
- •4.1.11. Команди w, who і whoami інформація про користувачів
- •4.1.12. Команда xf8config – настройка графічної підсистеми
- •4.2. Команди для роботи з текстом
- •4.2.1. Команди diff і cmp
- •4.2.2. Команди grep і egrep – текстовий фільтр
- •4.2.3. Команди more и less – посторінкове виведення
- •4.2.4. Команди head і tail – виведення начала і хвоста файлу
- •4.2.5. Команда wc – підрахунок слів у файлі
- •5. Захист інформації в інформаційних системах
- •5.1 Основні завдання забезпечення безпеки
- •5.2 Базові поняття криптографії
- •5.2.1 Поняття криптографічного алгоритму і протоколу
- •5.2.2 Криптосистеми з секретним ключем
- •5.2.3 Криптосистеми із відкритим ключем
- •5.2.4. Гибридні криптосистеми
- •5.2.5. Цифрові підписи
- •5.2.6. Сертифікати
- •5.3. Принципи аутентифіекації і керування доступом
- •5.3.1. Основи аутентифікації
- •5.3.2. Основи керування доступом
- •5.4. Аутентифікація та керування доступом в unix
- •5.4.1. Облікові записи користувачів
- •5.4.2. Аутентифікація
- •5.4.3. Керування доступом
- •6. Програмний інтерфейс unix. Системні виклики і функції стандартних бібліотек
- •6.1. Підтримка програмування в oc unix. Вивчення передачі інформації
- •6.2. Змінні оточення
- •6.3. Обробка помилок
- •6.4. Правила формування і засоби розбору командних рядків
- •7. Операції над файлами
- •7.1 Файлові операції posix
- •7.2. Збирання інформації про атрибути файла
- •7.3. Операції над каталогами
- •Література
2.13 Вызов функции с переменным числом параметров
При вызове функции с переменным числом параметров в вызове этой функции задается любое требуемое число аргументов. В объявлении и определении такой функции переменное число аргументов задается многоточием в конце списка формальных параметров или списка типа аргументов.
Примером функций с переменным числом параметров являются функции из библиотеки языка Си, осуществляющие операции ввода/выода информации (printf(), scanf() и т.д.).
Программист может сам разрабатывать функции с переменным числом параметров. Для обеспечения удобного способа доступа к аргументам функции с переменным числом параметров имеются три макроса: va_start, va_arg, va_end, находящиеся в заголовочном файле stdarg.h. Эти макросы указывают на то, что функция, разработанная пользователем, имеет некоторое число обязательных аогументов, за которыми следует переменное число необязательных аргументов. Обязательные аргументы доступны через свои имена как при вызове обычной функции. Для извлечения необязательных аргументов используются макросы va_start, va_arg, va_end в следующем порядке.
Макрос va_start предназначен для установки аргумента arg_ptr на начало списка необязательных параметров и имеет вид функции с двумя параметрами:
void va_start(arg_ptr, prav_param);
Параметр prav_param должен быть последним обязательным параметром вызываемой функции, а указатель arg_ptr должен быть объявлен с предопределением в списке переменных типа va_list в виде:
va_list arg_ptr;
Макрос va_start должен быть использован до первого использования макросв va_arg.
Макрос va_arg обеспечивает доступ к текущему параметру вызываемой функции и тоже имеет вид функции с двумя параметрами:
type_arg va_arg(arg_ptr, type);
Эта макрокоманда извлекает значение типа type по адресу, заданному указателем arg_ptr, увеличивает значение указателя arg_ptr на длину использованного параметра (длина type) и таким образом параметр arg_ptr будет указывать на следующий параметр вызываемой1 функции. Макрокоманда va_arg используется столько раз, сколько необходимо для извлечения всех параметров вызываемой функции.
Макрос va_end используется по окончании обработки всех параметров функции и устанавливает указатель списка необязательных параметров на ноль.
Рассмотрим применение этих макросов для обработки параметров функции, вычисляющей среднее значение произвольной последовательности целых чисел. Поскольку функция имеет переменное число параметров, будем считать концом списка значение, равное -1. Поскольку в списке должен быть хотя бы один элемент, у функции будет хотя бы один обязательный параметр.
#include<stdarg.h>
#include<stdio.h>
double read_znach(int x, …)
{
int i=0, j=0;
double sum=0;
va_list uk_arg;
va_start(uk_arg,x);
if(x!=-1)
sum=x;
else
return 0;
j++;
while(i=va_arg(uk_arg,int)!=-1)
{
sum+=i;
j++;
}
va_end(uk_arg);
return (double)sum/j;
}
int main()
{
double n;
n=sred_znach(2,3,4,-1);
printf(“n=%.2lf”,n);
n=sre_znach(5,6,7,8,9,-1);
printf(“%.2lf”,n);
return 0;
}
2.14 Рекурсивні функції
Рекурсія - це такий спосіб організації обчислювального процесу, при якому підпрограма в ході виконання складових її операторів звертається сама до себе.
Розглянемо класичний приклад - обчислення факторіалу: програма запрошує з клавіатури ціле число n і обчислює його факторіал.
При виконанні правильно організованої рекурсивної функції здійснюється багатократний перехід від деякого поточного рівня організації алгоритму до нижнього рівня послідовно до тих пір, поки, нарешті, не буде одержане тривіальне рішення поставленої задачі.
int factr(int n)
{
int answer;
if(n==1)
return (1);
answer=factr(n-1)*n;
return (answer);
}
Основною перевагою рекурсивних функцій є використання їх для простішого створення версії деяких алгоритмів в порівнянні з ітеративними еквівалентами. Наприклад, сортуючий алгоритм Quick sort достатньо важко реалізувати ітеративним способом. Деякі проблеми, особливо пов'язані з штучним інтелектом, також використовують рекурсивні алгоритми. Нарешті, деяким людям здається, що думати рекурсивно набагато легше, ніж ітеративно.
При написанні рекурсивних функцій слід мати оператора if, щоб примусити функцію повернутися без рекурсивного виклику. Якщо цього не зробити, то, одного разу викликавши функцію, вийти з неї буде неможливо. Це найбільш типова помилка, пов'язана з написанням рекурсивних функцій.
