Программа должна после запуска на исполнение выводить информацию об авторе, назначении программы (приводится лабораторное задание полностью), перед запросом ввода данных с клавиатуры обязательно должно быть сообщение о типе и количестве вводимых данных

Вид материалаПрограмма

Содержание


Тема №4. Функции в языке Си.
Тема №5. Обработка одномерных массивов.
Краткая теоретическая справка и рекомендации по выполнению
Примеры функций для работы с одномерными массивами.
New_Item(c, i, range1, range2)
Exchange ( p, 0, indexMin ); }
Подобный материал:
1   2   3   4   5   6   7

Тема №4. Функции в языке Си.


Задание: реализуйте задачу по теме №3 с использованием функций.

Пример решения задачи по теме №3 с использованием функций.

Для иллюстрации решения рассмотрим алгоритм, представленный для языка Паскаль. Сделаем «перевод» с языка Паскаля на язык Си, указав отличия.

Во-первых, нет необходимости процедуры определения предыдущего элемента перед предыдущим, так как эта операция в языке Си делается в одно действие.

Во-вторых, напомним, что в языке Си нет понятия «процедура», но есть функция, которая не возвращает никакого значения.

В-третьих, не ставьте знак «точка с запятой» после закрывающей круглой скобки в перечне параметров.

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

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

Шестое – локальные переменные пишутся внутри операторных скобок, определяющих тело функции.

#include

#include

//Описание функции печати части строки

void Part(char First, char Last)

{ char C;

C = First;

Last --;

while (C <= Last)

{

printf("%2c",C);

C+=2;

}

}

//Основная часть программы

int main()

{

const int F1= 'K';

const int F2='A';

char First1 =F1, First2 =F2;


while (First1>='C')

{

Part(First1,F1); // Печать первой части строки

Part(First2,First1); // Печать второй части строки

printf("\n");

First1 -=2;

}

return 0;

}

}Контрольные вопросы по теме №4
  1. Что такое глобальные переменные?
  2. Для чего нужны параметры в функции?
  3. Назначение функций?
  4. Что такое локальные переменные?
  5. Что такое параметры-переменные?
  6. Что такое параметры-значения?
  7. Что такое рекурсия?
  8. Что такое условие выхода из рекурсии?
  9. Что такое формальные параметры?
  10. Что такое фактические параметры?

Тема №5. Обработка одномерных массивов.


Задание: заполните один или несколько одномерных массивов (по индивидуальному заданию). Распечатайте результат заполнения. Проведите преобразование (по индивидуальному заданию) и упорядочивание (сортировку) массивов. Распечатайте результирующие массивы. Сортировки проведите тремя методами. При использовании каждого из методов желательно использовать свой массив. Если количество массивов меньше трех, то один из массивов перед сортировкой надо скопировать в дополнительный массив и провести его сортировку.

Краткая теоретическая справка и рекомендации по выполнению

Для переменных типа массив в языке Си всегда в качестве индекса используется целое число. Это связано с тем, что переменная типа массив является указателем на начало этого одномерного массива. Аналогично в математике и физике определяется относительная система координат. А индекс – это смещение относительно начала отсчета в этой системе. Причем компилятор языка Си не отслеживает правильность использования индекса. По этой причине при неаккуратном программировании может возникнуть множество проблем, вплоть до «зависания» компьютера, если только операционная система не «отследит» обращение по некорректному адресу.

Самый безобидный вариант некорректного использования индексов приведен в следующем коротком фрагменте программы:

int x; int y[2]; int z;

void main()

{

x=1; z=4;

y[0]=2; y[1]=3; // Корректное обращение к элементам массива

y[-1]=5; y[2]=6; // Некорректное обращение к элементам массива

}

Здесь три глобальные переменные x, y, z расположены друг за другом. Так как они глобальные, то в такой же последовательности они будут располагаться в оперативной памяти. Поэтому присваивание элементу y[–1] значения 5, приведет к изменению переменной x, а изменение элемента y[2] изменит переменную z. На этом же примере легко можно убедиться, что при объявлении переменной типа массив, в квадратных скобках указывается общее количество элементов массива. Если количество элементов переменной типа массив было N, то первый элемент будет с индексом 0, а последний – с индексом (N–1).

Для одномерных массивов также распространена другая форма обращения к отдельному элементу. В записи *(y+1), в соответствии с порядком выполнения операций языка Си, сначала вычисляется адрес размещения переменной в оперативной памяти (y+1), а потом определяется сам элемент с помощью оператора «звездочка» (разыменование). При выполнении лабораторного задания необходимо хотя бы в одном месте использовать обращение к элементу массива через указатель.

Примеры функций для работы с одномерными массивами.


// 1. Инициализация генератора случайных чисел

void Randomize()

{

srand(time(0));

}

Функция инициализации генератора случайных чисел использует библиотечные функции srand, в которую в качестве параметра передается текущее время time(0). Прототип функции time находится в заголовочном файле .

//2. Генератор случайного числа в диапазоне от 0 до range

int Random(int range)

{

return (rand() % range);

}

Функция генератора случайных чисел использует библиотечную функцию rand (прототип в файле stdlib.h). Функция rand вычисляет псевдослучайное число в диапазоне от 0 до 65535. Для задания числа в заданном диапазоне используется остаток от целочисленного деления генерируемого числа на диапазон range.

// 3. Проверка повторения случайного числа

// c - указатель начала массива, n - индекс нового элемента

int Test_Repetition(int *c, int n)

