Вы находитесь на странице: 1из 9

Лабораторная работа №4.

Одномерные массивы и указатели

Цель работы: приобретение навыков программирования при решении задач с


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

Общие сведения.

Массивы - это последовательная группа ячеек памяти, имеющих одинаковое имя.


Доступ к отдельным элементам массивов организуется посредством указания имени
массива и порядкового номера (индекса) необходимого элемента. Индекс определяет
положение элемента относительно начала массива.

При описании массива необходимо указать:

1) тип элементов;

2) имя массива;

3) размерность массива.

Общая форма описания массива имеет вид:

тип имя_масссива [размер1][размер 2]….;

При описании одномерного массива в скобках указывается только один индекс,


определяющий количество элементов в массиве. Например:

float A[5], B[25];

При описании можно инициализировать элементы массива заданными значениями.

Например:

int D[5]={23, 45, 32, 12, 88};

В языке Си элементы в массиве нумеруются, начиная с нуля, т.е. индекс первого


элемента равен 0, а индекс последнего элемента – на единицу меньше размера массива.

Связь между указателями и массивами. В языке Си массивы и указатели тесно


связаны.

Указатель – это переменная, в которой хранится адрес другой переменной или


участка памяти.

Указатель объявляется следующим образом:


тип *<имя переменной>;

Указатели объявляются в списке переменных, но перед их именем ставится знак


*. Указатель всегда указывает на переменную того типа, для которого он был объявлен.

Унарная операция &, примененная к некоторой переменной, показывает, что нам


нужен адрес этой переменной, а не ее текущее значение. Если переменная uk объявлена как
указатель, то оператор присваивания uk=&x означает: "взять адрес переменной x и
присвоить его значение переменной-указателю uk".

Унарная операция *. примененная к указателю, обеспечивает доступ к содержимому


ячейки памяти, на которую ссылается указатель. Например, *uk можно описать словами
как "то, что содержится по адресу, на который указывает uk".

Доступ к любому элементу массива может быть выполнен с помощью указателей.


Если uk -указатель на целое, описанный как int *uk, то uk после выполнения
операции uk=&a[0] содержит адрес a[0], а uk+i указывает на i -й элемент массива. Таким
образом, uk+i является адресом a[i]. Так как имя массива в программе отождествляется с
адресом его первого элемента, то выражение uk=&a[0] эквивалентно
такому: uk=a. Поэтому значение a[i] можно записать как *(a+i). Применив к этим двум
элементам операцию взятия адреса, получим, что &a[i] и a+i идентичны.

Рассмотрим пример программы , которая печатает строку символов в обратном


порядке.

#include <stdio.h>
main()
{
char *uk1,*uk2;
uk1=uk2="ЯЗЫКИ И ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ";
while(*uk2!='\0')
putchar(*uk2++);
putchar('\n');
while(--uk2 >= uk1)
putchar(*uk2);
putchar('\n');
}

В самом начале указателям uk1 и uk2 присваивается начальный адрес


строки "ЯЗЫКИ И ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ". Затем строка
посимвольно печатается и одновременно указатель uk2 смещается вдоль строки. В конце
вывода uk2 указывает на последний символ исходной строки. Во втором цикле while все
тот же указатель uk2 начинает изменяться в обратном направлении, уменьшаясь до тех пор,
пока он не будет указывать на нулевой элемент массива, обеспечивая выдачу строки в
обратном порядке.

Задание А.

Составить блок-схему и программу обработки одномерного массива. Элементы


массива заполнить, используя функцию генератора случайных чисел.
Пример. Дан массив А[n]. Заполнить массив B[n] элементами массива А[n] ,
начиная с последнего и осуществить циклический сдвиг вправо на К позиций, где К-число
положительных элементов.

На рисунке 2.4.1 приведена блок-схема решения задания


Рисунок 2.4.1 -Блок-схема решения задания

Программа может иметь следующий вид:

#include <stdlib.h>

# include <conio.h>

