Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Структура программы на СИ. Понятие о функциях
Программа на языке Си представляет собой набор последовательно описанных функций (процедуры и подпрограммы в языке Си считаются частным случаем функций). Каждая функция - самостоятельная единица программы, предназначенная для решения определенной задачи (или подзадачи). При описании она имеет следующий вид:
Тип_функцни Имя (<список аргументов>) <описания аргументов> { <описания> <операторы> }
Отметим, что список аргументов может быть пустым (однако, скобки после имени функции сохраняются). В этом случае, естественно, нет и их описаний. Имеется одна главная функция (с именем main), с которой начинается выполнение программы. Функции могут обращаться к другим функциям посредством конструкций вызова. Вызов функции используется при вычислении значения выражения. В результате вызова функция возвращает вычисленное значение, которое и является значением вызова функции. Попутно функция может преобразовывать значения своих аргументов. Такой результат вызова функции называется побочным эффектом. В модуле, вызывающем данную функцию, тип возвращаемого ею значения должен быть описан (даже если это неопределенное значение) вместе с описанием переменных. Пример. Пусть необходимо вывести на экран словосочетание «Простая функция без аргументов» 15 раз, используя функции.
Программа 97 #include<stdio.h> main () ( int i,print(); for (i=l;i<=15;i++) print(); { print() /* вызываемая функция без аргументов */ ) printf ("Простая функция без аргументов\n»); }
Аргументы передаются по значению путем копирования в соответствующие (по порядку) параметры, указанные в определении функции. Соответствие аргументов и параметров по количеств) и типу не контролируется в языке Си. Такой контроль может быть выполнен с помощью дополнительных средств отладки. Следует различать формальные аргументы, используемые при описании функций, и фактические, задаваемые при вызове функций. Формальный аргумент - переменная в вызываемой программе, а фактический аргумент - конкретное значение, присвоенное этой переменной вызывающей программой. Фактический аргумент может быть константой, переменной или даже более сложным выражением. Независимо от типа фактического аргумента он вначале вычисляется, а затем его величина (в данном случае некоторое целое число) передается функции (см. программу 97). Можно задавать список аргументов, разделенных запятыми. Пример: программа 98, которая находит числа х, у, z, принадлежащие отрезку [1;20] и удовлетворяющие условию x^2 = у^2 + z^2.
Программа 98 #include<stdio.h> main() ( int х, у, z, zero(); char p, q, ch(); x=2; y=45; z=0; q=’o’; printf("х» "); zero(x); printf("x+y+(x+y)^z= "); zero(x+y+(x+y)^z); printf("q= "); ch(q); } int zero(u) int u; ( printf("%d\n",u); ) char ch(u) char u; { printf("%c\n",u); ) Результат работы программы:
x=2 x+y+(x+y)^z= 94 q=0
Программа 99 #include<stdio.h> main() ( int x,y,z; int zero(); printf("Следующие величины могут быть сторонами прямоугольного треугольника:\n"); for (х=1;х<=20;х++) for (у=1;у<=20;у++) for (z=l;z<=20;z++) if (y*y+z*z==x*x) zero(x,у,z); } int zero(f,g,h) int f,g,h; ( printf ("x= %d, y= %d, 2=%d\n",f,g,h); ) Результат работы программы:
следующие величины могут быть сторонами прямоугольного треугольника х= 5, у= 3, z= 4 х= 5, у= 4, z= 3 x= 10, y= 6, z= 8 x= 10, y=8, z=6 x= 13, y=5, z= 12 x= 13, y= 12, z= 5 x = 15, y= 9, z= 12 x= 15, y= 12, z=9 x=17, y=8, z=15 x= 17, y= 15, z=8 x=20, y=12, z=16 x=20, y= 16, z= 12
Завершает выполнение данной функции и передает управление вызывающей функции оператор return; в главной функции main он же вызывает завершение выполнения всей программы. Оператор return может содержать любое выражение:
return (<выражение>);
Если выражение не пусто, то вычисляется его значение, которое и становится значением данного вызова функции. Достижение «конца» функции (правой закрывающей фигурной скобки) эквивалентно выполнению оператора return без возвращаемого значения (т.е. оператор return в конце функции может быть опущен). Пример. Данная программа вычисляет факториал, если число меньше 8; если вводимое число больше или равно 8, то выводится сообщение «Очень большое число». Программа 100 #include<stdio.h> main() { int n, s(); printf("Введите число "); scant("%d", &n); if (n<8) printf(=%d", s(n)); else printf("Очень большое число"); ) int s(x) /* определение функции с параметром */ int x; { int y,p=l; for (y=x; y>0; y-) p*=y; return(p); /* Возвращает в основную программу значение р */ } Результат работы программы:
1. Введите число 4 р=24 2.Введите число 9 Очень большое число
Пример: предположим, что нужно вычислить x2 (для некоторого неотрицательного целого у) (очевидный способ реализации возведения в целочисленную степень -многократное умножение, но существует более эффективный алгоритм, приведенный ниже).
Программа 101
#include<stdio.h> main() ( int а, Ь, x, у, z; int odd(); printf("\nВведите x, у через пробел: "); scanf("%d %d", &х, &у); а=х; Ь=у; z=l; while (b!=0) if (odd(b)) { z=z*a; b- -;} else (a=a*a; b=b/2;} printf("\n%d", z); } int odd(t) int t; ( return((t%2==0)? 0:1); ) Результат работы программы:
Введитеx, у через пробел: 15 2
Если функции необходимо вернуть несколько значений, можно использовать два различных приема: • применить глобальные переменные (в этом случае кроме изученных ранее характеристик переменных (имени, типа, значения), используется еще одна – класс памяти, см.ниже); • применить переменные типа «указатель» в качестве аргументов функции. При вызове функции информация о переменной может передаваться функции в двух видах. Если мы используем форму обращения
function 1(х);
то происходит передача в функцию значения переменной х. Изменение этого значения в вызывающую функцию не возвращается. Если мы используем форму обращения
function2(&x);
то происходит передача адреса переменной х. Теперь измененное значение переменной х может использоваться в вызывающей функции. Первая форма обращения требует, чтобы определение функции включало в себя формальный аргумент того же типа,что и х:
function l(num) int num;
Вторая форма обращения требует, чтобы определение функции включало в себя формальный аргумент, являющийся указателем на один из объектов соответствующеготипа:
function2(x) int *x;
Обычно пользуются первой формой, если входное значение необходимо функции для некоторых вычислений или действий, и второй формой, если функция должна будет изменять значения переменных в вызывающей программе. Выше вторая форма вызова \же применялась при обращении к ф\нкции scanf(). Когда мы хотим ввести некоторое значение в переменную num, мы пишем scanf(''%d",&num). Данная функция читает значение, затем, используя адрес, который ей дается, помещает это значение в память. Пример: пусть необходимо поменять местами заданные значения переменных х и у.
Программа 102
#include<stdio.h> main() { int х, у; int interchange(); /* описание функции типа int */ x=l; y=3; printf("Имели... x=l y=3\n"); interchange(&x, &y); /* обращение к функции (в данном случае передаются адреса переменных) */ printf("Получили... x=%d y=%d", х, у); } /* вызываемая функция */ int interchange(u, v) int *u, *v; ( int p; p=*\i; *u=*v; *v=p; } Результат работы программы:
Имели х=1 у=3 Получили х=3у=1
В этой программе в вызове функции interchange(&x,&y) вместо передачи значений х и у мы передаем их адреса. Это означает, что формальные аргументы и и v, имеющиеся в спецификации interchanage(u,v), при обращении будут заменены адресами и, следовательно, они должны быть описаны как указатели. Поскольку х и у целого типа, u и v являются указателями на переменные целого типа, и мы вводим следующее описание:
int *u,*v; int p;
Оператор описания используется с целью резервирования памяти. Мы хотим поместить значение переменной х в переменную р, поэтому пишем: р=*u; Вспомните, что значение переменной u - это &х, поэтому переменная и ссылается на х. Это означает, что операция *u дает значение х, которое как раз нам и требуется. Мы не должны писать, например, так:
р = u; /* неправильно */
поскольку при этом происходит запоминание адреса переменнойх, а не ее значения.Аналогично, оператор *u = *v соответствует оператору х = у. Тип функции определяется типом возвращаемого ею значения, а не типом ее аргументов. Если указание типа отсутствует, то по умолчанию считается, что функция имеет тип int. Если значения функции не принадлежат типу int, то необходимо указать ее тип в двух местах. 1. Описать тип функции в ее определении:
char pun(ch,n) /* функция возвращает символ */ int n; char ch;
2. Описать тип функции также в вызывающей программе. Описание функции должно быть проведено наряду с описаниями переменных программы; необходимо только указать скобки (но не аргументы) для идентификации данного объекта как функции.
main() { char rch,pun();
Date: 2015-11-13; view: 402; Нарушение авторских прав |