Обращение к элементам одномерного динамического массива
Адресация элементов динамического массива осуществляется аналогично адресация элементов статического массива, то есть с помощью индексированного имени.
Синтаксис:
ИмяМассива[ВыражениеТипаКонстанты];
или
ИмяМассива[ЗначениеИндекса];
Например:
mas[5] – индекс задается как константа,
sl[i] – индекс задается как переменная,
array[4*p] – индекс задается как выражение.
Пример 1. Сформировать динамический одномерный массив, заполнить его случайными числами. Преобразовать массив таким образом, чтобы в первой его половине располагались элементы, стоявшие в чётных позициях, а во второй половине – элементы, стоявшие в нечётных позициях.
#include <iostream.h>
void main() {
int *a, n, i;
cout << "Введите n: ";
cin >> n;
cout << ' ';
a = new int [n]; //Выделение памяти под массив
for (i=0; i<n; i++) {
cout << "Введите a[" << i << "]: ";
cin >> a[i];
cout << ' ';
}
int *buf = new int [n];
//Выделение памяти под вспомогательный массив
int j = 0; //Индекс вспомогательного массива
for (i=0; i<n; i+=2) {
//Переписываем элементы с чётным индексом в новый массив
buf[j] = a[i];
j++;
}
for (i=1; i<n; i+=2) {
//Переписываем элементы с нечётным индексом в новый массив
buf[j] = a[i];
j++;
}
cout << "Преобразованный: " << ' ';
for (i=0; i<n; i++)
cout << buf[i] << ' ';
delete [] a; //Освобождаем память
delete [] buf;
}
Отметим, что указатель на массив не обязательно должен показывать на начальный элемент некоторого массива. Он может быть сдвинут так, что начальный элемент будет иметь индекс, отличный от нуля, причем он может быть как положительным, так и отрицательным.
Пример 2.
#include <stdio.h>
#include <stdlib.h>
void main() {
float *mas;
int m;
scanf("%d",&m);
mas=(float *)calloc(m,sizeof(float));
//сейчас указатель q показывает на начало массива
mas[0]=22.3;
mas-=5;
/*теперь начальный элемент массива имеет индекс 5,
а конечный элемент индекс n-5*/
mas[5]=1.5;
/*сдвиг индекса не приводит к перераспределению массива
в памяти и изменится начальный элемент*/
mas[6]=2.5; // это второй элемент
mas[7]=3.5; // это третий элемент
mas+=5;
/*теперь начальный элемент вновь имеет индекс 0,
а значения элементов q[0], q[1], q[2] равны
соответственно 1.5, 2.5, 3.5*/
mas+=2;
/*теперь начальный элемент имеет индекс -2, следующий -1,
затем 0 и т.д. по порядку*/
mas[-2]=8.2;
mas[-1]=4.5;
mas-=2;
/*возвращаем начальную индексацию, три первых элемента
массива q[0],q[1],q[2], имеют значения 8.2, 4.5, 3.5*/
mas--;
/*вновь изменим индексацию. Для освобождения области
памяти, в которой размещен массив q используется
функция free(q), но поскольку значение указателя q
смещено, то выполнение функции free(q) приведет к
непредсказуемым последствиям.
Для правильного выполнения этой функции указатель q
должен быть возвращен в первоначальное положение */
free(++mas);
}
Пример 3. Задача Иосифа Флавия или считалка Джозефуса.
Задача в своей основе имеет легенду. Отряд из 41-го сикария, защищавший галилейскую крепость Массада, не пожелал сдаваться в плен блокировавшим его превосходящим силам римлян. Сикарии стали в круг и договорились, что каждые два воина будут убивать третьего, пока не погибнут все. Самоубийство – тяжкий грех, но тот, кто в конце концов останется последним, должен будет его совершить. Иосиф Флавий, командовавший этим отрядом, якобы быстро рассчитал, где нужно стать ему и его другу, чтобы остаться последними. Но не для того, чтобы убить друг друга, а чтобы сдать крепость римлянам. В современной формулировке задачи участвует n воинов и убивают каждого k-го. Требуется определить номера m и t начальных позиций двоих воинов, которые должны будут остаться последними.
#include<stdio.h>
#include<stdlib.h>
void kill(int *mass,int n,int i);
void krug(int *mass,int n,int k, int i=0);
void main() {
int n,k,*mass,i;
FILE *f;
f=fopen("input.txt","r");
fscanf(f,"%d %d",&n,&k);
fclose(f);
mass=(int *)malloc(n*sizeof(int));
for (i=0;i<n;i++) mass[i]=i+1;
f=fopen("output.txt","w");
fprintf(f,"Исходная нумерация: \n");
for (i=0;i<n;i++) fprintf(f,"%d ",mass[i]);
fclose(f);
krug(mass,n,k);
f=fopen("output.txt","a+");
fprintf(f,"\nОставшиеся в живых: \n");
for (i=0;i<k;i++) fprintf(f,"%d ",mass[i]);
fclose(f);
free(mass);
}
void kill(int *mass,int n,int i) {
int j;
for (j=i;j<n-1;j++)
mass[j]=mass[j+1];
}
void krug(int *mass,int n,int k,int i) {
int ii;
if (n>k) {
ii=i+k-1;
if (ii>=n) ii=ii%n;
kill(mass,n,ii);
krug(mass,n-1,k,ii);
}
}
Перед компиляцией кода в среде MSVC++ необходимо в меню Options/Project отключить режим Use Microsoft Foundation Classes.
Задания
1.Наберите коды программ из Примера 1 и 2. Выполните компиляцию и запуск программ.
2.Задан массив. Определить сколько раз меняется знак в данной последовательности чисел, запомнить номера позиций, в которых меняется знак.
3.Задана последовательность из N вещественных чисел. Вычислить сумму чисел, порядковые номера которых являются числами Фибоначчи.
Домашние задания
1.Наберите код программы из Примера 3. Выполните компиляцию и запуск программы.
2.Задана последовательность из N вещественных чисел. Найти частное средних арифметических значений элементов с нечетными и четными индексами.
3. Индивидуальное задание. Номер варианта определяется по журналу. Напишите программу, оформив её в виде функций генерации, вывода и обработки массивов. Сформировать динамический одномерный массив, заполнить его случайными числами и вывести на печать. Выполнить указанное в варианте задание и вывести полученный массив на печать. Реализуйте данную программу двумя способами: 1) с помощью операций new и delete; 2) с помощью библиотечных функций malloc (calloc) и free.
Варианты индивидуального задания
№ | Задание |
1. | Удалить первый четный элемент. |
2. | Удалить первый отрицательный элемент. |
3. | Удалить элемент с заданным ключом (значением). |
4. | Удалить элементы, равные среднему арифметическому элементов массива. |
5. | Удалить элемент с заданным номером. |
6. | Удалить N элементов, начиная с номера K. |
7. | Удалить все четные элементы. |
8. | Удалить все элементы с четными индексами. |
9. | Удалить все нечетные элементы. |
10. | Удалить все элементы с нечетными индексами. |
11. | Добавить элемент в начало массива. |
12. | Добавить элемент в конец массива. |
13. | Добавить К элементов в начало массива. |
14. | Добавить К элементов в конец массива. |
15. | Добавить К элементов, начиная с номера N. |
16. | Добавить после каждого отрицательного элемента его модуль. |
17. | Добавить после каждого четного элемента элемент со значением 0. |
18. | Добавить по К элементов в начало и в конец массива. |
19. | Добавить элемент с номером К. |
20. | Добавить после каждого положительного элемента число ноль. |
21. | Удалить элемент с заданным номером. |
22. | Удалить N элементов, начиная с номера K. |
23. | Удалить все четные элементы. |
24. | Удалить все элементы с четными индексами. |
25. | Удалить все нечетные элементы. |
26. | Удалить все элементы с нечетными индексами. |
27. | Удалите элементы, большие среднего арифметического элементов массива. |
28. | Удалите элементы, меньшие среднего арифметического элементов массив. |
Дата добавления: 2015-02-16; просмотров: 1864;