Лекция 3 Индуктивные функции. Последовательности чисел в файле. Задача 1. Является ли последовательность постоянной? Не использовать feof()!!! #include int main(void) { FILE *IN; int first, num; IN = fopen("tmp.dat", "r"); if (IN == NULL) { printf("File not opened\n"); return -1; } if (fscanf(IN, "%d", &first) != 1) { printf("File empty\n"); return -1; } while (fscanf(IN, "%d", &num) == 1) { if (num != first) { printf("No\n"); fclose(IN); return 0; } } printf("Yes\n"); fclose(IN); return 0 } Вопрос. Зачем закрыывать файлы? Ответ. 1. В файлах, открытых на запись, не сохранятся изменения. 2. Все открытые файлы заносятся в таблицу открытых файлов в операционной системе, общая для всех процессов (таблица дескрипторов). Размер таблицы ограничен, поэтому ненужные файлы надо закрывать, чтобы таблица не переполнилась. Пример. Найти максимальный размер таблицы дескрипторов (в файлах) #include int main(void) { FILE *IN; int i; for (i = 0; ; ++i) { IN = fopen("tmp.dat", "r"); if (IN == NULL) break; } printf("Files opened: %d\n", i); return 0; } (Стандартный ввод/вывод: stdin, stdout, stderr) Задача 2. Найти значение многочлена, коэффициенты которого находятся в файле "tmp.dat" в порядке возрастания степеней, в точке x, задаваемой с клавиатуры. Пример. В файле - числа: 1 0 -1 1 - это коэффициент при нулевой степени многочлена 0 - при первой -1 - при второй степени y = -x*x + 0 * x +1 #include int main(void) { double res = 0; double a; double x; double xn = 1; /* This is x in degree of current n */ FILE *IN; IN = fopen("tmp.dat", "r"); if (IN == NULL) { printf("File not opened\n"); return -1; } printf("Input x\n"); scanf("%lf", &x); while (fscanf(IN, "%lf", &a) == 1) { res += a * xn; xn *= x; } fclose(IN); printf("Res: %lf\n", res); return 0; } Сомерсет Моэм: "Главное в программе - чтобы она была выполнена" Задача 3. Найти значение многочлена, коэффициенты которого находятся в файле "tmp.dat" в порядке убывания степеней, в точке x, задаваемой с клавиатуры (за одно прочтение файла, нельзя пользоваться дополнительной памятью) Пример. В файле - числа: 1 0 -1 1 - это коэффициент при второй степени многочлена 0 - при первой -1 - при нулевой степени y = x*x + 0 * x - 1 y = an * x^n + a(n-1) * x^(n-1) + ... + a1 * x^1 + a0 * x^0 Схема Горнера: y = ((...(((an)*x + a(n-1))*x + a(n-2))*x + ...)*x+a1)*x+a0 #include int main(void) { double res = 0; double a; double x; FILE *IN; IN = fopen("tmp.dat", "r"); if (IN == NULL) { printf("File not opened\n"); return -1; } printf("Input x\n"); scanf("%lf", &x); while (fscanf(IN, "%lf", &a) == 1) { res = res*x + a; } fclose(IN); printf("Res: %lf\n", res); return 0; } Задача 4. Считать целое число с клавиатуры и вывести число, с теми же цифрами, что и исходного, но идущими в обратном порядке Пример. 1234 -> 4321 (((4)*10 + 3)*10 + 2)*10 + 1 == 4321 #include int main(void) { int n, last_digit, res = 0; printf("Input integer number\n"); scanf("%d", &n); while(n > 0) { last_digit = n % 10; res = res * 10 + last_digit; n /= 10; } printf("Res: %d\n", res); return 0; } Приведение типов: Например, если все операнды в выражении целые, то результат тоже будет целый. while: last_digit res n 1234 1. 4 4 123 2. 3 43 12 3. 2 432 1 4. 1 4321 0 while(n) - n==0 => условие цикла не выполнено => выход из цикла Задача 5. В последовательности чисел, записанных в файле "tmp.dat", найти количество локальных максимумов (за одно прочтение файла). Определение. Локальный максимум в последовательности чисел - это число, которое не меньше своих соседей. #include int main(void) { int res = 0; int a, b, c; FILE *IN; IN = fopen("tmp.dat", "r"); if (IN == NULL) { printf("File not opened\n"); return -1; } if (fscanf(IN, "%d", &a) != 1) { printf("File empty\n"); return -1; } if (fscanf(IN, "%d", &b) == 1) { if (a >= b) ++ res; while (fscanf(IN, "%d", &c) == 1) { if ((b >= a) && (b >= c)) ++res; a = b; b = c; } if (b >= a) ++res; } else { res = 1; } fclose(IN); printf("Res: %d\n", res); return 0; }