Функции в языке С. Объявление функции. Оператор return. Прототипы функций. Параметры и аргументы функции, страница 2

main()                                                                                                        t

'{

float b; b=5.2;

printf("квадрат числа %f равен %f', b, sqr(b)); }

float sqr(float a) /* Это описание функции */ {

return a*a;

}

Следующие два примера использования функций вызовут сообщения об ошибке при компиляции. В первом примере препятствием для компиляции будет несоответствие возвращаемого значения объявленному типу функции. Языки С и C++ автоматически преобразуют данные к другому типу, но только тогда, когда это возможно. Целый тип не может быть автоматически преобразовываться в указатель на целое.

#include <stdio.h>

/* Пример 34. Неправильный */

int *sqr(int *i)  /* Прототип функции */

main()

{

о    int i;                                                                                                          .

,,    sqr(&x);

}

int *sqr(int *i) /* Объявление функции */

{

100

return *i=(*i)*(*i);

}

#include <stdio.h>

/* Пример 35. Неправильный */

int sqr(int *i)  /* Прототип функции */

main ()

{

int x=10; sqr(&x, 10); /* Несоответсвие количества аргументов */

> int sqr(int *i)                                                                                             

{                                                                                                                                

*i=(*i)*(*i);                                                                                              

}

Обратим внимание на то, что если мы исправим эти программы, то функция будет возвращать квадрат числа i не через значение функции, а через параметр функции.

Если функция не имеет аргументов, то при объявлении прототипа такой функции следует вместо аргументов писать ключевое слово void. В старом стандарте языка С, который должен поддерживаться новыми компиляторами, отсутствие аргументов в скобках не говорило об их отсутствии в данной функции вообще. Чтобы не было недоразумений или путаницы, желательно использовать ключевое слово void, если параметры у функции отсутствуют.

Это должно касаться и функции main(). Ее объявление должно иметь вид void main(void) или main(void).

#include <stdio.h>

/* Пример 36 * /

void line_ (void); /* прототип функции */

main (void)

{

line_();

}

void  line_(void)

{

int i;                                                                        

for(i=0;i<80;i++) printf ("-");

}

Мы уже говорили о стандартных заголовочных файлах (header files). Заголовочные файлы языка С содержат два типа информации: первый - это отдельные определения, которые используются функциями. Второй — это прототипы функций, относящиеся к этому заголовочному файлу. Примерами таких заголовочных файлов являются файлы stdio.h, string.h, conio.h и др.

Параметры и аргументы функции

В языке С есть особенность, связанная с тем, что все аргументы функции передаются по значению. При вызове функции в стеке выделяется место для формальных параметров функции, и в это выделенное место заносится значение фактического параметра, т. е. значение параметра при вызове функции. Далее функция использует и меняет значения в стеке. При выходе из функции измененные значения параметров теряются.

В языке С вызванная функция не может изменить переменные, указанные в качестве фактических параметров в функции при обращении к ней.

Функция  swap(), которая должна менять значения параметров местами, не будет фактически это делать,

void swap(int a, int b)

{

int tmp=a;

a=b; 

b=tmp;

}

Если необходимо, функцию можно приспособить для изменения аргументов. Надо передавать в качестве параметра не значение, а адрес переменной, которую нужно изменять, т. е. передавать указатель на переменную. Такой прием в языке С будет называться передачей параметра по ссылке.