- •Базовые типы данных
- •Пример простой программы на языке с
- •Ветвления
- •Последовательная обработка
- •Сумма числовой последовательности
- •Максимум числовой последовательности
- •Последовательная обработка символов
- •Подсчет строк, слов и символов
- •Массивы
- •Статические и динамические массивы
- •Двумерные массивы
- •Структурное программирование сверху вниз
- •Алгоритм сортировки методом обмена (методом пузырька)
- •Подпрограммы
- •Примеры зачетных задач
- •Рекурсия
Алгоритм сортировки методом обмена (методом пузырька)
При просмотре массива упорядочиваются пары соседних элементов: элементы, расположенные не по возрастанию, меняются местами. После просмотра максимальный элемент окажется в конце массива, и второй раз просматриваются уже n - 1 элементов, затем n - 2 и т. д., последний раз просматриваются два элемента.
12 6 14 3 10 // рассматривается n элементов
6 12 14 3 10
6 12 3 14 10
6 12 3 10 14
6 12 3 10 // рассматривается n-1 элементов
6 3 12 10
6 3 10 12
6 3 10 // рассматривается n-2 элементов
3 6 10
3 6 // рассматривается n-3 элементов
/* 2. Сортировка массива x по возрастанию методом обмена */
int k; /* Максимальный индекс просмотра */
. . .
for (k=n-1; k>0; k--)
/* Просмотр элементов x[0], ... , x[k] */
for (i=0; i<k; i++)
/* Сортировка x[i] и x[i+1] */
if (x[i] > x[i+1]) /* Порядок нарушен */
Обмен: x[i] <--> x[i+1];
Реализация алгоритма сортировки методом обмена приведена в программе 7.2.
/* Программа 7.2. Печать входных чисел по возрастанию */
#include <stdio.h>
#define NMAX 100 /* Макс-е количество входных чисел */
void main (void)
{ float x[NMAX]; /* Обрабатываемые числа */
int n; /* Количество чисел */
int i; /* Индекс текущего числа */
int k; /* Максимальный индекс просмотра */
float r; /* Для обмена */
/* 1. Ввод массива x */
printf ("\nВведите количество чисел\n");
scanf ("%d", &n);
printf ("Введите числа\n");
for (i=0; i<n; ++i)
scanf("%f", &x[i]);
/* 2. Сортировка массива x по возрастанию методом обмена */
for (k=n-1; k>0; k--)
for (i=0; i<k; i++)
if (x[i] > x[i+1])
{r=x[i]; x[i]=x[i+1]; x[i+1]=r;}
/* 3. Вывод массива x */
printf("Упорядоченные числа:\n");
for (i=0; i<n; ++i)
printf (" %4.1f", x[i]);
}
Подпрограммы
Задача 15. Вычислить c=n!/(m!*(n-m)!)
Решение А. Использование подпрограммы не обладающей значением.
/* Программа 15а. Вычисление c=n!/(m!*(n-m)!) */ /* с помощью подпрограммы, не обладающей значением */ #include <stdio.h>
void p_fakt (int k, int *f); /* прототип функции */
void main (void)
{ int n, m, c; /* исходные данные и результат */ int f1, f2, f3; /* n!, m!, (n-m)! */
printf("\nВведите два исходных целых числа "); scanf("%d %d", &n, &m);
p_fakt (n, &f1); /* f1 = n! */
p_fakt (m, &f2); /* f2 = m! */
p_fakt (n-m, &f3); /* f3 = (n-m)! */
c = f1 / (f2 * f3); printf ("\n c = %d", c); }
/* Подпрограмма: f = k!; */
void p_fakt (int k, int *f) { int j; /* текущий множитель */
*f=1;
for (j=2; j<=k; j++) *f = *f * j;
return; /* не обязателен */ }
Решение Б. Использование подпрограммы, возвращающей значение (функции).
/* Программа 15б. Вычисление c=n!/(m!*(n-m)!) */ /*с помощью подпрограммы, обладающей значением */ #include <stdio.h>
int fakt (int k); /* прототип функции */
void main(void) { int n, m, c; /* исходные данные и результат */
printf("\nВведите два исходных целых числа "); scanf("%d %d", &n, &m);
c = fakt(n) / (fakt (m) * fakt (n-m));
printf ("\n c = %d", c); }
/* Функция ! */ int fakt (int k)
{ int f; /* k! */
int j; /* текущий множитель */
f=1; for (j=2; j<=k; j++) f = f * j;
return f; /* значение функции */ }
Задача 16. Обмен значений двух переменных
/* Функция обмена значений двух переменных */
#include <stdio.h>
void swap (float *a, float *b)
/* a,b - указатели на заданные переменные */
{ float c;
c = *a; *a =*b; *b = c;
}
/* Гл. функция – драйвер, для тестирования функции swap */
void main()
{ float a=5.5, b=-2.4,
c=10, d=20;
swap (&a, &b);
swap (&c, &d);
printf (“После обмена a=%.1f, b=%.1f”, a, b);
printf (“\n c=%.0f, d=%.0f\n”,c,d);
}
Задача 17. Даны две последовательности вещественных чисел. Найти разность максимальных значений этих последовательностей. Для вычисления максимального значения использовать подпрограмму.
#include <stdio.h>
float fmax ( float m[], int n)
{ float max;
int i;
max=m[0];
for (i=1; i<n; i++)
if (m[i] > max) max=m[i];
return max;
}
int main()
{ float x[25], y[50];
int i, j; i=j=0;
puts(“Vv first posledov”);
while (scanf(“%f”,&x[i++])>0) ;
puts(“Vv second posledov”);
while (scanf(“%f”,&y[j++])>0) ;
printf (“\n Razn = %.2f\n”, fmax(x,i) – fmax(y,j));
return 0;
}
Задача 18. Функция вычисления суммы и количества положительных элементов массива.
void SumPos (float m[ ], int n, float *s, int *k)
/* Вх. параметры:
m – указатель на заданный массив,
n – число элементов массива.
Вых. параметры:
*s – сумма положительных элементов массива,
*k – количество положительных элементов */
{ int i;
for (i=0, *s=0, *k=0; i<n; i++)
if (m[i]>0) { (*s) += m[i]; (*k) ++; }
}
/* Пример вызова функции */
float a[20], s;
int k;
…
SumPos (a, 20, &s, &k);
Задача 19. Определить, все ли элементы последовательности положительные.
/* Вх. параметры:
p – указатель на заданный массив (последовательность),
n – число элементов.
Значение:
f =1 – все элементы положительные,
f=0 – иначе */
int prov_pol (float p[ ], int n)
{ int i, f;
f=1;
for (i=0; i<n; i++)
if (p[i]<0) f=0;
return f;
}
Задача 20. Составить подпрограмму ввода целого числа, перед которым возможны пробелы, символы "новой строки" и знак
(подобным образом вводится число по формату %d функции scanf).
Тест:
Вход:
412
-5 +234<Ctrl-z><Enter>
void vvod_chisla (int * znach)
{ int sim, znak;
*znach = 0; znak = 1;
/* Пропуск пробелов и "новых строк" до числа */
while ((sim=getchar()) == ' ' || sim=='\n');
/* Чтение знака */
if (sim == '-' || sim == '+')
{ if (sim == '-') znak = -1;
sim = getchar();
}
/* Чтение цифр */
while (sim>='0' && sim<='9')
{ *znach = *znach * 10 + sim - '0';
sim = getchar();
}
*znach = *znach * znak;
}