# include <stdio.h>

#define n 10

int main ()

{ int buf,j,pol,i,b[n], a[n];

for (i = 0; i < n; i++)

a[i]=rand()%10-5;pol=0;

printf ("\n \n Сгенерированный массив a[n] \n");

for (i=0;i< n;i++)

printf ("%d ",a[i]);

j=n-1;

for (i=0;i< n;i++)

{b[j]=a[i]; j=j-1;

if (a[i]>=0)pol++;}

printf ("\n Число положительных элементов \n pol=%d",pol);

printf ("\n \n вывод массива b[n] \n");

for (i=0;i< n;i++)

printf ("%d ",b[i]);

for (i=0;i<pol;i++)

{ buf=b[n-1];

for(j=n-1;j>0;j--)

b[j]=b[j-1]; b[0]=buf; }

printf ("\n \n Сдвиг элементов массива b[n] на %d позиций \n", pol);


for (i=0;i< n;i++)

printf ("%d ",b[i]);

printf ("\n");

system("PAUSE");

return 0;}

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

Сгенерированный массив a[n]

1 2 3 -4 -5 -1 -2 -3 -7 9

Число положительных элементов

pol=4

вывод массива b[n]

9 -7 -3 -2 -1 -5 -4 3 2 1

Сдвиг элементов массива b[n] на 4 позиций

-4 3 2 1 9 -7 -3 -2 -1 -5

Варианты задания А

При выполнении задания элементы массива генерировать с помощью генератора


случайных чисел.

1. Дан массив A[N]. Заполнить массив В[N] элементами массива A[N] следующим
образом: вначале заполнить элементами с четными индексами, а затем — с
нечетными. Осуществить циклический сдвиг вправо на k позиций, где k – число
положительных элементов

2. Дан массив A[N]. Заполнить массив В[N] элементами массива A[N] следующим
образом: вначале заполнить элементами с |нечетными индексами, а затем —с
четными. Осуществить циклический сдвиг вправо на k позиций, где k – число
отрицательных элементов

3. Дан массив A[N]. Заполнить массив В[N] элементами массива A[N], которые
удовлетворяют двойному неравенству: A[1] <A[i] < A[10]. Незаполненные элементы
массива В[N] заполнить оставшимися элементами массива A[N]. Осуществить
циклический сдвиг влево на k позиций, где k – число оставшихся элементов массива A[N].

4. Дан массив A[N]. Заполнить массив В[N] элементами массива A[N], которые
удовлетворяют двойному неравенству: A[1] < A[i] или A[i] < A[10]. Незаполненные
элементы массива В[N] заполнить оставшимися элементами массива A[N]. Осуществить
циклический сдвиг вправо на k позиций, где k – число оставшихся элементов массива A[N].

5. Дан целочисленный массив размера N. Преобразовать его, прибавив к четным


числам первый элемент. Первый элементы массива не изменять. Осуществить циклический
сдвиг вправо на k позиций, где k – число четных элементов

6. Дан целочисленный массив размера N. Преобразовать его, прибавив к нечетным


числам первый элемент. Первый элемент массива не изменять. Осуществить циклический
сдвиг вправо на k позиций, где k – число четных элементов

7. Дан целочисленный массив размера N. Преобразовать его, прибавив к четным


числам последний элемент. Последний элемент массива не изменять. Осуществить
циклический сдвиг влево на k позиций, где k – число нечетных элементов

9. Дан целочисленный массив размера N. Преобразовать его, прибавив к четным


числам первый элемент. Первый элемент массива не изменять. Осуществить циклический
сдвиг вправо на k позиций, где k – число нечетных элементов

10. Поменять местами минимальный и максимальный элементы массива размера


10. Осуществить циклический сдвиг вправо на k позиций, где k – число элементов,
расположенных между его минимальным и максимальным элементами.

11. Дан массив A[N]. Все положительные элементы уменьшить на


