Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГОС_ответы.doc
Скачиваний:
41
Добавлен:
27.10.2018
Размер:
21.59 Mб
Скачать

Int n,m; scanf("%d%d",&n,&m); //число элементов строк и элементов в строке

тип **имя; // определение указателя на указатель

имя=new тип*[n];//запрос памяти для указателей на строки

for(int i=0;i<m;i++)

имя[i]=new тип[n];//запрос памяти для элементов в строке

...

for(i=0;i<m;i++) delete имя[i]; //освобождение памяти для элементов в строке

delete[]имя;); //освобождение памяти для указателей на строки

В следующем примере при создании двумерного массива вначале создается массив из m указателей типа double*, а затем для каждого из них в цикле запрашивается память, равная длине строки n.

Пример

#include <stdio.h>

#include <stdlib.h>

Int main()

{ double **dm;

int m,n,i,j;

puts("Введите размеры матрицы");

scanf("%d%d",&m,&n);

dm=new double* [m];

if(dm==NULL)

{ printf("Ошибка выделения памяти!\n");

return -1; }

for(i=0;i<m;i++)

{dm[i]=new double[n];

if(dm[i]==NULL)

{ printf("Ошибка выделения памяти!\n");

delete [] dm; return -1; }

}

for(i=0;i<m;i++)

for(j=0;j<n;j++)

{ dm[i][j]=double(i+j);

printf("dm[%d][%d]=%lf\n",i,j,*(dm[i]+j));

}

for(i=0;i<m;i++)

delete[]dm[i];

delete []dm;

return 0;

}

8 С++. Структури даних: опис, визначення, ініціалізация, доступ до елементів структури, розташування елементів структури у пам’яті. Вкладені структури.

Структуры ‑ это совокупность поименованных объектов в общем случае разных типов. Каждая структура включает в себя один или несколько объектов (переменных, массивов, указателей, структур), называемых элементами структуры..

Структурный тип определяет, сколько элементов и какого типа, входят в структуру. Объявление структуры начинается со служебного слова struct, за которым помещаются описания входящих в структуру элементов, заключенные в фигурные скобки. Элементы структуры могут быть базового и производного типа, в том числе структурами и массивами. Объявление структуры иногда называют созданием структурного типа или шаблона структуры. Шаблон структуры имеет права типа.

Синтаксис объявления шаблона структуры следующий:

struct имя_структурного_типа{type_1 элемент_1;

type_2 элемент_2;

. . . . . . ;

type_n элемент_n;

};

После объявления структурного типа с его помощью можно определить конкретные структуры следующим образом: имя_структурного_типа имя_структуры; Например:

struct STR {char ch;

float f;

int a[3];};

STR rec1, rec2, rec3[2];

Здесь объявлен структурный тип STR с элементами char ch, float f,int a[3] и определены две структуры: rec1 и rec2, а также массив из 2-х структур rec3.

Каждая из определенных структур rec1, rec2, rec3[2] содержит в качестве элементов свои собственные данные, состав которых определяется структурным типом с именем STR, то есть все структуры имеют в данном случае одинаковое внутреннее строение и у каждой их них имеются поля char ch, float f,int a[3].

Для обращения (доступа) к элементам структуры используются уточненные имена. Используется следующая конструкция языка: имя_структуры.имя_элемента_структуры. Например:

rec1.ch=’z’; rec1.f=3.2;

rec1.a[0]=1; rec2.ch=’w’;

rec2.f=4.5; rec2.a[1]=10;

rec3[0].ch=’d’; rec3[1].a[2]=100;

Выделение памяти под структурную переменную осуществляется по шаблону. Например, для структур rec1, rec2 распределение памяти следующее:

1 б.

2 б.

3 б.

4 б.

5 б.

6 б.

7 б.

8 б.

9 б.

10 б.

11 б.

ch

f

a[0]

a[1]

a[2]

Например, для структур rec3 распределение памяти следующее:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

ch

f

a[0]

a[1]

a[2]

ch

f

a[0]

a[1]

a[2]

rec3[0]

rec3[1]

Размер структуры можно определить с помощью оператора sizeof().

