Лекция 1
Рекурсивные функции.
Указатели.
Символьные строки и функции обработки строк.
Рекурсивные функции
- Рекурсивная функция – это функция, в определении которой есть обращение к себе самой.
- Пример . Допустим, нужно вычислить n! ( факториал числа n ).
Значение n! можно представить как произведение n на факториал (n-1) :
n! = n*(n-1)!
(n-1)! = (n-1)*(n-2)!
…
/* Рекурсивная функция вычисления n! */
float fact (int n)
{ if (n
{ puts (“Недопустимый аргумент функции fact”);
exit (1); /* завершение выполнения программы */
}
if (n==1 || n==0) return 1;
return n*fact(n-1);
}
Пример вызова этой функции:
int k;
scanf (“%d”, &k);
printf (“%d! = %.0f”, k, fact(k) );
Последовательность рекурсивных
обращений при k=4:
fact(4) 24 (результат)
4 * fact(3) 4 * 6
3 * fact(2) 3 * 2
2 * fact(1) 2 * 1
1 1
Указатели
- Указатель – это переменная, которая ссылается на другую переменную. Значением указателя является адрес переменной, на которую он ссылается.
- Описание переменной типа указатель:
тип * имя;
Примеры объявления указателей:
- int * p1; /* p1 – указатель на цел. переменную */
- float * p2; /* указатель на вещ. переменную */
- char * p3; /* указатель на симв. переменную */
Так же, как и другие переменные, указатели при объявлении можно инициализировать, например:
- int n=0, k=1;
- int * p1 = &n; /* указателю p1 присваивается адрес n */
Пример расположения переменных в памяти:
Адрес Память
… …
-------------------
3100 0 n
-------------------
3102 1 k
-------------------
3104 3100 p1
-------------------
…
Операция разадресации “*”
- Чтобы через указатель обратиться к той переменной, на которую он ссылается, используется операция разадресации “ * ”.
int *p1, k=1;
p1=&k;
(*p1)++; /* значение k увеличивается на 1,
т.к. *p1 - переменная, на которую ссылается указатель p1 */
printf (“%d”, *p1); /* вывод значения 2 */
- При работе с массивом имя массива рассматривается как указатель на начальный элемент массива.
int m[5] = {10,20,30,40,50};
/* m = &m[0],
*m эквивалентно m[0],
*(m+1) эквивалентно m[1],
*(m+2) эквивалентно m[2],
… */
int i;
/* вывод массива m */
for (i=0; i
printf (“%d ”, *(m+i)); /* или printf (“%d ”, m[i]); */
Использование указателей в качестве параметров функций
/* Функция обмена значений двух переменных */
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);
}
0) (*s)+=m[i], (*k)++; } " width="640"
Пример 2
/* Функция вычисления суммы и количества положительных элементов массива */
void SumPos (float m[], int n, float *s, int *k)
/* Вх. параметры:
m – указатель на заданный массив,
n – число элементов массива.
Вых. параметры:
*s – сумма положительных элементов массива,
*k – количество положительных элементов */
{ int i;
for (i=0, *s=0, *k=0; i
if (m[i]0) (*s)+=m[i], (*k)++;
}
/* Пример вызова функции */
float a[20], s;
int k;
…
SumPos (a, 20, &s, &k);
Символьные строки и библиотечные функции обработки строк
- Символьная строка представляет собой последовательность символов, заканчивающуюся нуль-символом (‘\0’ c кодом 0).
- Строковые константы заключаются в кавычки. При компиляции программы они автоматически дополняются нуль-символом.
- Строковые переменные объявляются как массивы символов, например:
char str[81];
char error[] = “Ошибка”; /* массив из 7 символов, включая ‘\0’ */
- При работе со строками можно использовать указатели, например:
char *s = “Привет”;
…
s = error;
- Для ввода с клавиатуры строки символов служит библиотечная функция gets(), а для вывода – функция puts().
- Пример:
char s1[81], s2[81];
char *s3 = “Привет!”;
puts (s3);
puts (“Введите две строки”);
gets (s1);
gets (s2);
- В библиотеках Turbo C, Borland C++ имеется ряд функций обработки строк:
- определения длины строки ( strlen ),
- сравнения строк ( strcmp, strncmp ),
- копирования строк ( strcpy, strncpy ),
- сцепления строк ( strcat, strncat ),
- поиска символа в строке ( strchr, strrchr, strpbrk ),
- поиска подстроки в строке ( strstr ).
- При их использовании в программу необходимо включить заголовочный файл string.h , содержащий прототипы этих функций.
= ‘A’ && *s return str; } " width="640"
Пример 1
/* Функция замены строчных латинских букв на прописные буквы */
char * ZamenaBukv (char *str)
/* Функция возвращает адрес строки str */
{
char *s; /* указатель на текущий символ строки */
for ( s = str; *s != ‘\0’; s++ )
if (*s = ‘A’ && *s
return str;
}
= ‘A’ && str[i] return str; } " width="640"
Пример 2
/* Второй вариант функции замены букв */
char * ZamenaBukv (char *str)
/* Функция возвращает адрес строки str */
{
int i; /* индекс текущего символа строки */
for ( i = 0; str[i] ; i++ )
if (str[i] = ‘A’ && str[i]
return str;
}
- Пример вызова этой функции:
char s[81];
gets (s);
puts (ZamenaBukv (s));