значение минимального элемента. Осуществить циклический сдвиг вправо на k позиций,
где k – число положительных элементов

12. Дан массив A[N]. Все отрицательные элементы увеличить на значение


максимального элемента. Осуществить циклический сдвиг влево на k позиций, где k –
число отрицательных элементов

13. Дан массив размера 10. Переставить в обратном порядке элементы массива,
расположенные между его минимальным и максимальным элементами. Осуществить
циклический сдвиг элементов массива влево на k позиций, где k – число элементов,
расположенных между его минимальным и максимальным элементами

14. Дан массив размера N. Осуществить циклический сдвиг элементов массива влево
на k позиций, где k – индекс минимального элемента.

15. Дан массив размера N. Осуществить циклический сдвиг элементов массива


вправо на k позиций, где k – индекс максимального элемента.

16. Дан массив A[N]. Осуществить циклический сдвиг элементов массива вправо
на k позиций, где k – целая часть среднего арифметического значения положительных
элементов массива A[N].
17. Дан массив A[N]. Осуществить циклический сдвиг элементов массива вправо
на k позиций, где k – целая часть среднего арифметического значения отрицательных
элементов массива A[N].

18. Дан массив A[N]. Осуществить циклический сдвиг элементов массива вправо
на k позиций, где k – целая часть среднего арифметического значения четных элементов
массива A[N].

19. Дан массив A[N]. Осуществить циклический сдвиг элементов массива вправо
на k позиций, где k – целая часть среднего арифметического значения нечетных элементов
массива A[N].

20. Дан массив A[N]. Все отрицательные элементы уменьшить на


значение минимального элемента. Осуществить циклический сдвиг вправо на k позиций,
где k – число положительных элементов

Задание Б

Составить программу обработки одномерного массива. Доступ к элементам массива


осуществлять с помощью указателя. Элементы массива заполнить, используя функцию
генератора случайных чисел.

Пример Дан массив А[n]. Заполнить массив B[n] элементами массива А[n] ,
начиная с последнего и осуществить циклический сдвиг вправо на К позиций, где К-число
положительных элементов.

#include <stdlib.h>

# include <conio.h>

# include <stdio.h>

#define n 10

int main ()

{ int buf,j,pol,i,b[n], *pa,*pb,*p, a[n];

for (i = 0; i < n; i++) a[i]=rand()%10-5;

pol=0;pa=&a[0];

pb=&b[9];

printf ("\n \n Сгенерированный массив a[n] a[n] \n");

for (i=0;i< n;i++)


printf ("%d ",*pa++);

pa=&a[0];

for (i=0;i< n;i++)

{*pb=*pa;

if (*pa>=0)pol++;

--pb;

++pa; }

printf ("\n Число положительных элементов \n pol=%d",pol);

printf ("\n \n вывод массива b[n] \n");

pb=&b[0];

for (i=0;i<n;i++)

printf ("%d ",*pb++);

pb=&b[9];

p=&b[0];

for (i=0;i<pol;i++)

{ buf=*pb;

for(j=0;j<n;j++)

*pb=*(--pb);

*p=buf;

p=&b[0];

pb=&b[9]; }

printf ("\n \n Сдвиг элементов массива b[n] на %d позиций \n", pol);

pb=&b[0];

for (i=0;i< n;i++)

printf ("%d ",*pb++);

printf ("\n");
system("PAUSE");

return 0;

Варианты задания Б

Варианты задания Б соответствуют вариантам задания А данной лабораторной


работы.

Контрольные вопросы.

1) Каким образом определяются переменные типа массив?

2) Какие операторы языка Си используются при обработке элементов массива?

3) Как осуществляется доступ к отдельному элементу одномерного массива с помощью


указателя?

4) Каким образом выводятся элементы массива на экран?

5) Какой результат унарной операции &?

6) Какой результат унарной операции *?

7) Выражение uk=&a[0] эквивалентно uk=a?

8) Выражения &a[i] и a+i идентичны?

Вам также может понравиться