Тема № 6. Функции в языке С.
Вопросы:
1. Общие сведения.
2. Определение, объявление и вызов функции.
Изложение вопросов.
1. В отличие от других языков программирования высокого уровня в С нет деления на процедуры, подпрограммы и функции (например, Pascal). В программа состоит только из функций.
Функция — самостоятельная единица программы, спроектированная для реализации конкретной задачи. Каждая функция должна иметь имя, которое используется для вызова. Имя функции main(), которая обязательно присутствует в любой С-программе, зарезервировано. В программе на С могут присутствовать несколько функций, причем функция main() необязательно должна быть первой. Но с функции main() всегда начинается выполнение любой С-программы.
При вызове функции ей могут быть переданы данные посредством аргументов. Функция может возвращать значение, которое и есть основной результат выполнения функции; этот результат подставляется на место вызова функции, где бы этот вызов не встретился в программе. Могут быть определены функции, которые не имеют никаких параметров и не возвращают никакого значения. Тем не менее действие таких функций может состоять в изменении внешних переменных или статических переменных или выполнением каких-либо других действий, не связанных с данными.
2. С использование функций в языке С связаны три понятия:
— определение функции;
— объявление функции;
— вызов функции.
Определение функции задает имя функции, типы и число ее формальных параметров, а также объявление и операторы, которые определяют действие функции. Последовательность объявлений объявлений и операторов называется телом функции. В определении функции также может быть задантип значения, возвращаемого функцией (он же и является типом функции), а также класс памяти.
В общем виде определение любой функции выглядит следующим образом:
тип результата имя функции (формальные параметры) заголовок
{
объявления и операторы тело
}
Приведем пример определения функции, проверяющей, является ли заданный символ русской буквой:
int rus(unsigned char ch)
{
if (ch>=’A’ && ch<=ё)
return 1;
else возвращаемые значения
return 0;
}
В С нет требования, чтобы определение функции обязательно предшествовало вызову функции. Определения используемых функций могут следовать за определением функции main() или могут находиться вообще в другом файле.
Однако, для того, чтобы компилятор мог выполнить проверку соответствия типов передаваемых аргументов типам формальных параметров в определении функции, до вызова функции нужно поместить объявление (прототип) функции
Прототип функции имеет такой же формат, что и определение функции, с той лишь разницей, что не имеет тела функции и что заголовок функции заканчивается точкой с запятой. Прототип функции задает имя функции, типы и число формальных параметров, тип возвращаемого значения (тип функции) и класс памяти. Формальные параметры в прототипе могут иметь имена, но эти имена компилятору не нужны. Прототип приведенной выше функции имеет вид:
int rus(unsigned char );
Данный прототип объявляет, что функция rus() возвращает целое значение (int) и имеет один формальный параметр типа unsigned char.
Вызов функции представляет собой либо отдельный оператор вызова, либо выражение, которое является частью другого оператора, как правило, присваивания. При вызове функции указывается ее имя и фактические аргументы, которые подставляются вместо формальных параметров в определении функции.
Приведем полный пример программы, осуществляющей проверку, являются ли вводимые с клавиатуры символы русскими буквами.
#include<stdio.h>
unsigned char word[20];
void main (void);
int rus (unsigned char);
void main (void)
{
unsigned char ch;
int i=0;
while ((ch=getchat())!=(unsigned char)EOF)
{
if(rus(ch))
word[i++]=ch;
else
printf("\n Не русская буква %x \n", ch);
}
printf("%s \n %d \n", word, i);
}
int rus(unsigned char ch)
{
if (ch>=’A’ && ch<=ё)
return 1;
else
return 0;
}
Прототипы библиотечных функций, таких как getchar(), printf(), находятся в файлах включения (stdio.h), поставляемых вместе с системой программирования.
Форма заголовка функции в определении, когда объявление типов формальных параметров находится в круглых скобках вслед за именем функции, соответствует стандарту ANSI языка С. В некоторой литературе старых изданий используется объявление формальных параметров в так называемом “старом стиле” или “стиле K&R”, когда типы формальных параметров объявляются перед телом функции.
Пример:
pr_table(tabl, count)
char *table;
int count;
{
…
}
Старый стиль удобен, когда для пояснения назначения параметров используется комментарий.
3. Формальные параметры — это переменные, которые принимают значения, передаваемые функции во время вызова. Предполагается, что функция имеет столько аргументов, сколько формальных параметров задано в списке.
Если функции не передаются аргументы, то вместо списка формальных параметров необходимо указать ключевое слово void.
Порядок и типы формальных параметров должны быть одни и те же в определении функции и в объявлении. Типы фактических аргументов в вызовах функции должны быть совместимы с типами соответствующих формальных параметров. Формальный параметр может быть любого основного типа, структурой, объявлением, перечислением, указателем или массивом.
Формальные параметры в теле функции используются в качестве ссылок на передаваемые аргументы.
Тело функции — составной оператор, содержащий операторы, определяющие действия функции. Этот оператор может содержать внутри себя объявления переменных, используемых внутри функции. Все переменные, объявленные в теле функции, имеют класс памяти auto, если они не объявлены иначе, и являются локальными. Когда вызывается функция, то для локальных переменных отводится память в стеке и производится их инициализация (если она задана). Далее управление передается первому оператору функции, и начинается процесс выполнения, который продолжается до тех пор, пока не встретится оператор return или конец тела функции. Управление при этом возвращается в точку вызова функции.
Если функция возвращает значение, то должен быть выполнен оператор return, содержащий некоторое значение. Значение возврата не определено, если оператор return не выполнен, или если в операторе return не было указано выражение.
Так как параметры функции передаются по назначению и используются в качестве ссылок на передаваемые аргументы, то при выходе из функции теряются. Поэтому в теле функции нельзя изменять значение аргумента, ибо функция работает с копиями аргументов. Однако, если в качестве аргумента передать указатель переменной, то есть ее адрес, то можно изменять ее значение в теле функции.
Пример:
void change(int *x, int *y)
{
int tmp=*x; используется операция разадресации (косвенной
*x=*y; адресации) для изменения значения переменной
*y=*tmp;
}
Комментарии (10)
RSS свернуть / развернутьcertenok
Книга лично меня заворожила тем, что писал не просто талантливый программист, а именно учитель.
Вот, например, читаю книгу но не могу понять почему получается именно так как написано, переварачиваю страницу и читаю: «скорее всего вы задались вопросом почему получается именно так, так вот...» А далее подробнейшее объяснение.
В общем идеальная книга для начального изучения WinAPI. Всем советую.
alik
certenok
Но все равно лучше перед этим подготовиться, и прочесть какой-нибудь небольшой самоучитель. Ну там, к примеру, руководство для начинающих Г. Шилдта или здесь даже посмотрите на сайте, конспекты понятные, все расписано, возможно и другая информация появится.
miledi
certenok
alik
Я хотел откомпилить свою лабораторную прогу по с++, такая проблема.
С ubuntu работаю не так давно, так чт обуду благодарен за развёрнутые коменты.
Проблема в следующем: долго боролся с проблемой, gcc не хотел компилировать код с++,
код с компилился нормально, а вот с++ ни в какую. После некоторого шаманства и гугла
установил пакет build-essential, код вроде откомпилировался, но при попытке повторно
откомпилировать код, скакануло напряжение и комп ушёл в ребут… После этого при
попытки компиляции кода мне выдаёт примерно следующее:
qaz@pc:~$ gcc ./6.3.cpp
gcc: Internal error: Bus error (program cc1plus)
Please submit a full bug report.
See <file:///usr/share/doc/gcc-4.4/README.Bugs> for instructions.
подскажите как быть?
Проблема в следующем: долго боролся с проблемой, gcc не хотел компилировать код с++,
код с компилился нормально, а вот с++ ни в какую. После некоторого шаманства и гугла
установил пакет build-essential, код вроде откомпилировался, но при попытке повторно
откомпилировать код, скакануло напряжение и комп ушёл в ребут… После этого при
попытки компиляции кода мне выдаёт примерно следующее:
qaz@pc:~$ gcc ./6.3.cpp
gcc: Internal error: Bus error (program cc1plus)
Please submit a full bug report.
See <file:///usr/share/doc/gcc-4.4/README.Bugs> for instructions.
подскажите как быть?
пробовал удалить gcc с его привязками и заново поставить, но как то не помогло
Заранее спасибо!
пробовал удалить gcc с его привязками и заново поставить, но как то не помогло
Заранее спасибо!
miha
gcc ./6.3.cpp
а командой
c++ ./6.3.cpp
alik
miledi
miha
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.