Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ПИ_ИКТ Программирование по С++ (1 семестр) _Хотов.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
5.83 Mб
Скачать

2 Многомерные массивы (матрицы)

  1. Дан двумерный массив размерностью 46, заполненный целыми числами с клавиатуры. Сформировать одномерный массив, каждый элемент которого равен количеству элементов соответствующей строки, больших данного числа.

  2. Дан двумерный массив размерностью 65, заполненный целыми числами с клавиатуры. Сформировать одномерный массив, каждый элемент которого равен первому четному элементу соответствующего столбца, если такого нет, то равен нулю.

  3. Дана матрица размером 54. Поменять местами первую строку и строчку, в которой находится первый нулевой элемент.

  4. Найти сумму двух матриц размером nm.

  5. Дан двумерный массив размером nm, заполненный случайными числами. Определить, есть ли в данном массиве столбец, в котором равное количество положительных и отрицательных элементов.

  6. Дана матрица А размерностью nm. Сформировать одномерный массив В, элементами которого являются номера первых отрицательных элементов каждой строки массива А. (0 – отрицательный элемент отсутствует).

  7. Дан двумерный массив размерностью 56, заполненный целыми числами с клавиатуры. Сформировать одномерный массив, каждый эле­мент которого равен наибольшему по модулю элементу соответствующего столбца.

  8. Найти среднее арифметическое элементов каждой строки матрицы Q(l,m) и вычесть его из элементов этой строки.

  9. Дан двумерный массив размером nm, за­полненный случайными числами. Определить, есть ли в данном массиве строка, содержащая больше положительных элементов, чем отрицательных.

  10. Дана матрица K(n,m). Сформировать одномерный массив L(m), элементами которого являются суммы элементов j-ого столбца.

  11. Матрица K(m,m) состоит из нулей и единиц. Найти в ней номера строк и столбцов, не содержащих единицы, либо сообщить, что таких нет.

  12. Целочисленный массив K(n,n) заполнить нулями и единицами, расположив их в шахматном порядке.

  13. Дана матрица А(n,m). Сформировать одномерный массив В(n), элементами которого являются суммы элементов i-ой строки.

  14. Дан двумерный массив размерностью 56, заполненный целыми числами с клавиатуры. Сформировать одномерный массив, каждый эле­мент которого равен произведению четных поло­жительных элементов соответствующего столбца.

  15. Дан двумерный массив размером 8х7, заполненный случайным образом. Заменить все элементы первых трех столбцов на их квадраты, в остальных столбцах изменить знак каждого элемента на противоположный.

  16. Дана матрица размером 8х7, заполненная случайным образом. Поменять местами две средние строки с первой и последней.

  17. Дан двумерный массив размером 5х6, заполненный случайным образом. Заменить максимальный элемент каждой строки на противоположный по знаку.

  18. Определить, есть ли в данном массиве строка, состоящая только из отрицательных элементов.

Содержание отчета

  1. Титульный лист.

  2. Наименование и цель работы.

  3. Краткое теоретическое описание.

  4. Задание на лабораторную работу.

  5. Схема алгоритма.

  6. Листинг программы.

  7. Результаты выполнения программы.

  1. Указатели и ссылки. Имя массива как указатель. Динамические массивы

    1. Указатели и ссылки. Имя массива как указатель. Динамические массивы

Краткая теория

Указатели

Программист может определить собственные переменные для хранения адресов областей памяти. Такие переменные называются указателями.

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

Простейшее объявление указателя на объект (в дальнейшем называемого просто указателем) имеет вид:

тип *имя;

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

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

int *a, b, *c;

описываются два указателя на целое с именами а и с, а также целая переменная b.

Существует специальная операция взятия адреса, обозначаемая символом &. Ее результатом является адрес объекта.

Указатель может быть константой или переменной, а также указывать на константу или переменную. Рассмотрим примеры:

int j; // целая переменная

const int ci = 1; // целая константа

int *рi; // указатель на целую переменную

