Переменные, перечисленные в заголовке функции, называются формальными параметрами. Эти переменные служат для передачи значений в функцию. При вызове функции формальные параметры заменяются значениями (фактическими параметрами).
Все переменные, объявленные в функции, включая параметры функции, действуют только в пределах данной функции. Во время вызова функции компилятор выделяет память для этих переменных, а по завершению выполнения функции, эта память освобождается.
Параметры функции бывают двух видов: параметры-значения и параметры-ссылки. Параметры-значения функции могут рассматриваться как локальные переменные, для которых выделяется память в стеке при вызове функции и производится копирование значений фактических аргументов. При завершении работы функции происходит очистка стека от данных, принадлежащих этой функции, при этом значения переменных теряются. Такой способ передачи параметров в функцию не изменяет значения переменных в вызывающей функции, являющихся фактическими параметрами. Пример передачи в функцию параметров-значений b и c:
int fn1(int b, float c);
Второй способ передачи параметров представляет собой передачу в функцию адреса фактического аргумента. Обращение к фактическому аргументу по адресу позволяет вызванной функции изменить его значение в вызвавшей эту функцию подпрограмме.
В качестве такого параметра можно использовать указатель на некоторую переменную:
int fn2(int* pb);
Используя операцию косвенной адресации в теле функции, можно изменить значение этой переменной: *pb=6.
Другой способ передачи в функцию адреса переменной – передача параметра по ссылке, при этом в вызванной функции создается псевдоним исходной переменной, форма обращения к такому параметру- ссылке такая же, как и к обычной переменной, а сам параметр передается с помощью адреса, например, int fn3(int &ab); при этом обращение к переменной ab в теле функции fn3() такое же, как к обычной переменной типа int.
Пример. Передача по значению - функция обмена в синтаксисе языка C.
#include <iostream>
using namespace std;
void swapargs(int * px, int * py);
int main()
{
int i, j;
i = 10; j = 19;
cout << "i: " << i << ", ";
cout << "j: " << j << "\n";
swapargs(&i, &j);
cout << "После перестановки: ";
cout << "i: " << i << ", "; cout << "j: " << j << "\n"; return 0;
}
void swapargs(int * px, int * py)
{ int t;
t = *px; *px = *py; *py = t;
}
Ссылочные переменные
В языке C++ введён новый составной тип данных – ссылочная пере-менная. Ссылка представляет собой имя, которое является псевдонимом для ранее объявленной переменной. Для объявления ссылочной переменной используется символ &.
Пример.
#include <iostream>
using namespace std;
int main()
{
int x;
int &r = x; // создание независимой ссылки
x = 10; // эти две инструкции
r = 10; // идентичны
return 0;
}
Основное назначение ссылок – использование в качестве формальных параметров функций. Используя ссылку в качестве аргумента, функция работает с исходными данными, а не с их копиями.
Пример передачи аргументов по ссылке - функция, меняющая значения аргументов
#include <iostream>
using namespace std;
void swapargs (int &x, int &y);
int main()
{
int i, j;
i = 10;
j = 19;
cout << "i: " << i << ", "; cout << "j: " << j << "\n"; swapargs(i, j);
cout << "После перестановки: ";
cout << "i: " << i << ", "; cout << "j: " << j << "\n"; return 0;
}
void swapargs (int &x, int &y)
{ int t;
t = x; x = y; y = t;
}
Массивы как параметры
При передаче массива в качестве параметра нужно:
– в заголовке функции после имени массива указать пустые квадратные скобки, например,
int sum_arr(int arr[], int size_arr)
– а в вызове функции указать имя массива уже без квадратных скобок:
sum=sum_arr(mass,N);
Потоковый ввод/вывод
В языке С++ производится ввод-вывод потоков байтов. Поток – это просто последовательность байтов. В операциях ввода байты пересылаются от устройства (например, от клавиатуры, дисковода) в оперативную память. При выводе байты пересылаются из оперативной памяти на устройства (например, на экран дисплея ).
Заголовочный файл iostream.h объявляет объекты cin, cout, которые соответствуют стандартным потокам ввода и вывода.
<< – операция – поместить в поток;
>> – операция – взять из потока;
\n – переход на новую строку (так же можно применять манипулятор потока endl, в отличие от ‘\n’ этот манипулятор не только переводит строку, но и выгружает в поток содержимое буфера вывода);
Примеры
cout<< “Test” << endl;
cout<< “Test \n”;
1.5. Консольный ввод-вывод средствами языка С, включенными в библиотеку С++
Процесс реализованного в функциях из С-библиотеки форматирования существенно проще, чем форматирование методами ввода и вывода языка С++.
Две функции printf() и scanf() и выполняют соответственно консольный вывод и ввод. Этим функциям передается переменное число аргументов, но первым аргументом всегда является текстовая строка, называемой строкой формата.Она задает способ преобразования данных. Эти функции объявлены в файле stdio.h.
Функция printf() выдаст на экран всю форматную строку, в которой знак %ххх заменяется символами выводимой информации. Символы после % до первого разделителя рассматриваются как спецификация преобразования значения выводимой переменной. Имя переменной - это второй, третий и т.д. аргументы списка аргументов.
Функция scanf() принимает с консоли все символы до нажатия клавиши ENTER и помещает их в буфер. Затем по форматной строке определяется способ преобразования введенных символов в соответствии с заданными спецификация ми. Полученное в результате преобразования число помещается по адресу переменной, который является вторым, третьим и т.д. аргументом в списке аргументов функции. Спецификация преобразования задается в виде последовательности
% [флаги] [ширина ] [.точность ] <тип>
В таблице перечисляются некоторые из флагов, задающих спецификацию преобразования.
Флаги | Действие |
- + Пробел | Производится выравнивание влево выводимого значения а пределах выделенного поля. Правая сторона выделенного поля дополняется пробелами. По умолчанию устанавливается выравнивание вправо. Выводится знак числа символом '-' или '+' Выводится пробел перед числом, если оно положительно. Для отрицательных чисел знак '-' выводится всегда |
# | Выводится идентификатор системы счисления для целых: - 0 перед числом, выводимым в восьмеричной с/с; - 0х или 0Х для чисел, выводимых в шестнадцатиричной с/с; - ничего для чисел, выводимых в десятичной с/с Выводится десятичная точка для чисел типа float |
Поле ширина воздействует только на вывод и определяет минимальную ширину поля в n символов. Если после преобразования ширины недостаточно, выводится столько символов, сколько есть. Незаполненные позиции дополняются пробелами.
Поле тип преобразования принимает значения с, d, i, o, x, s
Тип преобра-зования | Тип перемен-ной | Действие |
c | char | При вводе - из файла читается и передается переменной один байт. При выводе - переменная преобразуется к типу char. В файл передается один байт |
d | int | Десятичное int со знаком |
i | int | Десятичное int со знаком |
o | int | Восьмеричное int unsigned |
x | int | Шестнадцатеричное int unsigned; при выводе для числа используются символы 0 - F |
s | char | При вводе принимает символы без преобразования до тех пор, пока не встретится '\n' или пока не достигнута специфицированная точность. В программу передаются символы до '\n' или пробела. При выводе выдает в поток все символы до тех пор, пока не встретится '\0' или пока не достигнута специфицированная точность |
1.5.1. Примеры ввода-вывода информации с помощью функцийprintf() и scanf()
Пример 1. Вывод значений двух переменных целого типа col, nm и одной строковой переменной name
int col=234;
int nm=77;
char name[10] = "namestr\n";
#include<stdio.h>
{
printf( "%4d %4d %25s", col,nm,name);
}
Пример 2. Вывод значений двух переменных целого типа col, nm в 16-ричной сс и одной строковой переменной name, значения переменных
printf( "%4x %4x %25s", col,nm,name);
Пример 3. Ввод значений символьной переменной и переменной целого типа
intPID;
char op;
printf( "Введите вид операции и PID процесса:" );
scanf( "%1c %4d", &op, &PID );