int n1= sizeof(rec1); // 11 байт

int n2= sizeof(STR); // 11 байт

При определении структуры возможна её инициализация, она по синтаксису аналогична инициализации массивов:

struct STR{ char ch;

float f;

int a[3];};

STR r1={‘a’,1.1,1,2,3};

Если определен массив структур, то инициализация осуществляется следующим образом:

STR r3[2]={{‘w’,6.6,10,20,30},{‘v’,7.7,40,50,60}};

Можно создавать указатели структурного типа. Если создан указатель структурного типа, то память выделяется только под указатель (4 байта). Поэтому необходимо указатель на структуру проинициализировать адресом (или присвоить адрес) уже объявленной структуры этого же типа.

STR *pst1=&rec2,*pst2;

pst2=&rec2;

После такого определения доступ к элементам структуры выполняется через разыменование указателя:

(*pts1).f=8.8; (*pts2).a[0]=100;

Еще одна возможность доступа к элементам структуры с помощью операции ’->’.

pts2->f=9.9; pts1->a[0]=1000;

В языке С (С++) определена операция по созданию и уничтожению объектов с динамической продолжительностью существования. Для этого используются соответственно либо функции malloc() и free(), либо операции new и delete.

#include <alloc.h>

struct STD{char name[20];float rating;};

STD *st;

st=(STD*)malloc(sizeof(STD));//Запрос памяти

gets(st->name);

st->rating=4.5;

free(st);//освобождение памяти

Аналогично можно воспользоваться операциями new и delete:

Можно создать массив структур с динамической продолжительностью существования:

MYSTR *b; int N;

puts(“Ведите размер массива”);

scanf(“%d”,&N);

b=new MYSTR[N];//Запрос памяти

for (int i=0; i<N; i++)

scanf("%s%d",b[i].name, &b[i].age);

for (int i=0; i<N; i++)

printf("%s\n%d\n",b[i].name,b[i].age);

delete [] b;//освобождение памяти

9 С++. Об'єднання даних: визначення, ініціалізация, доступ до елементів об'єднання, відображення елементів об'єднання у пам’яті

Объединение – это совокупность объектов различных типов, все члены которой начинаются с одного адреса. Этот тип объектов вводится с помощью служебного слова union.

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

Синтаксис определения объединения подобен синтаксису определения структуры. Сначала определяем тип объединения, а затем – объединение:

union имя_типа_объединения {type_1 поле_1;

type_2 поле_2;

. . . . . . ;

type_n поле_n;};

имя_типа_объединения имя_объединения;

Рассмотрим этот тип на примерах:

union UN1{int a;char ch;long b;};

UN1 un1;

union UN2{double d;float f[3];};

UN2 un2;

Компилятор выделит под объединение un1 память, равную длине элемента типа long.

1 байт

1 байт

1 байт

1 байт

ch

a

b

Компилятор выделит под объединение un2 память, равную длине массива f типа float.

4 байта

4 байта

4 байта

f[0]

f[1]

f[2]

d

Для обращения к элементам объединения используются уточненные имена. Например:

un1.a=10; un1.ch=’k’; un1.b=100L;

un2.f[0]=1.2; un2.f[1]=3.2; un2.f[2]=4.5; un2.d=7.4;

Необходимо помнить, что в каждый момент памяти в объединении храниться только одно значение. Поэтому после таких присвоений для объединения un1 в памяти будет находиться только un1.b=100, а переменные un1.a, un1.ch будут равняться. Для объединения un2 в памяти будут находиться un2.d=7.4 и un2.f[2]=4.5, а переменные un2.f[0], un2.f[1] свои значения изменят.

При определении объединений их можно инициализировать, но в отличие от структур инициализируется только первый элемент. Например:

union{int i;char ch;} un7={200};

union UN3{char c[4];int a[2];long g;};

union UN4{ int a[2];long g; char c[4];};

UN3 un8 ={“abc”}; UN4 un9={8,9};

Так как элементы объединения охватывают один и тот же участок памяти, то они могут использоваться для различных трактовок одного и того же кода:

union COM{int a;char c[2];};

COM common={24930}; //инициализация объединения common 24930=0х6162

