- •Т.Э. Шульга основы программирования на языке с
- •Введение
- •1. Структура программы на языке с
- •Void main()
- •Задание 1. Вывод строки на экран с использованием esp-последовательности
- •2. Переменные. Основные типы данных
- •Задание 2. Описание переменных и преобразование типов
- •3. Ввод – вывод значений переменных
- •Void main()
- •Void main()
- •Задание 3. Форматирование вывода
- •4. Основные операции языка с
- •Void main ()
- •Заданиe 4. Простейшие вычисления
- •5. Конструкции выбора
- •Void main()
- •Void main()
- •Void main()
- •Задание 5. Обработка введенного символа
- •Задание 6. Вычисление значения функции
- •Задание 7. Применение разветвляющихся алгоритмов при решении простейших задач
- •Задание 8. Mультиветвление
- •6. Конструкции цикла и передачи управления
- •Int *t; // неинициализированный указатель на объект типа int,
- •Void main()
- •Int a2[3][2]; // массив из 3 массивов, содержащих по 2 целых элемента.
- •Задание 9. Детерминированные циклы. Простейшие задачи
- •Void main()
- •Задание 10. Итерационные циклы. Простейшие задачи
- •Void main()
- •Int last;
- •Задание 11. Одномерные массивы
- •Void main()
- •Задание 12. Вложенные циклы
- •Void main ()
- •Задание 13. Двумерные массивы
- •Void main ()
- •Задание 14. Посимвольная обработка строк
- •Void main ()
- •Задание 15. Сортировка массива
- •Void main ()
- •7.Функции
- •Int max (int n, int m ) // определение функции нахождения максимума
- •Void main()
- •Int strcmp(const char *str1, const char* str2);
- •Void main()
- •Int fclose (file * stream);
- •Int feof(file *stream);
- •Int fseek ( file* stream, long offset, int origin);
- •Void main ()
- •Задание 16. Определение и вызов функций
- •Задание 17. Рекурсивные функции
- •Задание 18. Использование библиотечных функций string.H
- •Задание 19. Использование библиотечных функций stdio.H
Int max (int n, int m ) // определение функции нахождения максимума
{return n<m?m:n;}
int cube(int); //прототип функции вычисления куба целого числа
void main (void)
{
int i,j,m;
scanf("%d%d", &i, &j);
m=cube(max(i,j));// вложенные вызовы функций – m – куб
// максимального из двух чисел
printf("\nmax=%d",m);
getch();
}
int cube(int x)// Определение функции вычисления
//куба целого числа
{return x*x*x;}
Пример 2. Определить функцию, подсчитывающую количество нулей в троичной записи натурального числа. Найти все пары натуральных чисел в диапазоне [n1,n2], разность между которыми равна 4 и в троичной записи которых равное число нулей. Например, такой парой является пара 6(203) и 10(1013) (в троичной записи по одному нулю).
# include <stdio.h>
# include <conio.h>
int oct (int a)// определение функции
{int sum=0;
while (a>0)
{
if (a%3==0) sum++;
a/=3;
}
return sum;
}
void main()
{
int n1,n2;
printf("Enter n1,n2 ");
scanf("%d%d",&n1,&n2);
for (int i=n1;i<=n2-4;i++)// Проверяем все пары чисел,
//разность между которыми равна 4
if (oct(i)==oct(i+4) && oct(i)>0)// условие, содержащие
//три вызова функции oct
printf("%d%s%d%s", i," ",i+4,"\n");
getch();
}
Особое место в ряду функций занимают так называемые рекурсивные функции, причем разделают прямую и косвенную рекурсию. Функция называется косвенно рекурсивной в том случае, если она содержит обращение к другой функции, содержащий вызов данной функции. Если же в теле функции имеется вызов самой этой функции, то речь идет о прямой рекурсии, а такую функцию называет рекурсивной. Рекурсивные алгоритмы эффективны в тех задачах, где рекурсия используется в определении данных. Если у задачи есть очевидное итерационное решение, то рекурсии следует избегать. Поэтому серьезное изучение рекурсивных методов нужно проводить, вводя динамические структуры данных. Сейчас же рассмотрим только принципиальные возможности С для организации рекурсивных алгоритмов.
Пример 3. Напишите рекурсивную функцию, вычисляющую xn (n–целое, неотрицательное).
float step(float x, int n)
{
if (n==0) return 1;
return x*step(x,n-1); //рекурсивный вызов
}
Void main()
{
float x;
int n;
printf("Enter x,n ");
scanf("%f%d",&x,&n);
printf("\nStepen(%f%s%d%s%f",x,",",n,")= ",step(x,n));
getch();
}
Для n=0 функция возвращает значение 1. В противном случае вызывается та же функция с уменьшенным на 1 значением параметра степени. Таким образом, организуется последовательность вычислений xn=x*xn–1, xn–1=x*xn–2…, x2=x*x1, x1=x*x0, x0=1. Обратите внимание, что последовательность рекурсивных обращений к функции прерывается только при вызове функции step(x,0). Таким образом, важным моментом при составлении любой рекурсивной функции является организация выхода их рекурсии. Каждая задача, решаемая рекурсивным образом, при некоторых наборах данных должна иметь элементарное нерекурсивное решение, например, в нашем примере x0=1.
Больше значение в современном программировании играет не только умение создавать собственные функции, но и грамотное использование уже созданных библиотечных функций. Использование любой стандартной библиотечной функции предполагает ее тщательное предварительное изучение с помощью справочника по языку программирования или справочной системы интегрированной среды программирования. В качестве примера рассмотрим некоторые из библиотечных функций языка С для работы со стоками и файлами.
Функции для работы со строками описаны в заголовочном файле string.h. ([7] стр. 501, [8] стр. 167) Как было отмечено в главе 6 строка в языке С задается как массив символов и строковые функции работают именно с символьными массивами, завершающимися символом ‘\0’, причем вся ответственность за переполнение массивов ложится на плечи программиста. Так как имя массива является указателем–константой на его первый элемент, то параметрами строковых функций чаще всего являются именно указатели–константы на объект типа char (const char *). Рассмотрим описание некоторых функций библиотеки string.h
1.
# include <string.h>
unsigned int strlen(char * str)
Функция strlen() возращает длину строкиstr. Завершающий нулевой символ не учитывается.
Пример использования функции:
char s[255]; gets(s);
printf("Длина строки равна %d",strlen(s));
2.
#include <string.h>