- •Простые типы данных и операции над данными. Приведение типов.
- •Void - пустой тип, используется для создания указателей и указания того, что функция не возвращает значений;
- •Выражения сравнения и логические операции.
- •Операторы инкремента и декремента.
- •Составные типы данных: массивы и строки.
- •Составные типы данных: структуры, указатели на структуры.
- •Указатель на тип void и методы работы с ним.
- •Составные типы данных: структуры и объединения.
- •Условные операторы.
- •If (выражение) инструкция1;
- •If (выражение)
- •If (выражение) инструкция1;
- •Циклы, виды циклов. Вложенные циклы. Алгоритмизация циклических процессов.
- •Пользовательские функции, прототипы.
- •14. Указатели и ссылки. Ссылочные переменные.
- •Перегрузка функций.
- •Передача параметров в функцию и вызов функции.
- •1. Вызов функции.
- •2. О аргументах и параметрах
- •Передача указателей и массивов в качестве аргументов функций.
- •Использование указателя для обеспечения вызова по ссылке. Ссылочные параметры.
- •Стек и динамическая память.
- •Простые типы данных и операции над данными. Приведение типов. Константы, квалификатор const.
- •Указатели и динамическое распределение памяти.
Передача указателей и массивов в качестве аргументов функций.
Стандартным способом передачи аргументов является копирование их значений, т.е. передача по значению. При этом способе функция не получает доступа к реальным объектам, являющихся ее аргументами. Вместо этого она получает в стеке локальные копии этих объектов. Изменение значений копий никак не отражается на значениях самих объектов. Локальные копии теряются при выходе из функции. Однако такой способ передачи аргументов может не устраивать нас в следующих случаях:
• передача большого объекта типа класса. Временные и пространственные расходы на размещение и копирование такого объекта могут оказаться неприемлемыми для реальной программы;
• иногда значения аргументов должны быть модифицированы внутри функции. Например, swap() должна обменять значения своих аргументов, что невозможно при передаче по значению:
void swap (int *px, int *py)
{
int *temp;
temp = px;
px = py;
py =temp;
std::cout << "swap. After swap: " << std::endl;
std::cout << "*px= " << *px << std::endl;
std::cout << "*py= " << *py << std::endl;
}
то значения x и y также не будут меняться местами. Дело в том, что в данном варианте функции swap (x,y) меняются местами не сами переменные, а указатели на них. При этом очевидно, что указатели в функцию передаются по значению, а не по ссылке, и, несмотря на то, что значения указателей будут меняться местами внутри функции swap (x,y), в функции main( ) они будут иметь те же самые адреса. Если обмениваются значения через указатели, то следует прибегать к двойному указателю (указателю на указатель), как это показано ниже:
void swap (int **px, int **py)
{
int *temp;
temp = *px;
*px = *py;
*py =temp;
std::cout << "swap. After swap: " << std::endl;
std::cout << "**px= " << **px << std::endl;
std::cout << "**py= " << **py << std::endl;
}
В главной программе вместо самих объектов будут передаваться их адреса: swap(&i, &j).
#include"firstheader.h"
int main(int argc, char* argv[])
{
int x = 3;
int y = 7;
int *px = &x;
int *py = &y;
std::cout << "Main. Before swap : " << std::endl;
std::cout << "x= " << x << std::endl;
std::cout << "y= " << y << std::endl;
std::cout << "*px= " << *px << std::endl;
std::cout << "*py= " << *py << std::endl;
swap(&px,&py);
std::cout << "Main. After swap : " << std::endl;
std::cout << "x= " << x << std::endl;
std::cout << "y= " << y << std::endl;
std::cout << "*px= " << *px << std::endl;
std::cout << "*py= " << *py << std::endl;
_getch();
return 0;
}
Важно заметить, что в C++ типы "массив" и "указатель" тесно связаны, а именно: массив практически всегда автоматически приводится к указателю на свой первый элемент. Поэтому в функцию, которая требует указатель, вполне законно передавать массив:
void MyFunc( int *arr );
MyFunc(m);
С другой стороны, среди формальных параметров функции можно объявить и обычный массив, и даже массив без указания размера. Если тип параметра — T[N] или T[], то он автоматически меняется на T*. Так что следующие три объявления функций абсолютно идентичны:
void MyFunc1( int *arr ); // компилятор посчитает
void MyFunc2( int arr[] ); // эти три объявления
void MyFunc3( int arr[15] ); // абсолютно идентичными
Однако можно передать массив по ссылке, так как для параметров-ссылок таких замен не производится:
void MyFunc4( int (&arr)[15] ); // Сюда можно передать массив из 15 элементов типа int (но ни из какого другого количества)
void MyFunc5( int (&arr)[3] ); // А сюда можно передать массив из 3 элементов типа int
//указатели сюда передавать нельзя. Менять параметры внутри функций тоже нельзя, так как они являются псевдонимами массивов, а не указателями.