printf("%c %c\n",common.c[0],common.c[1]);

На печать выведутся символы b и а, так как их коды в согласно ASCII–таблице соответственно 62 и 61. В дампе памяти числа 61 и 62 будут записаны в обратном порядке. Таким образом, переменная а будет выведена на экран в виде двух символов. Схема размещения элементов объединения в двух соседних ячейках памяти приведена ниже:

a

c[0]

Aдрес

0x62

c[1]

Aдрес+1

0x61

Заносить значения в участок памяти, выделенный для объединения, можно с помощью любого из его элементов. И доступ возможен так же с помощью любого из его элементов:

union{float pi; long l;}upi;

union{float exp;long l;}uex;

upi.pi=3.141593;

printf("l=%ld\n",upi.l); //l=1078530012

uex.l=1076754517L;

printf("e=%f\n",uex.exp); //e=2.718282

10 С++. Призначення функції. Опис, визначення, виклик функції. Передача даних за значенням та за покажчиком.

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

Всем именам функций по умолчанию присваивается класс памяти extern, т.е. они имеют внешний вид компоновки и статическую продолжительность существования. Kаждая функция глобальна, и поэтому доступна во всех модулях программы.

Любая функция, кроме главной функции main(), должна быть определена или, по крайней мере, описана до её использования (вызова) в конкретном модуле.

Определение функции имеет следующий синтаксис

тип_функции имя_функции(спецификация_формальных параметров)

{ тело функции}

Тип функции – это тип возвращаемого функцией значения, т.е. базовый (например, int, float, т.д.) или производный тип вычисленного в функции значения (например, тип структуры или объединения). Если функция ничего не возвращает, например, обеспечивает вывод на экран или изменяет значения массива и т.п., то тип функции обозначается void.

Имя функции – это любой уникальный допустимый идентификатор, например, myfunc.

Спецификация формальных параметров (или сигнатура функции) – это пусто или void, если в функцию не передаются никакие параметры, либо список спецификаций отдельных параметров с указанием типов и имен. В конце списка может быть поставлено многоточие (). Спецификация формальных параметров имеет вид:

тип имя_параметра или тип имя_параметра=умалчиваемое_значение

Первая строка функции называется заголовком функции.

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

В теле функции может быть несколько операторов return. Это означает, что в зависимости от операторов тела функции выход из функции может быть осуществлен в нескольких точках.

Если функция не возвращает никакого значения, т.е. имеет тип void, то выражение в операторе return может отсутствовать, а сам оператор return может отсутствовать.

Пример. Функция вычисляет сумма трех переменных типа int. Функция имеет три формальных параметра и один оператор return.

int sum(int a,int b,int c)

{int S=a+b+c;

return S;}

Обращение к функции

Обращение к функции (вызов функции) – это выражение с операцией круглые скобки(). Для вызова функции указывается имя функции и список фактических параметров:

Имя_функции (список фактических параметров);

Результатом выражения является возвращаемое значение, тип которого соответствует типу функции.

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

Понятие прототипа функции

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

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

Примеры прототипов:

int sum(int a,int b,int c);

int max(int, int y);

float mult(double *, char);

Передача параметров в функции по значению

В языке С(C++) передача параметров (кроме указателей и массивов) в функции при их вызове осуществляется по значению. Это означает, что для передаваемых (фактических) параметров в функции создаются копии этих параметров. Действия, производимые с этими параметрами (копиями) в функции не влияют на переменные вне функции, т.е. на фактические переменные.. Для формальных параметров выделяется своя область памяти, в которую заносятся значения фактических параметров. При выходе из функции выделенная память высвобождается.

Передача параметров в функции по указателю

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

11 С++. Функції з параметрами, що замовчуються, зі зміними параметрами

Спецификация формальных параметров может содержать так называемое умалчиваемое значение. При этом спецификация формальных параметров имеет вид:

тип имя_параметра=умалчиваемое_значение

При вызове такой функции умалчиваемый параметр может быть опущен.

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

Пример 3.1

#include <stdio.h>

int def(int a, int b=3, int c=4)

{return a*b+c;}