- •2. Структура и основные элементы программы
- •3.Общее понятие типов данных
- •4. Переменные и константы
- •5.Основные типы данных
- •6. Спецификаторы типов данных
- •7. Определение переменных и констант в программе
- •8. Инициализация переменных различных типов
- •9.Целочисленные типы данных
- •10. Вещественные типы данных
- •11. Особенности представления вещественных типов данных
- •12.Логический тип данных
- •13. Символьный тип данных
- •14. Управляющие последовательности
- •15. Операции и выражения
- •16. Операция присваивания, составные операции присваивания
- •17. Понятие l-значения
- •18. Преобразование типов данных
- •19. Арифметические операции
- •20. Операции инкремента и декремента, их разновидности
- •21. Операции отношения
- •22. Логические операции
- •23. Побитовые операции сдвига
- •24. Побитовые логические операции
- •25. Примеры применения побитовых операций
- •26. Условная операция и ее использование
- •27. Определение объема памяти, необходимого для размещения объектов
- •28. Понятие приоритета операций и его влияние на результаты вычислений
- •31.Флаги форматирования потоков ввода-вывода
- •32. Форматирование ввода-вывода с помощью манипуляторов
- •33.Форматирование ввода-вывода с помощью функций потоков ввода-вывода
- •34. Управление шириной поля вывода и выравниванием данных при выводе
- •35. Управление форматом вывода вещественных значений
- •36. Основные понятия структурного программирования
- •37. Базовый набор управляющих структур
- •39.Условная инструкция (if)
- •40. Инструкция множественного выбора (switch)
- •42. Цикл с постусловием (do while)
- •43. Итерационный цикл (for)
- •46. Инструкция перехода goto
- •47. Понятие рекуррентных вычислений, примеры
- •48. Понятие инварианта цикла
- •49. Понятие и определение массива
- •52. Ввод элементов массивов с клавиатуры
- •53. Декларативная и программная инициализация массивов
- •54. Копирование массивов
- •55. Нахождение минимальных и максимальных значений в массивах
- •56. Сдвиг элементов массивов
- •57. Перестановка элементов в массивах
- •58. Поиск данных в массивах
- •59. Сортировка данных в массивах
- •60. Вычисление сумм и произведений элементов массивов
- •61. Представление текстовых строк в виде массива символов
- •62. Ввод-вывод символьных строк
- •63. Определение фактической длины строки
- •64. Копирование символьных строк
- •65. Основные функции обработки строк библиотеки cstring
- •66. Массивы текстовых строк (двумерные массивы символов)
- •67. Указатели Понятие указателя
- •Работа с указателями
- •68. Арифметика указателей
- •69. Индексирование указателей
- •70. Ссылки
- •71. Определение функции
- •72. Инструкция return
- •73. Завершение работы функции
- •74. Механизмы передачи данных через параметры функций
- •75. Передача данных по значению
- •76. Передача данных через указатели
- •77. Передача данных по ссылке
- •78. Параметры по умолчанию
- •79. Функции с переменным числом параметров
- •80. Inline функции
- •81. Перегрузка функций
- •82. Рекурсия
- •83. Прототипы функций
79. Функции с переменным числом параметров
Одним из представителей подобных функций является, например, функция printf (), используемая в языках C и C++ для вывода данных:
void main()
{
int a = 10, b = 20;
char *str = "Это текст";
printf("a = %d, с = %s, b = %d", a, str, b);
}
Эта функция может принимать произвольное число аргументов в зависимости от структуры первого аргумента, задающего так называемую строку формата. В строке формата каждый символ % означает подстановку соответствующего аргумента из перечисленных за строкой формата. Количество подставляемых аргументов должно соответствовать количеству символов % в стоке формата и может быть любым.
Для того чтобы написать собственную функцию с произвольным числом параметров, необходимо придерживаться определенной методики, включающей следующие пункты:
1. При разработке тела функции необходимо использовать макросы для работы со списками аргументов функций. Для их использования в программу необходимо включить заголовочный файл <stdarg.h>:
#include <stdarg.h>
2. В списке параметров заголовка функции должен присутствовать хотя бы один обязательный параметр, после которого следуют необязательные параметры, обозначенные тремя точками. Например:
double Summa (int N, …)
Здесь в списке параметров присутствует один обязательный параметр N, за которым могут следовать необязательные параметры. Необязательные параметры должны всегда находиться в конце списка параметров.
3. В теле функции необходимо определить переменную для работы со списком параметров (тип данных этой переменной va_list определен в <stdarg.h>), значение которой инициализируют с помощью макроса va_start (он также принадлежит <stdarg.h>). Перед завершением работы функции необходимо (обязательно!) с помощью макроса va_end очистить стек программы от необязательных параметров функции:
{
va_list L; // Объявляем переменную для списка параметров
va_start (L, N); // Инициализируем переменную списка параметров
……….
va_end (L); // Очищаем стек
return ………;
}
Макрос va_start имеет два параметра. Первый – это переменная списка параметров. Второй – имя последнего обязательного параметра функции (параметра, который находится в списке параметров непосредственно перед необязательными параметрами).
4. Получение очередного параметра из списка необязательных параметров осуществляется с помощью макроса va_arg (), например, так:
double R = 0;
for (int I = 0; I < N; ++ I)
R += va_arg (L, double);
Параметрами макроса va_arg являются переменная списка параметров и тип данных очередного параметра из списка.
Приведенные выше “заготовки” приводят нас к функции, выполняющей суммирование N вещественных значений:
#include <iostream>
#include <stdio.h>
#include <stdarg.h>
using namespace std;
double Summa (int N, …)
{
va_list L; // Объявляем переменную для списка параметров
va_start (L, N); // Инициализируем переменную списка параметров
double R = 0;
for (int I = 0; I < N; ++ I)
R += va_arg (L, double); // Добавляем к R очередной аргумент
va_end (L); // Очищаем стек
return R;
}
int main ()
{
cout << Summa (3, 10.0, 20.0, 30.0) << endl; // 60
cout << Summa (5, 10.0, 20.0, 30.0, 40.0, 50.0) << endl; // 150
return 0;
}