Функции. Вызов функций: вызов по значению и по ссылке. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Функции. Вызов функций: вызов по значению и по ссылке.



Функция – это совокупность объявлений и операторов, обычно предназначенная для решения определенной задачи. Каждая функция должна иметь имя, которое используется для ее объявления, определения и вызова. В любой программе на С должна быть функция с именем main (главная функция), именно с этой функции, в каком бы месте программы она не находилась, начинается выполнение программы. При вызове функции ей при помощи аргументов (формальных параметров) могут быть переданы некоторые значения (фактические параметры), используемые во время выполнения функции. Функция может возвращать некоторое (одно!) значение. Это возвращаемое значение и есть результат выполнения функции, который при выполнении программы подставляется в точку вызова функции, где бы этот вызов ни встретился. Допускается также использовать функции, не имеющие аргументов, и функции, не возвращающие никаких значений. Действие таких функций может состоять, например, в изменении значений некоторых переменных, выводе на печать некоторых текстов и т.п.

С использованием функций в языке С связаны три понятия – определение функции (описание действий, выполняемых функцией), объявление функции (задание формы обращения к функции) и вызов функции.

Вызов функции имеет следующий формат:

               адресное-выражение ([список-выражений])

Если функция не использует параметров, то наличие круглых скобок обязательно, а вместо списка параметров рекомендуется указать слово void. Порядок и типы формальных параметров должны быть одинаковыми в определении функции и во всех ее прототипах. Поскольку синтаксически имя функции является адресом начала тела функции, в качестве обращения к функции может быть использовано адресное-выражение (в том числе и имя функции или разадресация указателя на функцию), имеющее значение адреса функции.

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

Фактический параметр может быть величиной любого основного типа, структурой, объединением, перечислением или указателем на объект любого типа. Массив и функция не могут быть использованы в качестве фактических параметров, но можно использовать указатели на эти объекты.

Выполнение вызова функции происходит следующим образом:

1. Вычисляются выражения в списке выражений и подвергаются обычным арифметическим преобразованиям.

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

2. Происходит присваивание значений фактических параметров соответствующим формальным параметрам.

3. Управление передается на первый оператор функции.

4. Выполнение оператора return в теле функции возвращает управление и возможно, значение в вызывающую функцию. При отсутствии оператора return управление возвращается после выполнения последнего оператора тела функции, а возвращаемое значение не определено.

Адресное выражение, стоящее перед скобками определяет адрес вызываемой функции. Это значит, что функция может быть вызвана через указатель на функцию.

Пример:

               int (*fun)(int x, int *y);

Здесь объявлена переменная fun как указатель на функцию с двумя параметрами: типа int и указателемна int. Сама функция должна возвращать значение типа int. Круглые скобки, содержащие имя указателя fun и признак указателя *, обязательны, иначе запись

               int *fun (intx,int *y);

будет интерпретироваться как объявление функции fun, возвращающей указатель на int.

 Вызов функции возможен только после инициализации значения указателя fun и имеет вид:

               (*fun)(i,&j);

В этом выражении для получения адреса функции, на которую ссылается указатель fun, используется операция разадресации *.

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

Пример:

               double (*fun1)(int x, int y);

               double fun2(int k, int l);

               fun1=fun2;    // инициализация указателя на функцию

               (*fun1)(2,7); // обращение к функции               

В рассмотренном примере указатель на функцию fun1 описан как указатель на функцию с двумя параметрами, возвращающую значение типа double, и также описана функция fun2. В противном случае, т.е. когда указателю на функцию присваивается функция, описанная иначе, чем указатель, произойдет ошибка.


 

Передача массива в функцию.

Передача массива в функцию осуществляется через передачу с помощью указателя адреса перевого элемента массива.

Пример. Считать из файла inputfile.dat, имеющего следующую структуру n

a... a

где n - размер массива

   а - элементы массива

 данные в динамический массив.

Вывести данные из массива в файл output.dat.

#include

#include

int* input(int* n, char* fileName){// ввод из файла

//n - размер массива

//fileName - имя файла

// функция возвращает указатель на массив в динамической памяти

   int* A;

   FILE *fp;

 // открытие файла на чтение

if ((fp = fopen(fileName, "r")) == NULL)

{ printf("Нельзя открыть %s\n", "inputfile.dat");

return NULL;

}

// ввод размера массива

fscanf(fp,"%d",n);

 //выделение памяти под массив

A=(int*)calloc(*n,sizeof(int));

 

// ввод значений

for (int i=0;i<*n;i++){

fscanf(fp,"%d",&A[i]);

}

fclose(fp);

return A;

}

void output(int n, int* A, char* fileName){// вывод массива в файл

//n - размер массива

//А - указатель на массив

//fileName - имя файла

   FILE *fp;

if ((fp = fopen("outputfile.dat", "w")) == NULL)

{ printf("Нельзя открыть %s\n", "outputfile.dat");

return;

}

// вывод значение матрицы

for (int i=0;i< n;i++){

fprintf(fp,"%d ",A[i]);

}

fclose(fp);

}

void main()

{ int *A; //указатель на массив     

   int n; // кол-во элементов             

A=input(&n,"inputfile.dat");

output(n,A,"outputfile.dat");

free(A);// освобождение память для динамического массива

}  


 



Поделиться:


Последнее изменение этой страницы: 2021-08-16; просмотров: 40; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.116.40.53 (0.015 с.)