Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Согласно принципам фон Неймана компьютер должен....docx
Скачиваний:
4
Добавлен:
01.08.2019
Размер:
131.24 Кб
Скачать

20. В отличие от оператора цикла с постусловием оператор цикла с предусловием вычисляет и проверяет условие до выполнения операторов, составляющих тело цикла. Синтаксис этого оператора следующий:

while (<условие>) <оператор>;

Здесь while – ключевое слово (перев. с англ.: пока); <оператор> – любой оператор языка C++, в том числе и составной (этот оператор называют телом цикла); <условие> – условное выражение типа сравнения, используемое для выхода и з цикла.

Оператор работает следующим образом: сначала вычисляется условное выражение и, если получается истинное значение, выполняется оператор, являющийся телом цикла, а затем снова проверяется условие. Если значение условного выражения ложно, то осуществляется выход из цикла. Таким образом, если условие было ложно при первом входе в цикл, то операторы тела цикла не выполнятся ни разу. Очевидно, один из операторов тела цикла должен влиять на значение условного выражения, поскольку иначе цикл будет повторяться бесконечно. 

21. Обработка одномерных массивов

Одномерные массивы имеют аналогию с таким понятием в математике, как вектор. Описание переменной типа массив задается следующим образом:

<тип> <идентификатор массива>[<t>];

Здесь <тип> – тип элементов массива (любой тип языка С++); <имя массива> – правильный идентификатор;  <t> – количество элементов массива.

Ниже приведены примеры описания одномерных массивов:

int f[10] ; char mas[100] ; float b[5]

22.  Выделение памяти производится оператором new, а освобождение памяти - оператором delete. Оператор new используется следующим образом: new туре;

Операторы управления динамической памятью. Операторы new и delete используются для создания и уничтожения динамических переменных. При создании динамической переменной в операторе new указывается тип создаваемой переменной, оператор имеет тип результата – указатель на создаваемый тип, и значение – адрес (указатель) созданной переменной.Оператор delete получает указатель на уничтожаемую переменную.

 

double   *pd;                                         

pd = new double;           // Обычная динамическая переменная           

if (pd !=NULL){                                                  

            *pd = 5;                                                                                    

            delete pd;}         

23. Эта операция позволяет выделить и сделать доступным свободный участок в основной памяти, размеры которого соответствуют типу данных, определяемому именем типа. В выделенный участок памяти заносится значение, определяемое инициализатором, который не является обязательным элементом. В случае успешного выполнения операция new возвращает адрес начала выделенного участка памяти. Если участок нужных размеров не может быть выделен (нет памяти), то операция new возвращает нулевое значение указателя (NULL). Необязательный параметр инициализатор – это выражение в круглых скобках. Указатель должен ссылаться на тот же тип, что имя_типа в операции new. Можно написать такой фpагмент пpогpаммы:

int *ptr; float *ptr1; ptr = new int; *ptr = 10; ptr1 = new float(13.15);

В первом случае опеpация new позволяет выделить 2 байта памяти и адрес начала выделенного участка присваивается указателю ptr. Следующий оператор присваивания инициализирует этот участок памяти числом 10. Во втором случае операция new позволяет выделить 4 байта памяти, адрес начала выделенного участка присваивается указателю ptr1 и этот участок памяти инициализируется числом 13.15. В дальнейшем доступ к выделенному участку памяти осуществляется с помощью операции косвенной адресации (или разыменовывание). Продолжительность существования выделенного участка – от точки создания до конца программы или до явного освобождения. С помощью операции

delete указатель

осуществляется явное освобождение памяти. Например:

delete ptr;

delete ptr1;

Если указатель, на который действует операция delete, не содержит адрес блока, зарезервированного ранее операцией new, то последствия будут не предсказуемыми.

Для выделения динамической памяти под массив операция new используется следующим образом:

int *mas1; // одномерный массив mas1=new int[n]; float *mas2; // двумерный массив mas2 = new float [n*n];

При этом к элементам одномерного массива можно обращаться по индексам и по указателю с помощью косвенной адресации, а к элементам двумерного массива - только по указателю. Чтобы работать с индексами, необходимо вспомнить, что двумерный массив это массив одномерных массивов. Имя одномерного массива является указателем на первый элемент массива. Таким образом, двумерный массив можно рассматривать как одномерный массив указателей на первые элементы строк матрицы. При этом усложняется выделение и освобождение динамической памяти. В следующей программе двумерный массив и его размерность читаются из файла и размещаются в динамической области памяти. Программа формирует одномерный массив из сумм элементов строк и записывает этот массив в выходной файл. Главным достоинством этой программы является возможность вводить размерность массивов. В файле in.txt (рис. 32) в первой строке два числа n и m размерность массива a, в следующих n строках по m чисел, разделенных пробелами – элементы двумерного массива a. В выходном файле out.txt (рис. 33) одна строка, содержащая n чисел, разделенных пробелами, - элементы сформированного массива b.

