Теперь вам придется много практиковаться, чтобы закрепить знания и до конца разобраться. Решим несколько задач для начала.
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.
Результат работы программы:
4.7
41
40 думки про "Задачі та рішення: Указатели C ”
Не понял рішення першого завдання Або я погано читав і дивився відсів, або я просто щось забув, але як я зрозумів, цей покажчик – покажчик на покажчик, верно? Тобто, одним рядком коду ми створюємо два покажчика, один з яких вказує на інший покажчик, який в свою чергу вказує на 2. Послухати так маячня У мене багато питань, Як покажчик вказує просто на двійку? Або там ще і змінна створюється? чому спочатку, там потрібно поставити * а потім немає? *(*(р = новий подвійний *) = Новий подвійний) = 2; І що взагалі відбувається в цьому рядку я так і не розібрався Хто в цьому розбирається допоможіть будь ласка, нічого не розумію
Вказівником p присвоюється адреса динамічно виділеної пам'яті в якій зберігається покажчик на double, далі ми разадресуем p і отримуємо покажчик на тип double і динамічно виділяємо йому пам'ять, разадресаціей отримуємо значення цього осередку пам'яті (з подвійною) і присвоюємо йому значення 2.Чи записати по іншому: р = новий подвійний *; *р = новий подвійний; **р = 2;
Прочитав уроки і подивився відео до цього моменту, зі скрипом намагаюся зрозуміти: по 2 завданню, //double* pArrForFill = 0;// як ми таким чином покажчик на масив зробили? типо адресу першого осередку? Ще, чому так: //double* giveMemoryToArr(double* ptrArr, int sizeOfArr) { ptrArr = new double[sizeOfArr];// а не ось так? //double* giveMemoryToArr(double* ptrArr, int sizeOfArr) { double * ptrArr = новий double[sizeOfArr];//
double* pArrForFill = 0 ми створюємо покажчик але він просто порожній //double* giveMemoryToArr(double* ptrArr, int sizeOfArr) { double * ptrArr = новий double[sizeOfArr];// таким чином ми заново створюємо покажчик, а навіщо нам це робити коли він у нас вже є і ми його передаємо в функцію?
завдання №3 я бачу рішення таке, більш просте як мені здається порожнеча фуу(int * pmas) { for (int i = 0; i < 12; i ) { pmas[i] = i + 1; cout << " | " << pmas[i]; } cout << "\n\n============================================\n\n"; for (int ix = 0; ix 0) pmas[ix] = pmas[ix] + 1; else pmas[ix] = pmas[ix] – 1; }
} void main() { setlocale(LC_ALL, “rus”); int * mas = новий int[12]; фуу(але); for (int i = 0; i < 12; i ) { cout << " | " << але[i]; } }
А чи не простіше зробити рішення 3 завдання так?: //бібліотеки #include //std using namespace std;
void swapOddAndShow(INT * &p, int size) { for (int i = 0; i < size; i ) { if (p[i] % 2 == 0) { p[i – 1] = p[i]; p[i] = p[i – 1] – 1; } } for (int i = 0; i < size; i ) { //після cout << p[i] << endl; }
}
int main() { Const INT розмір = 12; int* pArr = новий int[size]; for (int i = 0; i < size; i ) { //раніше молодий лосось[i] = i + 1; cout << молодий лосось[i] << endl; }
cout << "=======================" << endl;
swapOddAndShow(молодий лосось, size);
delete[] молодий лосось; } Загалом у мене досвіду трохи, тому я можу помилятися.
Не понял рішення першого завдання
Або я погано читав і дивився відсів, або я просто щось забув, але як я зрозумів, цей покажчик – покажчик на покажчик, верно?
Тобто, одним рядком коду ми створюємо два покажчика, один з яких вказує на інший покажчик, який в свою чергу вказує на 2.
Послухати так маячня
У мене багато питань,
Як покажчик вказує просто на двійку? Або там ще і змінна створюється?
чому спочатку, там потрібно поставити * а потім немає?
*(*(р = новий подвійний *) = Новий подвійний) = 2;
І що взагалі відбувається в цьому рядку я так і не розібрався
Хто в цьому розбирається допоможіть будь ласка, нічого не розумію
Вказівником p присвоюється адреса динамічно виділеної пам'яті в якій зберігається покажчик на double, далі ми разадресуем p і отримуємо покажчик на тип double і динамічно виділяємо йому пам'ять, разадресаціей отримуємо значення цього осередку пам'яті (з подвійною) і присвоюємо йому значення 2.Чи записати по іншому:
р = новий подвійний *;
*р = новий подвійний;
**р = 2;
Спасибо, впринципі я приблизно так і думав, тільки у мене в голові це здавалося набагато складніше
за 4 завданням можете підказати з-за чого виникає ця помилка
“викликав спрацьовування точки зупину”
не кожен раз .
Прочитав уроки і подивився відео до цього моменту, зі скрипом намагаюся зрозуміти:
по 2 завданню, //double* pArrForFill = 0;// як ми таким чином покажчик на масив зробили? типо адресу першого осередку?
Ще, чому так:
//double* giveMemoryToArr(double* ptrArr, int sizeOfArr)
{
ptrArr = new double[sizeOfArr];//
а не ось так?
//double* giveMemoryToArr(double* ptrArr, int sizeOfArr)
{
double * ptrArr = новий double[sizeOfArr];//
double* pArrForFill = 0
ми створюємо покажчик але він просто порожній
//double* giveMemoryToArr(double* ptrArr, int sizeOfArr)
{
double * ptrArr = новий double[sizeOfArr];//
таким чином ми заново створюємо покажчик, а навіщо нам це робити коли він у нас вже є і ми його передаємо в функцію?
3 задача:
#include
using namespace std;
void fillArr(int * parr);
int main()
{
setlocale(LC_ALL, “rus”);
int arr[12]{};
cout << "Массив до функции:\n";
cout << "___________________________\n";
for (int i = 0; i < 12; i )
{
arr[i] = i + 1;
cout << arr[i] <<"|";
}
fillArr(arr);
cout << "\n___________________________\n";
cout << "\nМассив после функции: \n";
cout << "___________________________\n";
for (int i = 0; i < 12; i )
{
cout << arr[i] << "|";
}
cout << "\n___________________________\n";
return 0;
}
void fillArr(int * parr)
{
for (int i = 1; i < 12; i = 2)
{
int j = парр[i – 1];
парр[i – 1] = парр[i];
парр[i] = j;
}
}
завдання № 3
#include
using namespace std;
void FillArray(INT * обр, int size)
{
for (int i = 0; i < size; i )
{
arr[i] = rand() % 100;
}
}
порожнеча OutputArray(INT * обр, int size)
{
for (int i = 0; i < size; i )
{
cout << + 1 << ": " << arr[i] << "\t";
}
cout << endl;
}
int main()
{
int size = 12;
INT * обр = новий INT[size];
FillArray(arr, size);
OutputArray(arr, size);
for (int i = 0; i < size; i )
{
if ((+ 1) % 2 == 0)
{
arr[i] = arr[i] + arr[i – 1];
arr[i – 1] = arr[i] – arr[i – 1];
arr[i] = arr [i] – arr[i – 1];
}
}
OutputArray(arr, size);
return 0;
}
завдання №3
я бачу рішення таке, більш просте як мені здається
порожнеча фуу(int * pmas)
{
for (int i = 0; i < 12; i )
{
pmas[i] = i + 1;
cout << " | " << pmas[i];
}
cout << "\n\n============================================\n\n";
for (int ix = 0; ix 0)
pmas[ix] = pmas[ix] + 1;
else
pmas[ix] = pmas[ix] – 1;
}
}
void main()
{
setlocale(LC_ALL, “rus”);
int * mas = новий int[12];
фуу(але);
for (int i = 0; i < 12; i )
{
cout << " | " << але[i];
}
}
А чи не простіше зробити рішення 3 завдання так?:
//бібліотеки
#include
//std
using namespace std;
void swapOddAndShow(INT * &p, int size) {
for (int i = 0; i < size; i ) {
if (p[i] % 2 == 0) {
p[i – 1] = p[i];
p[i] = p[i – 1] – 1;
}
}
for (int i = 0; i < size; i ) { //після
cout << p[i] << endl;
}
}
int main()
{
Const INT розмір = 12;
int* pArr = новий int[size];
for (int i = 0; i < size; i ) { //раніше
молодий лосось[i] = i + 1;
cout << молодий лосось[i] << endl;
}
cout << "=======================" << endl;
swapOddAndShow(молодий лосось, size);
delete[] молодий лосось;
}
Загалом у мене досвіду трохи, тому я можу помилятися.
олівець-623a3e4b767f2986601500/ “Частотний словник слів “