{ int x, j;

x = 0; // Считаем, что значение новое

// Цикл сравнения со всеми предыдущими

for (j=0; j

if (*(c+n)==*(c+j))

{

x = 1; // Элементы совпали

break;

}

return x;

}


Функция проверки повторения случайного числа используется только тогда, когда по условию задачи необходимо генерировать неповторяющиеся случайные числа. Эта функция простым перебором сравнивает новое число (c[n]) со всеми значениями массива.

// 4. Добавить новый элемент

// с - указатель начала массива, n - номер нового элемента

// range1, range2 – левая и правая границы диапазона

void New_Item(int *c, int n, int range1, int range2)

{ int x = 0; // Элементы массива разные

do

{

c[n] = Random(range2 - range1) + range1; // Новое значение

x =Test_Repetition(c,n); // Проверка на повторение

}

while (x==1); // Повторять, когда элементы совпали

}

В этой функции, если проверка на «неповторимость» элемента не требуется, достаточно использовать только строку присваивания в переменную c[n] результата работы функции Random.

// 5. Заполнение одномерного массива

// c - массив, n - количество элементов

void Filling (int *c, int n, int range1, int range2)

{ int i;

c[0]=Random (range2 - range1) + range1; // Элемент с индексом 0.

// Цикл заполнения массива

for (i=1;i

New_Item(c, i, range1, range2);

}

Для реализации заполнения неповторяющимися числами, в функции заполнения массива приходится первое значение (с индексом 0) задавать отдельно, а не в цикле.

// 6. Распечатка одномерного массива

void Print(int *c, int n)

{ int i;

for (i=0; i

printf("%4d",c[i]);

puts(""); // Переход на новую строку

}

// 7. Поиск минимального значения

// с – указатель на начало одномерного массива,

// n - количество элементов массива,

// index – указатель на индекс минимума

int Min(int *c, int n, int *index)

{ int i, min;

min = c[0]; // Начальное значение минимума

(*index) = 0; // Начальное значение индекса минимума

for ( i=1; i

if (c[i]

{

min = c[i];

(*index) = i;

}

return min;

}

В функции поиска минимального значения в массиве обратите внимание на использование параметра-переменной index, которая передается указателем.

// 8. Создание дубликата массива в динамической памяти

int * Copy (int *c, int n)

{ int *m, i;

// Резервирование памяти под дубликат массива

m = (int*)malloc(sizeof(int)*n);

// Копирование массива

for ( i = 0; i

// Функция возвращает адрес нового массива

return m;

}

Обратите внимание, что количество резервируемой памяти определяется типом данных одного элемента и количеством элементов в массиве ((sizeof(int)*n)). Так как библиотечная функция для резервирования памяти (malloc) возвращает нетипированный указатель, то требуется преобразование к типу. В данном примере – это преобразование к типу указателя на целое число (int *).

// 9. Обмен элементов местами в массиве

void Exchange (int *c, int n, int k)

{ int tmp; //Переменная для временного хранения данных

tmp = c[n];

c[n] = c[k];

c[k] = tmp;

}

// 10 .Сортировка методом прямого поиска

void SearchSort ( int *c, int n )

{ int i, min, indexMin; int *p;

for ( i=0; i

{ p = (c+i); // Задать адрес начала массива

min = Min (p, n-i, &indexMin); // Найти минимум в массиве

// Обменять местами минимальный элемент с первым

Exchange ( p, 0, indexMin ); }

}

Основная часть программы для обработки одномерных массивов может содержать заголовочные файлы, предварительное описание функций и главную часть программы. Предварительно описанные функции (в виде заголовков) могут быть представлены после главной функции.

#include

#include

#include

#include


#define N 15

void Randomize();

int Random(int range);

int Test_Repetition(int *c, int n);

void New_Item(int *c, int n, int range1, int range2);

void Filling (int *c, int n, int range1, int range2);

void Print(int *c, int n);

int Min(int *c, int n, int *index);

int * Copy (int *c, int n);

void Exchange (int *c, int n, int k);

void SearchSort ( int *c, int n );


// Главная функция

int main()

{

int m[N];

int min, IndexMin;

int *Duplicate;


Rus();

Randomize();

Title();

puts("\nЗаполнение массива");

Filling(m,N,-30,70);

puts("\nРаспечатка массива\n");

Print (m,N);

puts("\nМинимальное значение массива\n");

min = Min(m,N,&IndexMin);

printf("min = %d его индекс = %d \n", min, IndexMin);

puts("\nСоздание дубликата массива\n");

Duplicate = Copy(m,N);

puts("\nРаспечатка дубликата массива\n");

Print (Duplicate,N);

puts("\nСортировка дубликата методом прямого поиска");

SearchSort(Duplicate,N);

puts("\nРаспечатка дубликата массива после сортировки\n");

Print (Duplicate,N);

puts("\nУдаление дубликата");

free(Duplicate);

return 0;

}


Контрольные вопросы по теме № 5.
  1. Какого типа могут быть индексы массивов?
  2. Что такое размерность массивов?
  3. Для чего нужен «барьер» в сортировке методом прямого включения?
  4. Каков алгоритм поиска минимума или максимума в одномерном массиве?
  5. Как найти индекс элемента в одномерном массиве по его значению?
  6. Алгоритм поиска минимума или максимума в двумерном массиве.
  7. Назначение функций random и randomize?
  8. Сортировка элементов двумерного массива.
  9. Как обратиться к элементу массива по указателю?