const int *pci; // указатель на целую константу

int * const ср = &i; // указатель-константа на целую переменную

const int * const срс = &ci // указатель-константа на целую константу

Указатель на константу

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

const int* p;

int i = 17;

p = &i; // Можно

*p = 29; // Нельзя

Константный указатель

С константными указателями все наоборот: адрес изменять нельзя, но зато можно изменять содержимое памяти по этому адресу.

int i = 17;

int j = 29;

int* const p; // Нельзя! Должно быть задано начальное значение

int* const p1 = &i; // Порядок

*p1 = 29; // Можно; величина, на которую ссылается указатель,

// может изменяться

p1 = &j; // Нельзя

Константный указатель на константу

Константный указатель на константу (попробуйте-ка трижды быстро произнести это вслух!) изменить вообще нельзя. Это неизменяемый адрес неизменяемой величины.

int i = 17;

int j = 29;

const int* const p; // Нельзя. Должен быть задан начальный адрес

const int* const p1 = &i; // Можно

*p1 = 29; // Нельзя

p1 = &j; // Нельзя

читаем справа налево

const char* pTr; // pTr является указателем (*) на констатный char

char* const pTr; // pTr является констатным (const) указателем (*) на char

Время жизни динамических переменных – от точки создания до конца программы или до явного освобождения памяти. В C++ используется два способа работы с динамической памятью. Первый использует семейство функций malloc и достался в наследство от языка C, второй использует операции new и delete.

Существуют следующие способы инициализации указателя:

1. Присваивание указателю адреса существующего объекта:

• с помощью операции получения адреса:

int а = 5; // целая переменная

int* p = &a; // в указатель записывается адрес а

int* р (&а); // то же самое другим способом

• с помощью значения другого инициализированного указателя:

int* r = р;

• с помощью имени массива или функции, которые трактуются как адрес:

int b[10]; // массив

int* t = b; // присваивание адреса начала массива

void f(int а){ /* ... */ } // определение функции

void (*pf) (int); // указатель на функцию

pf = f; // присваивание адреса функции

2. Присваивание указателю адреса области памяти в явном виде:

char* cp = (char *) 0хВ8000000;

Здесь 0хВ8000000 — шестнадцатеричная константа, (char *) – операция приведения типа: константа преобразуется к типу «указатель на char».

3. Присваивание пустого значения:

int* suxx = NULL;

int* rulez = 0;

В первой строке используется константа NULL, определенная в некоторых заголовочных файлах C как указатель, равный нулю. Рекомендуется использовать просто 0, так как это значение типа int будет правильно преобразовано стандартными способами в соответствии с контекстом.

4. Выделение участка динамической памяти и присваивание ее адреса указателю:

• с помощью операции new:

int* n = new int; // 1

int* m = new int (10); // 2

int* q = new int [10]; // 3

• с помощью функции mallос:

int* u = (int *)malloc(sizeof(int)); // 4

В операторе 1 операция new выполняет выделение достаточного для размещения величины типа int участка динамической памяти и записывает адрес начала этого участка в переменную n. Память под саму переменную n (размера, достаточного для размещения указателя) выделяется на этапе компиляции. В операторе 2, кроме описанных выше действий, производится инициализация выделенной динамической памяти значением 10.

В операторе 3 операция new выполняет выделение памяти под 10 величин типа int (массива из 10 элементов) и записывает адрес начала этого участка в переменную q, которая может трактоваться как имя массива. Через имя можно обращаться к любому элементу массива.

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

Операцию new использовать предпочтительнее, чем функцию malloc, особенно при работе с объектами.

Освобождение памяти, выделенной с помощью операции new, должно выполняться с помощью delete, а для выделенной с помощь malloc осовобождаться с помощью free.

Для описанных выше переменных освобождение памяти будет выглядеть так:

delete n; // 1

delete m; // 2

delete []q; // 3

free(u); // 4

При выделении памяти с помощью new[], необходимо применять delete[]. Размерность массива при этом не указывается.