Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры программирование.doc
Скачиваний:
7
Добавлен:
17.04.2019
Размер:
257.54 Кб
Скачать
  1. Передача указателей и массивов в качестве аргументов функций.

Стандартным способом передачи аргументов является копирование их значений, т.е. передача по значению. При этом способе функция не получает доступа к реальным объектам, являющихся ее аргументами. Вместо этого она получает в стеке локальные копии этих объектов. Изменение значений копий никак не отражается на значениях самих объектов. Локальные копии теряются при выходе из функции. Однако такой способ передачи аргументов может не устраивать нас в следующих случаях:

• передача большого объекта типа класса. Временные и пространственные расходы на размещение и копирование такого объекта могут оказаться неприемлемыми для реальной программы;

• иногда значения аргументов должны быть модифицированы внутри функции. Например, 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

//указатели сюда передавать нельзя. Менять параметры внутри функций тоже нельзя, так как они являются псевдонимами массивов, а не указателями.