СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Лекция 10 "Программирование на Си"

Категория: Информатика

Нажмите, чтобы узнать подробности

Просмотр содержимого документа
«Лекция 10 "Программирование на Си"»

Лекция 1 Рекурсивные функции. Указатели. Символьные строки и функции обработки строк.

Лекция 1

Рекурсивные функции.

Указатели.

Символьные строки и функции обработки строк.

Рекурсивные функции  Рекурсивная функция – это функция, в определении которой есть обращение к себе самой.  Пример . Допустим, нужно вычислить n! ( факториал числа n ).  Значение n! можно представить как произведение n на факториал (n-1) :   n! = n*(n-1)!   (n-1)! = (n-1)*(n-2)!   …

Рекурсивные функции

  • Рекурсивная функция – это функция, в определении которой есть обращение к себе самой.

  • Пример . Допустим, нужно вычислить 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) );

/* Рекурсивная функция вычисления 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

Последовательность рекурсивных

обращений при 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 */

Примеры объявления указателей:

  • 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     -------------------    …

Пример расположения переменных в памяти:

Адрес Память

… …

-------------------

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 *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]); */
  • При работе с массивом имя массива рассматривается как указатель на начальный элемент массива.
  • Пример:

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]); */

Использование указателей в качестве параметров функций  Пример 1 /* Функция обмена значений двух переменных */ void swap (float *a, float *b)  /* a,b - указатели на заданные переменные */ { float c;  c = *a; *a =*b; *b = c; }

Использование указателей в качестве параметров функций

  • Пример 1

/* Функция обмена значений двух переменных */

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); }

/* Гл. функция для тестирования ф-ции 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);

/* Пример вызова функции */

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;

Символьные строки и библиотечные функции обработки строк

  • Символьная строка представляет собой последовательность символов, заканчивающуюся нуль-символом (‘\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);
  • Для ввода с клавиатуры строки символов служит библиотечная функция 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 , содержащий прототипы этих функций.
  • В библиотеках 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));
  • Пример вызова этой функции:

char s[81];

gets (s);

puts (ZamenaBukv (s));