Главная Обратная связь

Дисциплины:

Архитектура (936)
Биология (6393)
География (744)
История (25)
Компьютеры (1497)
Кулинария (2184)
Культура (3938)
Литература (5778)
Математика (5918)
Медицина (9278)
Механика (2776)
Образование (13883)
Политика (26404)
Правоведение (321)
Психология (56518)
Религия (1833)
Социология (23400)
Спорт (2350)
Строительство (17942)
Технология (5741)
Транспорт (14634)
Физика (1043)
Философия (440)
Финансы (17336)
Химия (4931)
Экология (6055)
Экономика (9200)
Электроника (7621)






Способ передачи параметров в подпрограмму



Существует несколько способов передачи параметров в подпрограмму.

· Передача параметров по значению. Формальному параметру присваивается значение фактического параметра. В этом случае формальный параметр будет содержать копию значения, имеющегося в фактическом, и никакое воздействие, производимое внутри подпрограммы на формальные параметры, не отражается на параметрах фактических. Так, если в качестве фактического параметра будет использована переменная, и внутри подпрограммы значение соответствующего формального параметра будет изменено, то фактический параметр останется без изменений.

int func1(int x) { x=x+1; return x; }

· Передача параметров по ссылке. В формальный параметр может быть помещён сам фактический параметр (обычно это реализуется путём помещения в формальный параметр ссылки на фактический). При этом любое изменение формального параметра в подпрограмме отразится на фактическом параметре — оба параметра во время вызова подпрограммы суть одно и то же. Параметры, передаваемые по ссылке, дают возможность не только передавать параметры внутрь подпрограммы, но и возвращать вычисленные значения в точку вызова. Для этого параметру внутри подпрограммы просто присваивается нужное значение, и после возврата из подпрограммы переменная, использованная в качестве фактического параметра, получает это значение.

void func2(int &x) { x=x+1; }

Если в качестве параметра функции указан массив, то передается указатель на его первый элемент. Например:

int strlen(const char*);

void f()
{
char v[] = "массив";
strlen(v);
strlen("Николай");
}

Это означает, что фактический параметр типа v[] преобразуется к типу v*, и затем передается. Поэтому присваивание элементу формального параметра-массива изменяет этот элемент. Иными словами, массивы отличаются от других типов тем, что они не передаются и не могут передаваться по значению.

 

 

109. Оператор static_cast - это оператор приведения типов между родственными объектами или типами указателей. Участвующие в этой операции классы должны быть связаны через наследственность, конструктор или функцию преобразования. Оператор static_cast также работает с простейшими числовыми типами данных. Следующее выражение имеет то же значение, что и выражение expr, но позволяет переводить его в тип type:

static_cast<type>(expr)

Хотя численное значение результата не изменяется, при выполнении этого оператора может быть изменено внутреннее представление данных. Оператор static_cast используется в следующих случаях: для приведения типов между родственными типами указателей, если они указывают на классы, которые связаны через наследственность. В отличие от dynamic_cast можно выполнять приведение к типу указателя на производный класс даже при отсутствии виртуальных функций, проверка во время выполнения программы также выполняется; приведение к простейшим типам данных; приведение выражения типа A к типу B, когда B имеет соответствующий конструктор из типа A или A имеет функцию преобразования в B. В принципе, можно использовать оператор static_cast всегда, когда допускается автоматическое преобразование в обратном направлении. Например, целые числа автоматически переводятся в действительные. Чтобы выполнить обратное преобразование, требуется оператор static_cast .



В основном оператор static_cast используется для приведения сложных типов к простым: при работе с простыми типами он подавляет предупреждение компилятора:

long j = 17;

short i = static_cast<short>(j);

Этим как бы говорится: "Да, я на самом деле хочу это сделать". При этом компилятор не выдает предупреждения о возможной потере данных. При этом необходимо быть уверенным в том, что данные не будут слишком велики для приведения в другой тип. Таким же образом возможно преобразование типов из указателя базового класса в производный без каких-либо ограничений. Но так как никакой проверки во время выполнения программы не делается, то забота о поддержке данных в должном виде возлагается на программиста (производный класс содержит все члены базового плюс члены производного класса). Например, в следующем примере B является базовым классом класса D:

B *pb;

// ...

D *pd = static_cast<D *>(pb);



В данном случае объект, на который указывает pb, фактически имеет тип D или производный от него. Однако при этом значения всех членов класса D, не входящих в класс B, не определены, и обращение к ним приведет к возникновению ошибок. В такой ситуации программист сам должен определить все недостающие члены с помощью присваивания. Можно пойти и в обратном направлении - выполнить присваивание указателю на базовый класс. В этом случае два следующих оператора эквивалентны.

pb = static_cast<D *>(pd);

pb = pd;

Другие случаи, в которых оператор static_cast может быть полезен, редко встречаются в программах. Например, с его помощью можно последовательно выполнить несколько преобразований типов данных. В следующем примере A и B - такие классы, в которых A имеет функцию преобразования в B, а B - функцию преобразования к типу int. Тогда объект типа A может быть преобразован в тип int следующим образом:

A oa;

int i = static_cast<int>(static_cast<B>(oa));

Без использования этой цепочки преобразований (и при отсутствии функции преобразования A в тип int) преобразование oa в целое было бы невозможным. На первый взгляд кажется, что при использовании оператора static_cast программисту придется выполнять больше работы, чем при программировании старыми методами. Однако при этом становятся доступными возможности ANSI C++ по разделению операторов приведения типа, что значительно облегчает просмотр больших программ. Оператор static_cast также полезен при применении различных форматов данных или при необходимости вывода данных в формате, отличном от того, который определен для данного типа по умолчанию. Например, нужно вывести целое число i в формате с плавающей точкой:

int i = 25;

cout << static_cast<double>(i);

Заметим, что для вывода на экран адреса строки надо использовать оператор reinterpret_cast, так как имя строки имеет тип указателя, а не простейший тип:

char str[] = "Hello";

cout << hex << reinterpret_cast<int>(str);

 

 


Эта страница нарушает авторские права

allrefrs.ru - 2019 год. Все права принадлежат их авторам!