24. -------

25. Общая форма записи заголовка функции: <тип> <имя> ([<список формальных параметров>])

Здесь <имя> - правильный идентификатор, который используется для обращения к функции;  <тип> - тип возвращаемого функцией результата;  <список формальных параметров> - включает в себя параметры, необходимые для нормального интерфейса, т. е. позволяет передавать данные в подпрограмму и из подпрограммы. Список формальных параметров необязателен и может отсутствовать (круглые скобки опускать нельзя). Если он есть, то может включать в себя параметры, передаваемые по значению, указателю и ссылке. Например :

void sum(float a, float b, float *s)  void sk (int *a, int c , float d)  float f (float x, float &y)  int ab (int a)  void par (void)

Таким образом, в списке формальных параметров перечисляются имена формальных параметров и их тип. Список формальных параметров расширяет раздел описаний функции, и формальные параметры наряду с локальными переменными используются в выражениях. Тело функции, в том числе и функции main, заключается в фигурные скобки и содержит описания и операторы.

Вызов функции производится при помощи оператора вызова функции: <имя >(<список фактических параметров>);

26. Передача параметра по значению

Передача параметра по значению означает что вызывающая функция копирует в память, доступную вызываемой, (обычно стекнепосредственное значение. Изменение копии переменной, соответственно, оригинал не затрагивает.

[править]Передача параметра по адресу

Если необходимо именно изменить переменную из внешней, по отношению к вызываемой функции, области видимости, можно копировать адрес переменной, подлежащей изменению. Соответственно при вызове функции g(&x) приходится использовать операцию взятия адреса. Эта техническая деталь отвлекает внимание программиста от логики прикладной программы, однако в случаях невозможности передачи по ссылке может оказаться единственным решением.

Можно заметить, что передача параметра по адресу является частным случаем передачи по значению: передаваемым значением является адрес, по которому можно найти другое значение — значение переменной x.

[править]Передача параметра по ссылке

Передача параметра по ссылке означает что копируется не само значение, а адрес исходной переменной (как в случае передачи параметра по адресу), однако синтаксис используется такой, чтобы программисту не приходилось использовать операцию разыменования и он мог иметь дело непосредственно со значением, хранящимся по этому адресу (как в случае передачи параметра по значению).

Передача по ссылке позволяет избежать копирования всей информации, описывающей состояние объекта (а это может быть существенно больше чем sizeof(int)) и является необходимой для конструктора копирования.

Если функция возвращает значение по ссылке (например в виде "return *this;"), то её вызов можно использовать слева от оператора присваивания (смотри также L-выражение).

В случае если передача по ссылке используется именно как средство увеличения быстродействия, но изменение параметра нежелательно, можно использовать передачу по ссылке константного объекта.

Таким образом можно ожидать, что примерная программа напечатает (если закоментировать ошибочную строку) "0010 022 233 333".

Некоторые языки (или их диалекты) не поддерживают передачу по ссылке, некоторые наоборот - передают параметры исключительно по ссылке, что порождает риск непреднамеренного изменения контекста вызывающей функции.

Передача параметров по значению и по ссылке

Переменные, в которых сохраняются параметры, передаваемые функции, также являются локальными для этой функции. Эти переменные создаются при вызове функции и в них копируются значения, передаваемые функции в качестве параметров. Эти переменные можно изменять, но все изменения этих переменных будут "забыты" после выхода из функции. Рассмотрим это на примере следующей функции, "меняющей" значения двух переданных ей переменных:

     #include<iostream>      using namespace std;      void swap(int a, int b)      {          int t;          t=b;          b=a;          a=t;      }      int main()      {          int p=3,q=5;          swap(p,q);          cout<<p<<" "<<q<<endl;          return 0;      }

При вызове функции swap создаются новые переменные a и b, им присваиваются значения 3 и 5. Эти переменные никак не связаны с переменными p и q и их изменение не изменяет значения p и q. Такой способ передачи параметров называется передачей параметров по значению.

Чтобы функция могла изменять значения переменных, объявленных в других функциях, необходимо указать, что передаваемый параметр является не просто константной величиной, а переменной, необходимо передавать значения по ссылке. Для этого функцию swap следовало бы объявить следующим образом: