мета-данные страницы
  •  

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
c:c_ultimate_guide:functions [2025/10/10 11:24] – создано radi0devc:c_ultimate_guide:functions [2025/11/09 12:07] (текущий) – внешнее изменение A User Not Logged in
Строка 53: Строка 53:
 ===== Параметры ===== ===== Параметры =====
  
-{{fixme}} 
 <code c> <code c>
 +// функция принимает массив символов
 +void print_message(char message[]){
 +  printf("%s\n", message);
 +}
  
 +// прототип выглядил бы так
 +void print_message(char[]);
 +</code>
 +
 +если параметров несколько, они перечисляются через запятую
 +
 +параметры ф-ии можно изменять((При компиляции функции для ее параметров выделяются отдельные участки памяти. Передаеться только значение)) в теле функции
 +
 +параметры могут иметь те же модификаторы, что и обычные переменные
 +
 +==== Передача параметров ====
 +
 +Существует два основных способа передачи параметров в функции: **по значению** и **по указателю**.
 +
 +При **передаче по значению** значением будет копия аргумента, а функция работает с этой копией. Это означает, что изменения, внесенные в параметры внутри функции, не отразятся на аргументах, переданных в функцию.
 +
 +<code c>
 +void modify_value(int value) {
 +  value = 100; // Это изменение не затронет оригинальный аргумент
 +}
 +
 +int main(void) {
 +  int original = 42;
 +  modify_value(original);
 +  printf("Original: %d\n", original); // Вывод: Original: 42
 +  return 0;
 +}
 +</code>
 +
 +При **передаче по указателю** передается адрес переменной, что позволяет функции изменять оригинальный аргумент. Этот подход часто используется для работы с массивами, строками и большими структурами данных, чтобы избежать лишнего расхода памяти при копировании.
 +
 +<code c>
 +void modify_value(int *value) {
 +  *value = 100; // Изменяет оригинальный аргумент
 +}
 +
 +int main(void) {
 +  int original = 42;
 +  modify_value(&original);
 +  printf("Original: %d\n", original); // Вывод: Original: 100
 +  return 0;
 +}
 +</code>
 +
 +Использование указателей также позволяет передавать массивы в функции, так как имя массива автоматически преобразуется в указатель на его первый элемент:
 +
 +<code c>
 +void print_array(int array[], int size) {
 +  for (int i = 0; i < size; i++) {
 +    printf("%d ", array[i]);
 +  }
 +  printf("\n");
 +}
 +
 +int main(void) {
 +  int numbers[] = {1, 2, 3, 4, 5};
 +  print_array(numbers, 5); // Передается адрес первого элемента массива
 +  return 0;
 +}
 +</code>
 +
 +==== Переменное количество параметров ====
 +
 +[[stdarg.h]]
 +
 +===== Возвращаемые значения =====
 +
 +Функция может иметь результат - некоторое значение, которое оно возвращает во внешний код.
 +
 +<code c>
 +void sum1(int x, int y){
 +  printf("%d + %d = %d \n", x, y,  x + y);
 +}
 +
 +// аналогично sum1
 +void sum2(int x, int y){
 +  printf("%d + %d = %d \n", x, y,  x + y);
 +  return;
 +}
 +
 +// возвращает int
 +int sum3(int x, int y){
 +  return x + y;
 +}
 +
 +int result = sum(x, y);
 +</code>
 +
 +В тех функциях, которые не возвращают никакого значения в качестве возвращаемого типа используется void. Если такой ф-ии явно не указать пустой return; - компилятор сам подставит его.
 +
 +При вызове return функция завершаеться, даже если после return есть еще код
 +
 +===== Рекурсия =====
 +
 +функция может вызывать саму себя прямо в теле
 +
 +<code c>
 +int factorial(int n) {
 +  if (n == 1) {
 +    return 1;
 +  }
 +  return n * factorial(n - 1);
 +}
 +</code>
 +
 +===== Типы функций =====
 +
 +Используя определение функции - ее возвращаемый тип и типы параметров мы можем описать тип функций. Для этого применяется оператор typedef:\\
 +''typedef возвращаемый_тип (название)(типы_параметров);''
 +
 +<code c>
 +#include <stdio.h>
 +  
 +typedef void (message)(void);
 + 
 +void hello() { printf("Hello, World \n"); }
 +void goodbye() { printf("Good Bye, World \n"); }
 + 
 +int main(void) {
 +  message* mes1 = &hello; // указатель указывает на функцию hello
 +  message* mes2 = &goodbye; // указатель указывает на функцию goodbye
 +  
 +  mes1(); // Hello, World
 +  mes2(); // Good Bye, World
 +  
 +  return 0;
 +}
 +</code>
 +
 +==== Тип функции-указатель ====
 +
 +Тип функции можно определить как указатель. Например:\\
 +''typedef int (*binary_op)(int, int);''
 +
 +Но стоит понимать, что в этом случае binary_op уже будет представлять указатель: 
 +
 +<code c>
 +#include <stdio.h>
 +  
 +typedef int (*binary_op)(int, int);
 + 
 +int sum(int x, int y) { return x + y; }
 + 
 +int main(void) {
 +  binary_op op1 = ∑ // op1 уже изначально представляет указатель
 +  printf("result = %d \n", op1(10,5)); // result=15 
 +      
 +  return 0;
 +}
 </code> </code>