![]()
Главная Обратная связь Дисциплины:
Архитектура (936) ![]()
|
Способ передачи параметров в подпрограмму
Существует несколько способов передачи параметров в подпрограмму. · Передача параметров по значению. Формальному параметру присваивается значение фактического параметра. В этом случае формальный параметр будет содержать копию значения, имеющегося в фактическом, и никакое воздействие, производимое внутри подпрограммы на формальные параметры, не отражается на параметрах фактических. Так, если в качестве фактического параметра будет использована переменная, и внутри подпрограммы значение соответствующего формального параметра будет изменено, то фактический параметр останется без изменений. int func1(int x) { x=x+1; return x; } · Передача параметров по ссылке. В формальный параметр может быть помещён сам фактический параметр (обычно это реализуется путём помещения в формальный параметр ссылки на фактический). При этом любое изменение формального параметра в подпрограмме отразится на фактическом параметре — оба параметра во время вызова подпрограммы суть одно и то же. Параметры, передаваемые по ссылке, дают возможность не только передавать параметры внутрь подпрограммы, но и возвращать вычисленные значения в точку вызова. Для этого параметру внутри подпрограммы просто присваивается нужное значение, и после возврата из подпрограммы переменная, использованная в качестве фактического параметра, получает это значение. void func2(int &x) { x=x+1; } Если в качестве параметра функции указан массив, то передается указатель на его первый элемент. Например: int strlen(const char*);void f() Это означает, что фактический параметр типа 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);
![]() |