Слайд 1Функции 2
Алтайский государственный университет
Математический факультет
Кафедра информатики
Барнаул 2013
Слайд 2План
Лекция 9
План
Пара заданий для самопроверки
Функции
Подпрограмма как алгоритмическая структура
Функции в языке
Си
Передача параметров
Возврат значений
Примеры функций
Функции: что еще?
Игнорирование возвращаемого значения
Тип функции по
умолчанию
Неопределенное значение функции
Тип и аргументы функции main()
Функции с переменным числом параметров
Функции и структура программы
Программа из одного файла
Программа из многих файлов
Области видимости переменных
Слайд 3Несколько заданий
для самопроверки
Задание «Найди ошибку»
Задание «Вызовы функций»
Слайд 4Несколько заданий для самопроверки
Задание 1а
Найдите ошибку
int g(void){
printf(“Внутри функции
g()”);
int h(){
printf(“Внутри функции h()”);
}
}
Описания функций не могут вкладываться друг в друга
Слайд 5Задание 1б
Найдите ошибку
int sum(int x, int y){
int result;
result = x + y;
}
Несколько заданий для самопроверки
Нет return
result;
Слайд 6Задание 1в
Найдите ошибку
int sum(int n){
if (n == 0)
return 0;
else
n
+ pow(2,n);
}
Несколько заданий для самопроверки
Не хватает return
Слайд 7Задание 1г
Найдите ошибку
void f(float a){
float a;
printf(“%f”,
a);
}
Несколько заданий для самопроверки
Повторное описание уже объявленной переменной
Слайд 8Задание 1д
Найдите ошибку
void product(void){
int a, b, c, result;
printf(“Введите три целых числа: ”);
scanf(“%d%d%d”,&a, &b, &c);
result = a*b*c;
printf(“Результат равен %d”, result);
return result;
}
Несколько заданий для самопроверки
Не нужен return, т.к. функция не имеет возвращаемого значения
Слайд 9Задание 2
Что выведет программа?
#include
int funcA(int x, int *y){
x++;
*y++
return x+*y;
}
int funcB(int *x, int y){
*x--;
y--;
return *x+y;
}
void main() {
int x=1, y=5;
x = funcA(funcB(&x,y),&y);
printf("%d %d\n”, x, y);
}
11 6
Несколько заданий для самопроверки
Слайд 10Примеры функций
Максимум двух чисел
Простое ли число?
Слайд 11Функции
Функции: пример 1
Задача: составить функцию, которая вычисляет наибольшее из двух
значений, и привести пример ее использования
Функция:
формальные параметры
int Max ( int
a, int b )
{
if ( a > b ) return a ;
else return b ;
}
return - вернуть результат функции
тип результата
Слайд 12Функции
Функции: пример 2
Задача: составить функцию, которая определяет, верно ли, что
заданное число – простое.
Особенности:
ответ – логическое значение: «да» (1) или
«нет» (0)
результат функции можно использовать как логическую величину в условиях (if, while)
Алгоритм: считаем число делителей в интервале от 2 до N-1, если оно не равно нулю – число составное.
count = 0;
for (i = 2; i < N; i ++)
if ( N % i == 0) count ++;
if ( count == 0 )
// число N простое}
else // число N составное
Слайд 13Функции
Функция: пример 2
int Prime ( int N )
{
int
count = 0, i;
for (i = 2; i*i
N; i++)
if (N % i == 0) count ++;
return (count == 0);
}
if (count == 0) return 1;
else return 0;
Слайд 14Функции
Функции: пример 2
#include
main()
{
int N;
printf ( "Введите целое
число\n" );
scanf ( "%d", &N );
if ( Prime(
N ) )
printf ("%d - простое число", N);
else printf ("%d - составное число", N);
}
int Prime ( int N )
{
...
}
функция
Prime( N )
Слайд 15Функции
Упражнения
1. Описать функцию, которая определяет сумму всех чисел от 1
до N и привести пример ее использования.
Пример:
Введите число:
100
сумма чисел от 1 до 100 = 5050
2. Составить функцию, которая определяет, сколько зерен попросил положить на N-ую клетку изобретатель шахмат (на 1-ую – 1 зерно, на 2-ую – 2 зерна, на 3-ю – 4 зерна, …)
Пример:
Введите номер клетки:
28
На 28-ой клетке 134217728 зерен.
Слайд 16Функции
Упражнения
3. Составить функцию, которая определяет наибольший общий делитель двух натуральных
и привести пример ее использования.
Пример:
Введите два числа:
14 21
НОД(14,21)=7
4. Составить функцию, которая вычисляет функцию синус как сумму ряда (с точностью 0.001)
Пример:
Введите угол в градусах:
45
sin(45) = 0.707
Слайд 17Функции
Упражнения
5. Составить функцию, которая определяет, верно ли, что сумма его
цифр – четное число.
Пример:
Введите число:
136
Сумма цифр четная.
6. Составить функцию, которая определяет, верно ли, что в заданном числе все цифры образуют возрастающую последовательность.
Пример:
Введите число:
258
Верно.
Введите число:
528
Неверно.
Введите число:
245
Сумма цифр нечетная.
Слайд 18Функции: что еще?
Игнорирование возвращаемого значения
Тип функции по умолчанию
Неопределенное значение функции
Тип
и аргументы функции main()
Функции с переменным числом параметров
Слайд 19Функции: что еще?
Функции: что еще?
При вызове функции можно игнорировать возвращаемое
значение, вызывая ее как процедуру
#include
int calc_and_print (int a, int
b) {
int c = a + b;
printf(“%d+%d=%d”, a, b, c);
return c;
}
void main() {
int z;
z=calc_and_print(4,15);
calc_and_print(z,33);
}
Вызов с сохранением значения
Вызов, игнорирующий
возвращаемое значение
Слайд 20Функции: что еще?
Функции: что еще?
Если при описании функции не указан
тип возвращаемого значения, то подразумевается int
#include
calc_and_print (int a, int
b) {
int c = a + b;
printf(“%d+%d=%d”, a, b, c);
return c;
}
void main() {
int z;
z = calc_and_print(4,15) % 7;
}
int calc_and_print (int, int)
Слайд 21Функции: что еще?
Функции: что еще?
Если при описании функции не использован
return для возврата значения, то значение функции не определено
#include
int
calc_and_print (int a, int b) {
int c = a + b;
printf(“%d+%d=%d”, a, b, c);
}
void main() {
int z;
z = calc_and_print(4,15);
printf(“%d”, z);
}
Нет return
В результате будет получен «мусор»
Слайд 22Функции: что еще?
Функции: что еще?
Функция main() может иметь тип int
или void
Возвращаемое значение в main() – код завершения процесса в
ОС
0 – нет ошибок
>0 – код ошибки
#include
void main() {
int z=0xCAFE;
printf(“%d”, z);
}
#include
int main() {
int z=0xCAFE;
scanf(“%d”,&z);
if(z) {
printf(“%d”, z);
return 0;
}
else
return 255;
}
Код ошибки – 255
Слайд 23Функции: что еще?
Функции: что еще?
Функция main() может иметь параметры
int
argc количество параметров командной строки
char *argv[] массив строк – значений параметров
#include
void
main(int argc, char *argv[]) {
for(int i=0; i
}
c:\> my_prog.exe a.txt 10
0: C:\TEMP\my_prog.exe
1: a.txt
2: 10
argv[0] – всегда полный путь к исполняемому файлу
Слайд 24Функции: что еще?
Функции: что еще?
Функции могут иметь переменное количество параметров
#include
int sred_znach(int x,...) {
int i=0, j=0, sum=0;
va_list uk_arg;
va_start(uk_arg,x); /*установка указателя uk_arg на */
/* первый необязательный параметр*/
if (x!=-1) sum=x; /*проверка на пустоту списка */
else return (0);
j++;
while ( (i=va_arg(uk_arg,int))!=-1) /* выборка очередного */
{ /* параметра и проверка*/
sum+=i; /* на конец списка */
j++;
}
va_end(uk_arg); /* закрытие списка параметров*/
return (sum/j);
}
int main() {
int n;
n=sred_znach(2,3,4,-1); /* вызов с четырьмя параметрами*/
printf("n=%d",n);
n=sred_znach(5,6,7,8,9,-1); /* вызов с шестью параметрами */
printf("n=%d",n); return (0);
}
Слайд 25Функции и
структура программы
Программа из одного файла
Программа из многих файлов
Области
видимости переменных
Слайд 26Функции и структура программы
Функции и структура программы
Функции в одном файле
Слайд 27Функции и структура программы
Функции и структура программы
Программа из нескольких файлов
int
mul(int a, int b) {
return a+b;
}
second.c
Слайд 28Функции и структура программы
Области видимости переменных
Переменные доступны только в той
области видимости,
где они описаны (за исключением описанных как static)
vars.c
Глобальная
область
видимости
Переменная локальна, область
видимости – тело функции
Переменная локальна, область
видимости – блок
Переменная yourVariable доступна внутри функции main()
Переменная hisVariable доступна только внутри блока { … }
Слайд 29Рекурсивные функции
Рекурсия: в математике и программировании
Общий вид рекурсии
Задача о ханойских
башнях
Цена рекурсии
Слайд 30Организация курса
Рекурсия в математике
Рекурсия – метод определения множества объектов через
себя, с использованием ранее заданных частных определений.
Факториал n! = n(n
– 1)! при n>0 и n! = 1 при n=0
Числа Фибоначчи: F1 = F2 = 1, Fn = Fn– 1+Fn– 2, при n>2
Слайд 31Рекурсивные функции
Рекурсия в программировании
Рекурсия – вызов функции из нее самой
напрямую или через другие функции
#include
long fact(long n) {
if(
n == 0 ) return 1;
else return n*fact(n-1);
}
void main() {
long N=5;
printf(“%d! = %d\n”, N, fact(N));
}
Функция вычисления факториала
В теле функции вызывается она сама
Слайд 32Рекурсивные функции
Общий вид рекурсии
Если (простейший случай) тогда
Решить напрямую
Иначе
Делать рекурсивный вызов до появления простейшего случая
Слайд 33Рекурсивные функции
Задача о ханойских башнях
В одном буддийском монастыре монахи уже
тысячу лет занимаются перекладыванием колец. Они располагают тремя пирамидами, на
которых надеты кольца разных размеров. В начальном состоянии 64 кольца были надеты на первую пирамиду и упорядочены по размеру. Монахи должны переложить все кольца с первой пирамиды на вторую, выполняя единственное условие — кольцо нельзя положить на кольцо меньшего размера. При перекладывании можно использовать все три пирамиды. Монахи перекладывают одно кольцо за одну секунду. Как только они закончат свою работу, наступит конец света.
Слайд 34Рекурсивные функции
Задача о ханойских башнях
Рекурсивное решение
Итак, нам необходимо перенести n
дисков со стержня (a) на стержень (c).
Если есть функция
перенесения n –1 диска, тогда задача легко разрешима.
Вначале перенесем n –1 диск со стержня (a) на стержень (b)
Применяя рекурсивный вызов той же функции, затем перенесем n-ый диск со стержня (a) на стержень (c)
И, наконец, перенесем n –1 диск со стержня (b) на стержень (c).
Конец света
Слайд 35Рекурсивные функции
Задача о ханойских башнях
Рекурсивное решение
void Step(int n, char a,
char b, char c)
// n - количество колец;
// a, b, c - башни;
{
// т. к. на каждом шаге количество колец
// будет уменьшаться на один,
// это условие будет условием выхода из рекурсии
if (n <= 0) return;
Step(n-1, a, c, b);
printf("диск %d с %c на %c \n", n, a, b);
Step(n-1, c, b, a);
}
Слайд 36Организация курса
Цена рекурсии
Использование рекурсии может сократить размер исходного кода программы
и сделать код более элегантным и понятным. Однако рекурсия имеет
и свои недостатки…
Слайд 37Организация курса
Цена рекурсии
Пример – вычисление чисел Фибоначчи
long F( int n
)
{
if( n
n;
else
return F( n - 1 ) + F( n - 2 );
}
F(3) вычисляется трижды!
Слайд 38Организация курса
Цена рекурсии
При рекурсивном вызове функции запоминается ее состояние, чтобы
после окончания рекурсивного вызова можно было продолжить ее вычисление
Состояние функции
– совокупность значений всех локальных переменных функции
Значения локальных переменных запоминаются в стэке (специальной области памяти)
Стэк имеет ограниченный размер и не позволяет глубокие рекурсии
Слайд 39Организация курса
Рекурсия
Рекурсия всегда(!) может быть заменена итеративным алгоритмом
При использовании итеративного
алгоритма, как правило, необходимо самостоятельно имитировать работу стэка
Слайд 40Вопросы и ответы
Вопросы?
Функции
Примеры функций
Функции: что еще?
Игнорирование возвращаемого значения
Тип функции по
умолчанию
Неопределенное значение функции
Тип и аргументы функции main()
Функции с переменным числом
параметров
Функции и
структура программы
Программа из одного файла
Программа из многих файлов
Области видимости переменных