Теперь вам придется много практиковаться, чтобы закрепить знания и до конца разобраться. Решим несколько задач для начала.
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: Указатели в С++, Двумерный динамический массив
Первое на что надо обратить внимание – это объявление динамического двумерного массива, выделение памяти для него и её освобождение. Когда мы рассматривали тему Двумерные массивы в С++ мы затрагивали тот вопрос, что двумерный массив – это массив массивов. Например если объявлен двумерный массив int 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;
Если пропустить первый шаг – произойдет утечка памяти. Так как ячейки занимаемые данными, будут отмечены как зарезервированная память и не смогут использоваться в программе повторно.
Передавая двумерный массив в функцию, нам необходимо передать указатель на указатель.
void show2Arr (int** ArrForChange, int strAmount, int colAmount);
void fill2Array (int** ArrForChange, int strAmount, int colAmount);
Когда функция получает этот указатель на указатель, она далее может с ним работать, как с обычным двумерным массивом. Например используя вложенные циклы, отображать данные на экран, как показано в строках 44 – 52. Или внести данные в ячейки массива – строки 58 – 64.
Разбираться с чужим кодом гораздо сложнее и противнее, чем написать свой (тем более, если редактор этого сайта искажает ваш код). Ответ на вопрос “а так сойдет?” ищите всегда компиляцией и выполнением вашего кода, лучше на разных наборах входных данных.
Может быть в третьей задаче заместо добавления переменной менять местами без добавления переменной? Arr[i] += Arr[i + 1]; Arr[i + 1] = Arr[i] – pArr[i + 1]; Arr[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;
void zaz(int s, int *ar); int main(){ int n,d; srand(time(0)); cout <> n; int *p = new int[n]; int *z = new int[n];
for (int i = 0; i < n; i++){ p[i] = rand() %100 ; cout << p[i] << " "; } z = p;
cout <> d; for (int i = 0; i < n; i++){ p[i] = p[i + d]; if (i == n – d) for (int k = 0; i < d; i++){ p[k+n-d] = z[k]; } } cout << p[10]; //zaz(n, p); cout << endl; system("pause"); return 0; }
void zaz(int s, int *ar) { for (int i = 0; i < s; i++){ cout << ar[i] << " "; }
3. Объявите указатель на массив типа int и выделите ПАМЯТЬ ПАМЯТЬ для 12-ти элементов. Необходимо написать функцию, которая поменяет значения четных и нечетных ячеек массива. Например есть массив из 4-х элементов:
Третье задание на замену четных и нечетных элементов. Сделал через копирование массива.
int changeelements(int* arr,int*arr2, int size) //функция замены местами элементов { for (int i = 0; i < size; i++) { if (i % 2 == 0) { arr2[i] = arr[i + 1]; } else if(i%2!=0) { arr2[i] = arr[i – 1]; } }
return *arr2; }
int fillarray(int* arr, int size) //функция заполнения массива { srand(time(NULL)); for (int i = 0; i < size; i++) { arr[i] = rand() % 100; } return *arr; } void showarray(int* arr, 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* arr = new int[size]; int* arr2 = new int[size]; //создали второй массив,чтобы скопировать элементы fillarray(arr,size); showarray(arr, size); changeelements(arr,arr2, size); showarray(arr2, size); delete[]arr; delete[]arr2; }
Это же задание только для нечетного количества элементов
using namespace std; int changeelements(int* arr,int*arr2, int size) { for (int i = 0; i < size; i++) { if (i % 2 == 0 && i + 1 == size) // условие выполнится, если элементов нечетное количество { arr2[i] = arr[i]; } else if (i % 2 == 0) { arr2[i] = arr[i + 1]; } else if(i%2!=0) { arr2[i] = arr[i – 1]; }
}
return *arr2; }
int fillarray(int* arr, int size) //функция заполнения массива { srand(time(NULL)); for (int i = 0; i < size; i++) { arr[i] = rand() % 100; } return *arr; } void showarray(int* arr, 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* arr = new int[size]; int* arr2 = new int[size]; fillarray(arr,size); showarray(arr, size); changeelements(arr,arr2, size); showarray(arr2, size); delete[]arr; delete[]arr2; }
а так сойдет?
Разбираться с чужим кодом гораздо сложнее и противнее, чем написать свой (тем более, если редактор этого сайта искажает ваш код).
Ответ на вопрос “а так сойдет?” ищите всегда компиляцией и выполнением вашего кода, лучше на разных наборах входных данных.
Может быть в третьей задаче заместо добавления переменной менять местами без добавления переменной?
Arr[i] += Arr[i + 1];
Arr[i + 1] = Arr[i] – pArr[i + 1];
Arr[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;
void zaz(int s, int *ar);
int main(){
int n,d;
srand(time(0));
cout <> n;
int *p = new int[n];
int *z = new int[n];
for (int i = 0; i < n; i++){
p[i] = rand() %100 ;
cout << p[i] << " ";
}
z = p;
cout <> d;
for (int i = 0; i < n; i++){
p[i] = p[i + d];
if (i == n – d)
for (int k = 0; i < d; i++){
p[k+n-d] = z[k];
}
}
cout << p[10];
//zaz(n, p);
cout << endl;
system("pause");
return 0;
}
void zaz(int s, int *ar)
{
for (int i = 0; i < s; i++){
cout << ar[i] << " ";
}
}
3. Объявите указатель на массив типа int и выделите ПАМЯТЬ ПАМЯТЬ для 12-ти элементов. Необходимо написать функцию, которая поменяет значения четных и нечетных ячеек массива. Например есть массив из 4-х элементов:
Третье задание на замену четных и нечетных элементов. Сделал через копирование массива.
int changeelements(int* arr,int*arr2, int size) //функция замены местами элементов
{
for (int i = 0; i < size; i++)
{
if (i % 2 == 0)
{
arr2[i] = arr[i + 1];
}
else if(i%2!=0)
{
arr2[i] = arr[i – 1];
}
}
return *arr2;
}
int fillarray(int* arr, int size) //функция заполнения массива
{
srand(time(NULL));
for (int i = 0; i < size; i++)
{
arr[i] = rand() % 100;
}
return *arr;
}
void showarray(int* arr, 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* arr = new int[size];
int* arr2 = new int[size]; //создали второй массив,чтобы скопировать элементы
fillarray(arr,size);
showarray(arr, size);
changeelements(arr,arr2, size);
showarray(arr2, size);
delete[]arr;
delete[]arr2;
}
Это же задание только для нечетного количества элементов
using namespace std;
int changeelements(int* arr,int*arr2, int size)
{
for (int i = 0; i < size; i++)
{
if (i % 2 == 0 && i + 1 == size) // условие выполнится, если элементов нечетное количество
{
arr2[i] = arr[i];
}
else if (i % 2 == 0)
{
arr2[i] = arr[i + 1];
}
else if(i%2!=0)
{
arr2[i] = arr[i – 1];
}
}
return *arr2;
}
int fillarray(int* arr, int size) //функция заполнения массива
{
srand(time(NULL));
for (int i = 0; i < size; i++)
{
arr[i] = rand() % 100;
}
return *arr;
}
void showarray(int* arr, 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* arr = new int[size];
int* arr2 = new int[size];
fillarray(arr,size);
showarray(arr, size);
changeelements(arr,arr2, size);
showarray(arr2, size);
delete[]arr;
delete[]arr2;
}