- •Раздел 1. Основы программирования на языке си
- •1) Для решения каких задач может применяться смешанное программирование?
- •2) Назовите основные типы данных на языке Си. Приведите примеры.
- •Целый тип данных
- •Данные плавающего типа
- •4) Условные выражения. Операторы выбора. Приведите примеры.
- •Оператор if
- •Выбор из нескольких возможностей: if...Else if...
- •Оператор switch
- •5) Основные циклические конструкции. Пост- и пред- условия. Приведите примеры.
- •6) Структурное программирование. Определение. Основы концепции.
- •7) Динамическая память. Основные команды. Приведите примеры.
- •Пример: печать n первых простых чисел
- •8) Массивы. Определение. Примеры инициализации одно- и двух- мерных массивов.
- •9) Структура программ на языке Си. Основные типы файлов.
- •Библиотечные заголовочные файлы ansi Си
- •Указатели
- •11) Опишите работу следующих операторов: break, goto, continue, default, return. Оператор goto
- •Оператор return
- •Оператор break
- •Оператор continue
Пример: печать n первых простых чисел
Рассмотрим пример, использующий захват динамической памяти. Требуется ввести целое цисло n и напечатать n первых простых чисел. (Простое число - это число, у которого нет нетривиальных делителей.) Используем следующий алгоритм: последовательно проверяем все нечетные числа, начиная с тройки (двойку рассматриваем отдельно). Делим очередное число на все простые числа, найденные на предыдущих шагах алгоритма и не превосходящие квадратного корня из проверяемого числа. Если оно не делится ни на одно из этих простых чисел, то само является простым; оно печатается и добавляется в массив найденных простых.
Поскольку требуемое количество простых чисел n до начала работы программы неизвестно, невозможно создать массив для их хранения в статической памяти. Выход состоит в том, чтобы захватывать пространство под массив в динамической памяти уже после ввода числа n. Вот полный текст программы:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int n; // Требуемое количество простых чисел
int k; // Текущее количество найденных простых чисел
int *a; // Указатель на массив найденных простых
int p; // Очередное проверяемое число
int r; // Целая часть квадратного корня из p
int i; // Индекс простого делителя
bool prime; // Признак простоты
printf("Введите число простых: ");
scanf("%d", &n);
if (n <= 0) // Некорректное значение =>
return 1; // завершаем работу с кодом ошибки
// Захватываем память под массив простых чисел
a = (int *) malloc(n * sizeof(int));
a[0] = 2; k = 1; // Добавляем двойку в массив
printf("%d ", a[0]); // и печатаем ее
p = 3;
while (k < n) {
// Проверяем число p на простоту
r = (int)( // Целая часть корня
sqrt((double) p) + 0.001
);
i = 0;
prime = true;
while (i < k && a[i] <= r) {
if (p % a[i] == 0) { // p делится на a[i]
prime = false; // => p не простое,
break; // выходим из цикла
}
++i; // К следующему простому делителю
}
if (prime) { // Если нашли простое число,
a[k] = p; // то добавляем его в массив
++k; // Увеличиваем число простых
printf("%d ", p); // Печатаем простое число
if (k % 5 == 0) { // Переход на новую строку
printf("\n"); // после каждых пяти чисел
}
}
p += 2; // К следующему нечетному числу
}
if (k % 5 != 0) {
printf("\n"); // Перевести строку
}
// Освобождаем динамическую память
free(a);
return 0;
}
8) Массивы. Определение. Примеры инициализации одно- и двух- мерных массивов.
Как известно, массив - это конечная совокупность данных одного типа. Можно говорить о массивах целых чисел, массивов символов и.т.д. Мы можем даже определить массив, элементы которого - массивы( массив массивов), определяя, таким образом, многомерные массивы. Любой массив в программе должен быть описан: после имени массива добавляют квадратные скобки [], внутри которых обычно стоит число, показывающее количество элементов массива. Например, запись int x[10]; определяет x как массив из 10 целых чисел. В случае многомерных массивов показывают столько пар скобок , какова размерность массива, а число внутри скобок показывает размер массива по данному измерению. Например, описание двумерного массива выглядит так: int a[2][5];. Такое описание можно трактовать как матрицу из 2 строк и 5 столбцов. Для обращения к некоторому элементу массива указывают его имя и индекс, заключенный в квадратные скобки(для многомерного массива - несколько индексов , заключенные в отдельные квадратные скобки): a[1][3], x[i] a[0][k+2]. Индексы массива в Си всегда начинаются с 0, а не с 1, т.е. описание int x[5]; порождает элементы x[0], x[1], x[2], x[3], x[4], x[5]. Индекс может быть не только целой константой или целой переменной, но и любым выражением целого типа. Переменная с индексами в программе используется наравне с простой переменной (например, в операторе присваивания, в функциях ввода- вывода). Начальные значения массивам в языке Си могут быть присвоены при компиляции только в том случае, если они объявлены с классом памяти extern или static, например:
static int a[6]={5,0,4,-17,49,1};
обеспечивает присвоения a[0]=5; a[1]=0; a[2]=4 ... a[5]=1. Как видите, для начального присвоения значений некоторому массиву надо в описании поместить справа от знака = список инициирующих значений, заключенные в фигурные скобки и разделенные запятыми. Двумерный массив можно инициировать так:
static int matr[2][5] = {{3,4,0,1,2},{6,5,1,4,9}};
Матрица хранится в памяти построчно, т.е. самый правый индекс в наборе индексов массива меняется наиболее быстро. Пусть, например, в заданном массиве из 10 целых чисел надо изменить порядок следования его элементов на обратный без привлечения вспомагательного массива. Соответствующая прорамма приведена на примере:
/*обращение массива*/ #include <stdio.h> main() { int p,i=0; static a[10]={10,11,12,13,14, 15,16,17,18,19}; while(i<10/2) { p=a[i]; a[i]=a[9-i]; a[9-i]=p; i++; } i=0; while(i<10) printf(" %d",a[i++]); }