Теперь вам придется много практиковаться, чтобы закрепить знания и до конца разобраться. Решим несколько задач для начала.
1. завдання елементарна, але вимагає хорошого розуміння що таке покажчики. Дан покажчик: double**p=0; Виконайте наступні завдання (рішення можна оформляти всередині функції main): * створіть конструкцію, зображену на малюнку; * виведіть число, вказане в квадратику, на екран; * після цього видаліть всі динамічні об'єкти.
Знову ж – шукаємо найкоротший рішення. Автор: Olej
Посмотреть код
Задача 1: Указатели в С++
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
usingnamespacestd;
intmain(void){
double**p=0;
*(*(p=newdouble*)=newdouble)=2;
cout<<**p<<endl;
delete*p;
deletep;
}
2. Объявите указатель на массив типа double и предложите пользователю выбрать его размер. Далее напишите четыре функции: первая должна выделить память для массива, друга– заполнить ячейки данными, третья – показать данные на экран, четвертая – освободить занимаемую память. Програма повинна пропонувати користувачеві продовжувати роботу (создавать новые динамические массивы ) або вийти з програми.
Остановимся на функции, которая выделяет память под массив, размер которого задает пользователь. це функціяgiveMemoryToArr(). Определение находится в строках 34 – 38. Как видно – в результаті вона повертає покажчик типу double. Дивіться – якби функція мала типvoid, как бы она работала? В нее передался бы указатель и заданный размер. Далее для этого указателя выделяется участок памяти – рядок 36. І все– при выходе их функции копия указателя уничтожается и адрес этого участка памяти нигде не сохранен. Поэтому функция должна вернуть адрес (указатель) в результаті роботи. Тобто адреса виділеної ділянки пам'яті нам треба буде записати в покажчик, который объявлен в main() в строке 13.
Результат:
3. Объявите указатель на массив типа int и выделите память память для 12-ти элементов. Необходимо написать функцию, которая поменяет значения четных и нечетных ячеек массива. Например есть массив из 4-х элементов:
Определение функции, которая меняет данные местами, находится в строках 40 – 52. У ній оголошується тимчасова зміннаbufferVar. Она будет выполнять роль буфера для значений, которые необходимо будет записать в другую ячейку. Цикл for буде перебирати всі осередки масиву. якщо індекс– парне число(если остаток от деления на 2 равен 0), то записуємо значення цього осередку в зміннуbufferVar. В саму четную ячейку записывается значение следующей (нечетной): ptrArr[i]=ptrArr[i+1]; І далі вже в непарну копіюємо значення зbufferVar: ptrArr[i+1]=bufferVar; Потім цикл і блок if перейдут к проверке следующей ячейки.
Результат работы:
4. Оголосити і заповнити двовимірний динамічний масив випадковими числами від 10 до 50. Показать его на экран. Для заполнения и показа на экран написать отдельные функции. (подсказка: функции должны принимать три параметра – указатель на динамический массив, количество строк, количество столбцов). Кількість рядків і стовпців вибирає користувач.
Посмотреть код
Задача 4: Указатели в С++, Двумерный динамический массив
Первое на что надо обратить внимание – это объявление динамического двумерного массива, виділення пам'яті для нього і її звільнення. Коли ми розглядали тему Двумерные массивы в С мы затрагивали тот вопрос, что двумерный массив – це масив масивів. Например если объявлен двумерный массив ІНТ ArrForChange[3][3], то значить він містить в собі три масиву по три елементи кожен. Объявляется двумерный динамический массив с применением операции ** (двойная звездочка). Это указатель на указатель. Он содержит в себе адрес массива указателей, каждый элемент которого хранит адрес какой-то строки двумерного массива. Визуально это можно показать так:
Сначала надо выделить память под массив, который будет содержать адреса строк двумерного массива:
выделение памяти для двумерного динамического массива
C++
22
int**ArrayForChange=newint*[stringAmount];
Вы видите, что память выделяется не для данных типа int, а именно для указателей на данные типа int.
Далее выделяется память для каждого указателя. В этой памяти уже будут находиться данные типа int:
выделение памяти для двумерного динамического массива
C++
23
24
25
26
for(inti=0;i<stringAmount;i++)
{
ArrayForChange[i]=newint[columnAmount];
}
звільняючи пам'ять, занимаемую двумерным массивом, надо быть внимательным. Освободить её надо обратным способом: сначала память в которой содержатся данные:
освобождение памяти двумерного динамического массива
C++
32
33
34
35
for(inti=0;i<stringAmount;i++)
{
delete[]ArrayForChange[i];
}
Потом память массива указателей:
освобождение памяти двумерного динамического массива
C++
36
delete[]ArrayForChange;
Если пропустить первый шаг – произойдет утечка памяти. Так как ячейки занимаемые данными, будут отмечены как зарезервированная память и не смогут использоваться в программе повторно.
Передавая двумерный массив в функцию, нам необходимо передать указатель на указатель.
Когда функция получает этот указатель на указатель, она далее может с ним работать, как с обычным двумерным массивом. Например используя вложенные циклы, отображать данные на экран, как показано в строках 44 – 52. Або внести дані в осередку масиву– строки 58 – 64.
Розбиратися з чужим кодом набагато складніше і противнее, ніж написати свій (тим більше, якщо редактор цього сайту спотворює ваш код). Відповідь на запитання “а так зійде?” шукайте завжди компіляцією і виконанням вашого коду, краще на різних наборах вхідних даних.
Може бути в третій завданню замість додавання змінної міняти місцями без додавання змінної? прибуття[i] += Arr[i + 1]; прибуття[i + 1] = Arr[i] – молодий лосось[i + 1]; прибуття[i] -= Arr[i + 1]; Що краще: створення змінної або ось такі операції?
Функция “void swapDataInCells(int* ptrArr, int sizeOfArr)” по заміні елементів у третій завданню. В цикле “for (int i = 0; i < sizeOfArr; i )" потрібно відняти від sizeOfArr одиницю: for (int i = 0; i < sizeOfArr – 1; i ).
дурниця… в циклі for (), вираз i < sizeOfArr показує до якого значення змінюється i (індекс елемента). Отняв единицу вы "уменьшаете" кількість які перебираються індексів елементів масиву, але не сам масив
Вітаю! написав елементарну прогу для зсуву елементів в масиві вліво, кількість е-ів – n задається, крок зміщення d теж задається, але така проблема, що останні d елементів незрозуміло що виходить, підкажіть у чому проблема?! #include #include #include
using namespace std;
недійсні Зази(INT s, INT * повинен); int main(){ Int N,d; srand(time(0)); cout <> n; INT * р = новий INT[n]; INT * г = новий INT[n];
for (int i = 0; i < n; i ){ p[i] = rand() %100 ; cout << p[i] << " "; } г = р;
cout <> d; for (int i = 0; i < n; i ){ p[i] = p[i + d]; if (я == п – d) for (int k = 0; i < d; i ){ p[до + п-д] = г[k]; } } cout << p[10]; //ZAZ(n, p); cout << endl; system("pause"); return 0; }
недійсні Зази(INT s, INT * повинен) { for (int i = 0; i < s; i ){ cout << з[i] << " "; }
3. Оголосіть покажчик на масив типу int і виділіть ПАМ'ЯТЬ ПАМ'ЯТЬ для 12-ти елементів. Необходимо написать функцию, которая поменяет значения четных и нечетных ячеек массива. Например есть массив из 4-х элементов:
а так зійде?
Розбиратися з чужим кодом набагато складніше і противнее, ніж написати свій (тим більше, якщо редактор цього сайту спотворює ваш код).
Відповідь на запитання “а так зійде?” шукайте завжди компіляцією і виконанням вашого коду, краще на різних наборах вхідних даних.
Може бути в третій завданню замість додавання змінної міняти місцями без додавання змінної?
прибуття[i] += Arr[i + 1];
прибуття[i + 1] = Arr[i] – молодий лосось[i + 1];
прибуття[i] -= Arr[i + 1];
Що краще: створення змінної або ось такі операції?
краще завжди використання додаткової проміжної змінної.
Функция “void swapDataInCells(int* ptrArr, int sizeOfArr)” по заміні елементів у третій завданню.
В цикле “for (int i = 0; i < sizeOfArr; i )" потрібно відняти від sizeOfArr одиницю:
for (int i = 0; i < sizeOfArr – 1; i ).
*Щоб для непарного числа елементів масиву теж працювало
дурниця… в циклі for (), вираз i < sizeOfArr показує до якого значення змінюється i (індекс елемента). Отняв единицу вы "уменьшаете" кількість які перебираються індексів елементів масиву, але не сам масив
3.
4.
Вітаю! написав елементарну прогу для зсуву елементів в масиві вліво, кількість е-ів – n задається, крок зміщення d теж задається, але така проблема, що останні d елементів незрозуміло що виходить, підкажіть у чому проблема?!
#include
#include
#include
using namespace std;
недійсні Зази(INT s, INT * повинен);
int main(){
Int N,d;
srand(time(0));
cout <> n;
INT * р = новий INT[n];
INT * г = новий INT[n];
for (int i = 0; i < n; i ){
p[i] = rand() %100 ;
cout << p[i] << " ";
}
г = р;
cout <> d;
for (int i = 0; i < n; i ){
p[i] = p[i + d];
if (я == п – d)
for (int k = 0; i < d; i ){
p[до + п-д] = г[k];
}
}
cout << p[10];
//ZAZ(n, p);
cout << endl;
system("pause");
return 0;
}
недійсні Зази(INT s, INT * повинен)
{
for (int i = 0; i < s; i ){
cout << з[i] << " ";
}
}
3. Оголосіть покажчик на масив типу int і виділіть ПАМ'ЯТЬ ПАМ'ЯТЬ для 12-ти елементів. Необходимо написать функцию, которая поменяет значения четных и нечетных ячеек массива. Например есть массив из 4-х элементов:
Третє завдання на заміну парних і непарних елементів. Зробив через копіювання масиву.
ІНТ changeelements(INT * обр,INT * arr2, int size) //функція заміни місцями елементів
{
for (int i = 0; i < size; i )
{
if (i % 2 == 0)
{
arr2[i] = arr[i + 1];
}
else if(я 2%!= 0)
{
arr2[i] = arr[i – 1];
}
}
повернутися * arr2;
}
ІНТ fillarray(INT * обр, int size) //функція заповнення масиву
{
srand(time(NULL));
for (int i = 0; i < size; i )
{
arr[i] = rand() % 100;
}
повернутися * обр;
}
недійсна showarray(INT * обр, int size) //функція виведення масиву
{
cout << endl;
for (int i = 0; i < size; i )
{
cout << arr[i] << " ";
}
}
int main()
{
int size;
cout << "Enter massive's size" <> size; //вводимо розмір масиву
cout << "Massive's size = " << size << endl;
INT * обр = новий INT[size];
INT * arr2 = новий INT[size]; //створили другий масив,щоб скопіювати елементи
fillarray(arr,size);
showarray(arr, size);
changeelements(arr,arr2, size);
showarray(arr2, size);
delete[]arr;
delete[]arr2;
}
Це ж завдання тільки для непарної кількості елементів
using namespace std;
ІНТ changeelements(INT * обр,INT * arr2, int size)
{
for (int i = 0; i < size; i )
{
if (i % 2 == 0 && i + 1 == розмір) // умова виконається, якщо елементів непарна кількість
{
arr2[i] = arr[i];
}
else if (i % 2 == 0)
{
arr2[i] = arr[i + 1];
}
else if(я 2%!= 0)
{
arr2[i] = arr[i – 1];
}
}
повернутися * arr2;
}
ІНТ fillarray(INT * обр, int size) //функція заповнення масиву
{
srand(time(NULL));
for (int i = 0; i < size; i )
{
arr[i] = rand() % 100;
}
повернутися * обр;
}
недійсна showarray(INT * обр, int size)//функція виведення масиву
{
cout << endl;
for (int i = 0; i < size; i )
{
cout << arr[i] << " ";
}
}
int main()
{
int size;
cout << "Enter massive's size" <> size;
cout << "Massive's size = " << size << endl;
INT * обр = новий INT[size];
INT * arr2 = новий INT[size];
fillarray(arr,size);
showarray(arr, size);
changeelements(arr,arr2, size);
showarray(arr2, size);
delete[]arr;
delete[]arr2;
}