- •Конспект лекций по дисциплине "Программирование"(іі часть)
- •123 "Компьютерная инженерия"
- •1 Функции 6
- •1 Функции
- •1.1 Определение, описание, вызов функции
- •Void prn1(int X)
- •Void prn2()
- •Void main()
- •Void main()
- •Void main()
- •1.2 Передача параметров в функции по значению и по указателю
- •Void func(int intg,float fltp)
- •Void main()
- •Void main()
- •1.3 Функции и массивы
- •Int func1(int arr[]) {...}
- •Void main()
- •Void main()
- •Void main()
- •1.4 Функции с умалчиваемыми значениями параметров
- •Void main()
- •Void main()
- •1.5 Функции с переменным числом параметров
- •Void main()
- •Void main()
- •1.6 Передача параметров в функцию main()
- •Int main(int argc,char**argv,char**envp)
- •Int main(int argc,char **argv)
- •1.7 Рекурсивные и подставляемые функции
- •Void main()
- •Void main()
- •1.8 Функции, возвращающие указатель
- •Void main()
- •1.9 Функции и структуры
- •Void f1(stud a)
- •Void f3(stud *p)
- •Void main()
- •1.10 Перегрузка функций
- •Void main()
- •Void main()
- •Int mul(double X,double y)
- •Int sum(int X) {return 2*X;}
- •Void main()
- •1.11 Шаблоны функций
- •Int main()
- •Void func(a);
- •Int main()
- •1.12 Указатели на функции
- •Void main()
- •Int f2(int X){return X*X;};
- •Void main()
- •Void main()
- •2 Работа с файлами
- •2.1 Потоковый ввод-вывод
- •2.2 Открытие и закрытие потока
- •Int fclose(file *имя);
- •Int main()
- •Void perror(const char *str);
- •2.3 Посимвольный ввод-вывод
- •Int fputc(int ch, file *fp);
- •Int fgetc(file *fp);
- •2.4 Построчный ввод-вывод
- •Int fputs(char*string, file *fp);
- •2.5 Форматированный ввод-вывод
- •Int fprintf(file *fp, char *format [,аргумент]…);
- •Int fscanf(file *fp, char *format [,указатель]…);
- •2.6 Форматированные вывод в строку и ввод из строки
- •Int a2; long b2;
- •2.7 Блоковый ввод-вывод
- •Int fwrite(void *ptr, int size, int n, file *fp);
- •Int fread(void *ptr,int size,int n,file *fp);
- •2.8 Произвольный доступ к файлу
- •Int fseek(file *fp, long offset, int from_where);
- •Int main()
- •3 Многофайловая компиляция
- •Void main()
- •Void main()
- •4 Объекты и их атрибуты
- •Void main()
- •5 Ссылки
- •Int &хref; // ошибка!!
- •Int f2_ptr(int *a, int *b) {return *a-*b;}
- •Int f4_ref(const int&a, int &b)
- •Void main()
- •Литература
1.7 Рекурсивные и подставляемые функции
Рекурсивная функция – эта такая функция, которая содержит в себе вызов этой же функции, т.е. самовызывающая функция.
Рекурсивные функции желательно не использовать, если есть очевидное итерационное решение.
Пример. Вычисление факториала неотрицательного целого числа
long fact(int k) // Определение функции
{if(k<0) return 0;
if (k==0} return 1;
return k* fact(k-1);}
Void main()
{int n=5; long F_n=fact(n);
printf (“%d!=%ld”,n,F_n);}
На экран выведется: 5!=120
Функция прерывается при k==0, последнее выражение (1*fact(1-1)) , вычисляет k*(k-1)*(k-2)*(k-3)*(k-4)*1.
Подставляемая функция (inline-функция) – это функция, тело которой подставляется при каждом ее вызове. Такая функция определяется с помощью слова inline.
Inline-функция обрабатывается компилятором как встраиваемая, т.е. вместо каждого вызова этой функции компилятор попытается подставить тело функции. При многократных вызовах код программы может значительно увеличиться, но скорость работы программы повысится за счет отсутствия вызовов этой функции.
Пример.
inline float mod(float x,float y)// Определение функции
{return sgrt(x*x+y*y);}
Void main()
{float f1=4.5, f2=-2.5, f3=-1.5,res1,res2;
res1=mod(f1,f2); // 5.1478
//res1=sgrt(f1*f1+f2*f2);
res2=mod(f1,f3); } // 4.743
//res2=sgrt(f1*f1+f3*f3); }
В ВС31 для inline-функции принято: 1) функция не должна быть рекурсивной; 2) функция не должна содержать операторов for, while, do, switch, goto. В этих случаях компилятор выдает предупреждение, и функция будет трактоваться как обычная.
Пример. Функция вводит символы, пока не введется ’q’. Функция рекурсивная, поэтому не может быть реализована как inline-функция.
inline void str() // Функции будет определена как обычная
{char b; if(cin>>b&&b!='q') str();}
1.8 Функции, возвращающие указатель
Если функция возвращает указатель, то в прототипе и в определении функции в качестве возвращаемого типа записывается тип возвращаемого указателя.
Пример. Функция возвращает адрес элемента массива, значение которого равно нулю. В программе это значение заменяется на 1.
#include <stdio.h>
int *func(int ,int []); //прототип функции
Void main()
{const N=5;
int *b,arr[N]={3,0,7,0,9}, n=0;
if((b=func(N,arr))!=NULL) // вызов функции
{n++; *b=1;
printf("*b=%d b=%p\n",*b,b);}
printf("выполнено замен %d \n",n);}
int *func(int n,int a[]) // Определение функции
{for (int i=0;i<n;i++)
if(a[i]==0) return &a[i];
return NULL;}
На экран выведется:
*b=1 b=8ff2:0FF2
*b=1 b=8ff2:0FF8
выполнено замен =2
1.9 Функции и структуры
В функции можно передавать и из функций можно возвращать структуры и объединения. В этом случае в качестве возвращаемых типов и в сигнатуре функции записываются структурные типы или типы объединений. При передаче структуры в функцию, в функции создается копия этой структуры, и действия, производимые со структурой внутри функции, не влияют на структуру в вызывающей функции. Если в функцию передается указатель на структуру, то функция будет обрабатывать непосредственно элементы той структуры, на которую в функцию передан указатель.
Пример. В функцию передается структура и указатель на структуру
#include <string.h>
#include <stdio.h>
struct STUD{char name[20];int age;};
