Функции в языке Си

Язык Си / Функции в языке Си

 

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

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

Семантика функции определяет способ реализации функции. Обычно представляет собой тело функции.

 

Определение функции

Каждая функция в языке Си должна быть определена, то есть должны быть указаны:

  • тип возвращаемого значения;
  • имя функции;
  • информация о формальных аргументах;
  • тело функции.

 
Определение функции имеет следующий синтаксис:

 
 
 
 
 
 
ТипВозвращаемогоЗначения ИмяФункции(СписокФормальныхАргументов)
{
   ТелоФункции;
  ...
  return(ВозвращаемоеЗначение);
}


Пример: Функция сложения двух вещественных чисел
1
2
3
4
5
6
float function(float x, float z)
{
  float y;
  y=x+z;
  return(y);
}


В указанном примере возвращаемое значение имеет тип float. В качестве возвращаемого значения в вызывающую функцию передается значение переменной y. Формальными аргументами являются значения переменных x и z.

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

Различают системные (в составе систем программирования) и собственные функции.

Системные функции хранятся в стандартных библиотеках, и пользователю не нужно вдаваться в подробности их реализации. Достаточно знать лишь их сигнатуру. Примером системных функций, используемых ранее, являются функции printf() и scanf().

Собственные функции — это функции, написанные пользователем для решения конкретной подзадачи.

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

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

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

 

Вызов функции

Общий вид вызова функции

 
Переменная = ИмяФункции(СписокФактическихАргументов);


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

 

Возврат в вызывающую функцию

По окончании выполнения вызываемой функции осуществляется возврат значения в точку ее вызова. Это значение присваивается переменной, тип которой должен соответствовать типу возвращаемого значения функции. Функция может передать в вызывающую программу только одно значение. Для передачи возвращаемого значения в вызывающую функцию используется оператор return в одной из форм:

 
return(ВозвращаемоеЗначение);

 
return ВозвращаемоеЗначение;


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

Оператор return также завершает выполнение функции и передает управление следующему оператору в вызывающей функции. Оператор return не обязательно должен находиться в конце тела функции.

Функции могут и не возвращать значения, а просто выполнять некоторые вычисления. В этом случае указывается пустой тип возвращаемого значения void, а оператор return может либо отсутствовать, либо не возвращать никакого значения:

 
return;


Пример: Посчитать сумму двух чисел.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
// Функция вычисления суммы двух чисел
int sum(int x, int y) // в функцию передаются два целых числа
{
  int k = x + y;  // вычисляем сумму чисел и сохраняем в k
  return k;       // возвращаем значение k
}
int main()
{
  int a, r;      // описание двух целых переменных
  printf("a= ");
  scanf("%d", &a); // вводим a
  r = sum(a, 5);    // вызов функции: x=a, y=5
  printf("%d + 5 = %d", a, r); // вывод: a + 5 = r
  getchar(); getchar(); // мы использовали scanf(),
  return 0;  // поэтому getchar() вызываем дважжы
}

Результат выполнения
Сумма двух чисел

В языке Си нельзя определять одну функцию внутри другой.

В языке Си нет требования, чтобы семантика функции обязательно предшествовало её вызову. Функции могут определяться как до вызывающей функции, так и после нее. Однако если семантика вызываемой функции описывается ниже ее вызова, необходимо до вызова функции определить прототип этой функции, содержащий:

  • тип возвращаемого значения;
  • имя функции;
  • типы формальных аргументов в порядке их следования.

 
Прототип необходим для того, чтобы компилятор мог осуществить проверку соответствия типов передаваемых фактических аргументов типам формальных аргументов. Имена формальных аргументов в прототипе функции могут отсутствовать.

Если в примере выше тело функции сложения чисел разместить после тела функции main, то код будет выглядеть следующим образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
int sum(intint);   // сигнатура
int main()
{
  int a, r;
  printf("a= ");
  scanf("%d", &a);
  r = sum(a, 5);    // вызов функции: x=a, y=5
  printf("%d + 5 = %d", a, r);
  getchar(); getchar();
  return 0;
}
int sum(int x, int y) // семантика
{
  int k;
  k = x + y;
  return(k);
}


 

Рекурсивные функции

Функция, которая вызывает сама себя, называется рекурсивной функцией.

Рекурсия — вызов функции из самой функции.

Пример рекурсивной функции — функция вычисления факториала.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
int fact(int num)  // вычисление факториала числа num
{
  if (num <= 1)   return 1;  // если число не больше 1, возвращаем 1
  else return num*fact(num - 1);  // рекурсивный вызов для числа на 1 меньше
}
// Главная функция
int main() 
{
  int a, r;
  printf("a= ");
  scanf("%d", &a);
  r = fact(a);    // вызов функции: num=a
  printf("%d! = %d", a, r);
  getchar(); getchar();
  return 0;
}

Результат выполнения
Результат рекурсивного вычисления факториала

Более подробно рекурсивные функции рассмотрены в этой статье.

Математические функции

Математические функции хранятся в стандартной библиотеке math.h. Аргументы большинства математических функций имеют тип double. Возвращаемое значение также имеет тип double.
Углы в тригонометрических функциях задаются в радианах.

Основные математические функции стандартной библиотеки.

Функция Описание
int abs(int x) Модуль целого числа x
double acos(double x) Арккосинус x
double asin(double x) Арксинус x
double atan(double x) Арктангенс x
double cos(double x) Косинус x
double cosh(double x) Косинус гиперболический x
double exp(double x) Экспонента x
double fabs(double x) Модуль вещественного числа
double fmod(double x, double y) Остаток от деления x/y
double log(double x) Натуральный логарифм x
double log10(double x) Десятичный логарифм x
double pow(double x, double y) x в степени y
double sin(double x) Синус x
double sinh(double x) Синус гиперболический x
double sqrt(double x) Квадратный корень x
double tan(double x) Тангенс x
double tanh(double x) Тангенс гиперболический x

Особенности использования функций в языке C++ рассмотрены в этой статье.


Назад: Язык Си

Комментариев к записи: 99

  • Евгений
    Здравствуйте нужно этот код поместить в функцию помоги пожалуйста
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    printf("Birthday: %d\n%d\n%d\n", pStudent->birthDay.day,pStudent->birthDay.month,pStudent->birthDay.year);
        int tmpBirthDay;
        int tmpBirthMonth;
        int tmpBirthyear;
        scanf("%d", &tmpBirthDay);
        scanf("%d", &tmpBirthMonth);
        scanf("%d", &tmpBirthyear);
        if(tmpBirthDay > 0)
        {
            pStudent->birthDay.day = tmpBirthDay;

        }
        if(tmpBirthDay > 0)
        {
            pStudent->birthDay.month = tmpBirthMonth;

        }
        if(tmpBirthDay > 0)
        {
            pStudent->birthDay.year = tmpBirthyear;

        }
       printf("\n");

  • Здраствуйте, помогите, пожалуйста, найти недочёт в программе. Нужно осуществлять ввод переменных, дейсвия над ними и их вывод в разных функциях. С передачей данных через return между вводом(фун-я Input) и действиями(фун-я Actions) нет, но передача между действиями и выводом хромает, не могу понять в чём проблема. Вроде возвращаю значения max, min и вызываю их в функции вывода, но не выходит. Ругается на строку вызова функции Output_MaxMin в функции main, что тут использована неинициализированная локальная меременная max и min, хотя выше их инициализирую. Заранее спасибо за помощь!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    int main()
    {
      srand(time(NULL));
      int z[6][5];
      int s;
      int i, j;
      int max, min;

      input(z);
      output(z);
      actions(z);
      Output_MaxMin(max, min);
      getchar();
      return 0;

    }
    int  input(int z[6][5]) {
      int* a = z;
      int i, j;
      for (i = 0; i < 6; i++) {
        for (j = 0; j < 5; j++) {
          *((a + i) + j) = rand() % (100 - 1 + 1) + 1;

        }
      }
      return *a;
    }
    int output(int* a) {

      int i, j;
      printf("\n");
      for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 5; j++) {
          printf("%4d", *((a + i) + j));
        }
        printf("\n");
      }
    }

    int actions(int z) {
      int summa[6];
      int* a = z;
      int* p = summa;
      int max, min;

      
      int i, j;
      int s;
      printf("Amount: \n");
      for (int i = 0; i < 6; ++i) {
        s = 0;
        for (int j = 0; j < 5; ++j)
          s += *((a + i) + j);
        *(p + i) = s;
        printf("%5d\n", *(p + i));
      }
      max = 0;
      min = 10000;
      for (int i = 0; i < 6; ++i)
      {
        if (*(p + i) > max)
        {
          max = *(p + i);
          
        }
      }
      for (int i = 0; i < 6; ++i)
      {
        if (*(p + i) < min)
        {
          min = *(p + i);
          
        }
      }
      printf("Maximum: %d\n", max);
      printf("Minimum: %d\n", min);
      return max, min;
    }
    int Output_MaxMin(int max, int min) {
      printf("Maximum: %d\n", max);
      printf("Minimum: %d\n", min);
    }

    • Елена Вставская
      Проблема с областями видимости переменных max, min. Те переменные, которые описаны в main, не видны в Actions. Чтобы это исправить, нужно описать переменные глобально, до всех функций. Тогда они станут видны во всем файле.

  • Добрый день. А не подскажете как в рекурсивной функции вычисления чисел Фибоначчи, с указанием количества шагов, организовать вывод значений на экран в самой функции? Вроде должно быть простое решение, но уже всю голову сломал.
    1
    2
    3
    4
    int Phib(int x) {
      if (x<3) return 1;
      return Phib(x-1)+Phib(x-2);
    }

    • Елена Вставская
      Поделитесь решением, когда найдете :) Пока мне видится вывод только из внешней функции.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      #include <iostream>
      using namespace std;
      int Phib(int x) {
        if (x < 3)
        {
          return 1;
        }
        return Phib(x - 1) + Phib(x - 2);
      }
      int main()
      {

        for(int i=1; i<=5; i++)
          cout << Phib(i) << " ";
        cin.get();
        return 0;
      }

      • Ну вот как вариант нашел:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        int fib(int n) {
            if (n > 0) {
                // выводим числа Фибоначчи от 1 до n-1
                fib(n - 1);
                // выводим n-ое число Фибоначчи
                cout << (n <= 2 ? 1 : fib(-(n - 1)) + fib(-(n - 2))) << endl;
            } else {
                n *= -1;
            }
            return n <= 2 ? 1 : fib(-(n - 1)) + fib(-(n - 2));
        }
        Но это на c++ и через потоки. Мне нужно на си и без них )

  • Александра
    Здравствуйте, Елена. У меня возникла проблема в том, что заданная функция, не хочет работать и выдает ошибку, можете подсказать)) Вот условие:Дана строка. Найти в строке индексы первого и последнего символов, таких, что слева и справа от них стоят цифры. Все строки (и только строки) должны быть размещены динамически с помощью оператора new. Разделителем слов в предложении считать только пробел. Все остальные символы считать частью слов предложения. Можно использовать функции для работы со строками. Дано предложение. Сформировать массив слов из таких слов предложения, которые имеют в своем составе латинскую букву 'a', обрамленную цифрами. */
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <stdio.h>
    #include <conio.h>
    #include <windows.h>
    #include <string.h>
    int main ()
    {
      char *s=new char[100];
      int p;
      
      printf("Vvedite predlozhenie\n"); 
      gets (s);
      printf("\nVvedennoe predlozhenie\n");
      puts (s);
      printf("\n");
      pos(s,p);
      delete []s;
     }

    void pos(char *s, int p)
    {
      int i=0,k;
      k= strlen(s);
      if (k>=3)
      {
        while(i+2<k)
        {
          if((s[i]>='0' && s[i]<='9')  && (s[i+2]>='0' && s[i+2]<='9'))  
          {
            p=i+2;
            printf("1:%d",p);
            printf("\n");
            break;
          }
          p=0;
          i++;
        }
        i=k;
        while(i+2>0)
        {
          if((s[i]>='0' && s[i]<='9')  && (s[i-2]>='0' && s[i-2]<='9'))  
          {
            p=i;
            printf("2:%d",p);
             printf("\n");
            break;
          }  
          i--;
        }
       
       if(p==0)
         printf("Net takix simvolov\n");
      } 
    }

    • Елена Вставская
      1.В вызове pos(s,p) чему равно p? Такое впечатление, что хотели вернуть значение из функции. Лучше это сделать через return. Если возвращать через аргумент, то по крайней мере его нужно описать указателем или ссылкой. 2. Почему поиск ведется не от начала строки а от 2 символа? 3. Зачем условие (s[i+2]>='0' && s[i+2]<='9')?

  • Здравствуйте, Елена! Спасибо за статью. У меня простой вопрос. Если тип формального параметра указан в прототипе, то возможно при определении функции в качестве формального параметра указывать только имя переменной без его типа?

  • Здравствуйте, помогите пожалуйста. Я написала код (находит слово в тексте и выводит его кол-во). Код работает, но нужно через функцию. Я не понимаю как его в функцию переделать.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include <stdio.h>
    #include <string.h>
    int main(){
        char poisk[65];
        int kol = 0;
        FILE *text;
        if ((text = fopen("text.txt", "r")) == NULL){
            printf("Текст не найден");
            getchar();
            return 0;
        }
        printf("Введите слово: ");
        scanf("%s", poisk);
        int ch;
        int i = 0;
        int len = strlen(poisk);
        while((ch = fgetc(text)) != EOF){
            if (poisk[i] == ch) {
                ++i;
            } else {
                i = 0;
            }
            if (i == len) {
                ++kol;
                i = 0;
            }
        }
        printf("Количество данного слова в тексте: %d", kol);
        fclose(text);
        getchar();
        return 0;
    }

    • Елена Вставская
      1
      2
      3
      4
      5
      6
      int func(FILE *text)
      {int kol=0;
      printf("Введите слово");
      ...
      return kol;
      }
      А в основной функции - вызов
      1
      kol=func(text);
      И вывести kol

      • Здравствуйте, не могу найти ошибку, всегда выводит 0.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        #include <stdio.h>
        #include <string.h>

        int func(FILE *text, char *poisk){
            int kol = 0, i = 0, ch, len = strlen(poisk);
            while((ch = fgetc(text)) != EOF){
                if (poisk[i] == ch) {
                    ++i;
                } else {
                    i = 0;
                }
                if (i == len) {
                    ++kol;
                    i = 0;
                }
                return kol;
            }
        }
        int main(){
            char poisk[65];
            int kol = 0;
            FILE *text;
            if ((text = fopen("text.txt", "r")) == NULL){
                printf("Текст не найден");
                getchar();
                return 0;
            }
            {
                kol=func(text, poisk);
            }
            printf("Введите слово: ");
            scanf("%s", poisk);
            
            printf("Количество данного слова в тексте: %d", kol);
            fclose(text);
            getchar();
            return 0;
        }
        Заранее спасибо.

        • Елена Вставская
          Сначала нужно ввести искомое слово, а затем вызывать функцию поиска

  • Добрый день. Елена, подскажите как в основном цикле использовать данную функцию?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    unsigned char debounce(unsigned char sample, unsigned char *toggle)
    {
        static unsigned char state, cnt0, cnt1;
        unsigned char delta;
     
        delta = sample ^ state;
        cnt1 = (cnt1 ^ cnt0) &amp; delta;
        cnt0 = ~cnt0 &amp; delta;
     
        *toggle = delta &amp; ~(cnt0 | cnt1);
        state ^= *toggle;
     
        return state;
    }

    • Елена Вставская
      Чему исходно равны state, cnt1, cnt2? Их значения используются, но они не присвоены.

  • Валерия
    Здравствуйте! Помогите пожалуйста! Написать функцию, обеспечивающую решение квадратного уравнения. Параметрами функции должны быть коэффициенты и корни уравнения. Значение, возвращаемое функцией, должно передавать в вызывающую программу информацию о наличии у уравнения корней: 2 – два разных корня, 1 – корни одинаковые, 0 – уравнение не имеет решения. Кроме того, функция должна проверять корректность исходных данных. Если исходные данные неверные, то функция должна возвращать - 1 .

  • Здравствуйте! Рад, что здесь можно задавать вопросы. Моя задача заключается в следующем: Описать функцию вычисления f(x) по формуле: f(x)= x*x при -2 ≤ x < 2; x*x+4x+5 при x ≥ 2; 4 при x < -2. Используя эту функцию для n заданных чисел, вычислить f(x). Среди вычисленных значений найти наибольшее. На вход дается последовательность ненулевых целых чисел, в конце последовательности число 0. Решаю эту задачу я таким образом:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    #include <stdio.h>

    int funct(int n) {

      if ( n < -2 )
        n = 4;
      else if ( n > 2 )
        n = n*n + 4*n + 5;
      else
        n = n*n;

      return n;
    }

    int main() {
      int biggest = 1;
      int n;
      scanf("%d", &n);

      if ( n == 0 )
        return 0;

      while ( n != 0 ) {
        int m = funct(n);

        if ( m > biggest )
          biggest = m;
        
        scanf("%d", &n);
      }

      printf("%d", biggest);

      return 0;
    }
    Вроде бы ошибок быть не должно, но только на одном из тестов на сервере программа ведет себя неправильно, отчего задача остается нерешенной. Проще задачи не придумаешь, но я все-таки не могу понять, где у меня может быть ошибка. Буду очень благодарен за помощь! P.S. Я не знал, как правильно оформить код в комментарии, но в коде страницы был контейнер с классом code. Не уверен, что это сработало.

  • Здравствуйте Елена. Пытаюсь разобрать функции с переменным количеством параметров. Помогите найти где лежат параметры вызова.()
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    #include <stdio.h>


    long summa(int k, ...)
    {
      int *pick = &k;
      long total = 0;
      for ( ; k; k--)
      {
        total += *(++pick);
      }
      return total;
    }

    void main()
    {
      printf("\n summa(2, 6, 4) = %d",summa(2,4,6));
      printf("\n summa(6, 1, 2, 3, 4, 5, 6) = %d",summa(6,1,2,3,4,5,6));
    }
    на выходе получаю :
    summa(2, 6, 4) = 0
    summa(6, 1, 2, 3, 4, 5, 6) = -116778876
    Пробовал добавить printf(" %p - %ld ", pick, *pick) и printf(" %p - %ld ", pick, *(pick+1)) в тело цикла.
    0x7ffded1bcb9c - 2
    0x7ffded1bcba0 - 0
    0x7ffded1bcba4 - 0
    summa(2, 6, 4) = 0
    Как видите, сдвиг есть, но там пусто или какой-то мусор.

    • Елена Вставская
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
      #include <stdio.h>

      long summa(int n, int k, ...) // первый параметр указывает количество параметров далее
      {
        int* pick = &k;
        long total = 0;
        for (; n; n--)
        {
          total += *(pick++);
        }
        return total;
      }

      void main()
      {
        printf("\n summa(2, 6, 4) = %d", summa(3, 2, 4, 6));
        printf("\n summa(6, 1, 2, 3, 4, 5, 6) = %d", summa(6, 1, 2, 3, 4, 5, 6));
      }

      • Спасибо что так быстро ответили!! И извините за спам. Вобщем в результате продолжительного гугления удалось решить проблему, как оказалось это особенности компилятора. Кстати, в книге после еще нескольких примеров тоже всплыло что разные компиляторы по своему адресуют параметры функций и тут в дело вступают макрокоманды: va_start va_arg va_end. Сайт у вас замечательный, и никого не слушайте они просто завидуют. PS. На правах автора выше размещенного кода, прошу убрать нумерацию строк =З

  • Александр
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include <stdio.h>
    #include <math.h>
    double func1 (double x_min,double x_max,double dx,double a,double f , double c ,double b);
    double fanc2 (double a ,double b , double c , int q);
    int main()
    {
    int a;
    printf("выберети функцию 1 или 2 ");
    scanf("%d",&a);

    switch (a) {
    case 1:
    {
    double x_min, x_max, dx, a, f , c , b ;

    do {
    printf("\n Укажите интервал:\t");
    scanf("%lf%lf", &x_min, &x_max);
    }while(x_min>x_max);

    printf("Введите значенaе a");
    scanf("%lf" , &a );

    printf("Введите значение b");
    scanf("%lf" , &b );

    printf("Введите значение c");
    scanf("%lf" , &c );

    do {
    printf("\n Укажите шаг:\t");
    scanf("%lf",&dx);
    }
    while (dx<0);

    for (x_min; x_min<=x_max; x_min+=dx)

    if (x_min<0 && b!=0)
    {
    f=-a*x_min*x_min*x_min-b;
    printf ("----------------------------------------\n");
    printf ("|x=%lf:|\tФункция равна: %f|\n", x_min , f);
    printf ("----------------------------------------\n");

    }

    else{

    if (x_min>0 && b==0)

    {
    f=(x_min-a)/(x_min-c);
    printf ("----------------------------------------\n");
    printf ("|x=%lf:|\tФункция равна: %f|\n", x_min , f);
    printf ("----------------------------------------\n");

    }

    else
    {
    f=(x_min/c)+(c/x_min) ;
    printf ("----------------------------------------\n");
    printf ("|x=%lf:|\tФункция равна: %f|\n", x_min , f);
    printf ("----------------------------------------\n");
    }
    }

    return 0;
    }

    break;
    case 2:

    {
    double a,b,c ;

    printf ("введите а");
    scanf ("%lf",&a);

    printf ("введите b");
    scanf ("%lf",&b);

    c=a*a+b*b;

    printf ("%lf" , c );

    return 0;
    }
    break;
    default:
    printf( "Неизвестное значение" );
    }
    }
    я не понимаю что надо сделать чтобы програма стала функциями

    • Елена Вставская
      Насколько я понимаю, то, что сейчас записано в case 1 и case 2, нужно оформить в виде функций, чтоб там только вызов остался. Прототипы функций указаны сверху (до main). Осталось только тело функций туда перетащить и вызов добавить в case-ax.

  • Ариадна
    Написать функцию с тремя вещественными параметрами, заменяющую значение каждого параметра на среднее арифметическое значений двух других параметров.помогите решить

  • Здравствуйте! На многих ресурсах искал способ подменить такую сущность как var или перегрузку функций для СИ. Мой основной язык С# но в силу поставленной задачи приходится постигать СИ. так вот мне нужно понять как сделать функцию которая будет перегружена разными типами аргументами что то наподобие такого void function(int a); void function(unsigned int a); void function(float a); void function(long a);

  • Здравствуйте! Не могу решить вот такую простую задачу: дано действительные числа a,b. Найти u=max(a,b), v=max(ab, a+b), c= max(u^5+v^5,256). Предыдущие даные задавать самостоятельно. нахождение max оформить в виде подпрограмы. Помогите пожалуйста


  • Здравствуйте! Написала функции ввода и вывода массива, но не знаю, как к ним обратиться в теле программы. Подскажите, пожалуйста, как это сделать.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <locale.h>
    #include <math.h>
    #define k 8
      int readM(double a[])
      {
        int i, n;
        scanf("%d", &n);
        for (i = 0; i < n; i++)
        {
          printf("Введите а[%d]=", i);
          scanf("%lf", &a[i]);
        }
        return n;
      }
      void displayM(double a[], int n)
      {
        int i;
        for (i = 0; i < n; i++)
          printf("%lf\t", a[i]);
        printf("\n");
      }
    int main() 
    {
            ?
      return 0;
    }

    • Елена Вставская
      1
      2
      3
      4
      5
      6
      7
      8
      int main()

        double a[100];
        int n;
        n = readM(a);
        displayM(a, n);
        return 0;
      }

  • Здравствуйте, мой преподаватель просит меня изменить программу вот так: Нужно перенести логику определения в отдельную функцию, которая возвращает true или false.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if ((x11 <= x21 && y11 >= y21) || (x12 >= x22 && y12 <= y22))
    {     
      cout << "true" << endl;
    }
    if ((x11 >= x21 && y11 <= y21) || (x12 <= x22 && y12 >= y22))
    {
      cout << "true" << endl;
    }
    else
    {
      cout << "false" << endl;
    }
    И я не понимаю, что именно мне нужно сделать. Вот сама программа:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <iostream>
    using namespace std;
    int main()
    {
      double x11, y11, x12, y12, x21, y21, x22, y22;
      cin >> x11 >> y11;
      cin >> x12 >> y12;
      cin >> x21 >> y21;
      cin >> x22 >> y22;
      if ((x11 <= x21 && y11 >= y21) || (x12 >= x22 && y12 <= y22))
      {
        cout << "true" << endl;
      }
      if ((x11 >= x21 && y11 <= y21) || (x12 <= x22 && y12 >= y22))
      {
        cout << "true" << endl;
      }
      else
      {
      cout << "false" << endl;
      }
      return 0;
    }
    Прошу, помогите!

    • Елена Вставская
      В простейшем случае - что-то типа
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      #include <iostream>
      using namespace std;
      void func(double x11, double y11, double x12, double y12, double x21, double y21, double x22, double y22)
      {
        if ((x11 <= x21 && y11 >= y21) || (x12 >= x22 && y12 <= y22))
        {
          cout << "true" << endl;
        }
        if ((x11 >= x21 && y11 <= y21) || (x12 <= x22 && y12 >= y22))
        {
          cout << "true" << endl;
        }
        else
        {
          cout << "false" << endl;
        }
      }
      int main()
      {
        double x11, y11, x12, y12, x21, y21, x22, y22;
        cin >> x11 >> y11;
        cin >> x12 >> y12;
        cin >> x21 >> y21;
        cin >> x22 >> y22;
        func(x11, y11, x12, y12, x21, y21, x22, y22);
        return 0;
      }

      • Александра
        Здравствуйте не понимаю почему все числа складываются которые кратны 4Найти и вывести сумму целых положительных чисел из интервала от a до b, кратных 4.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        #include <iostream>
        #include <cstdio>
        using namespace std;
         
        int main()
        {
            int sum, A, B, ch;
            sum = 0;
            cout << "Введите начало отрезка: ";
            cin >> A;
            cout << "Введите конец отрезка: ";
            cin >> B;
            for (ch = A; ch <= B; ch++)
            {
                if (ch%4) continue;
                sum = sum + ch;
            }
            cout << sum;
            return 0;
        }

  • Здравствуйте, Елена! Подскажите пожалуйста! Программа должна принимать строчные, прописные и другие символы, подсчитывать их количество и выводить их на экран. Выводит только строчные символы. Не пойму почему.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include <stdio.h>
    #include <string.h>

    int main (void)
    {
    char ch;
    int lc=0; /* счетчик строчных символов*/
    int uc=0; // счетчик прописных символов
    int oc=0; /* счетчик других символов */
    scanf("%с", &ch);
    while (ch!='#') 
    {
    if ((ch>='а')&&(ch<='z'))
    {
      lc++;
    }
      

    else if ((ch>='A')&&(ch<='Z'))

      uc++;
    }
      
    else
    {
      oc++;  
    }
    scanf("%c", &ch);
    }
    printf("%d строчных, %d прописных, %d других", lc, uc, oc);
    return 0;
    }

  • Очень начинающий - это про меня. Решил попробовать из библиотеки на LCD "выкусить" часть в отдельный модуль для использования с другими подобными библиотеками. Получилось это:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    static uint8_t lcd_rus(uint8_t);

    //Таблица перекодировки в русские символы.
    static const unsigned char PROGMEM convert_HD44780[64] =
    {
      0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,
      0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
      0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,
      0xAC,0xE2,0xAD,0xAE,0xAD,0xAF,0xB0,0xB1,
      0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,
      0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
      0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,
      0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7
    };

    static uint8_t lcd_rus(uint8_t c)
    {

      if  (c > 191)
      {
        c -=192;
        c= pgm_read_byte(&convert_HD44780[c]);
      }

      return c;
    }
    При компиляции предупреждение типа "объявлено, но не используется" Соответственно не работает. Строка static uint8_t lcd_rus(uint8_t); является вызовом функции?


      • Спасибо! По-моему нашел.
        1
        2
        3
        4
        5
        6
        7
        void LCDdata(uint8_t i)    //Отправка символа для отображения на дисплее.
        {
          Busy_flag();  //Проверим сперва флаг занятости, а свободен ли дисплей?
          CPORT|=(1<<RS); //RS=1 посылаем данные в LCD
          Send_byte(lcd_rus(i));
          CPORT&=~(1<<RS);//RS=0
        }

      • Здравствуйте Елена! У меня вопрос, помогите найти ошибку! Не получается сложить элементы массива в функции. Надо чтобы возвращалась сумма! //Напишите функцию, которая принимает одномерный массив целых чисел и возвращает сумму всех чисел.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        void mnozhitel(int mas[], int size) { //цикл заполнение
            int sum = 0;
            for (int i = 0; i < size; i++) {
                cout << (sum + mas[i]) << " ";
            } 
        }  
           
        int main() {
            setlocale(LC_ALL, "rus");
            const int size = 10;
            int mas[size]{ 5,5,8,9,11,6,10,7,14,17 };
            
            mnozhitel(mas, size);
            
            cin.get();    cin.get();
        }

        • Елена Вставская
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          int summa(int mas[], int size) { //цикл заполнение
          int sum = 0;
          for (int i = 0; i < size; i++) {
          sum += mas[i];
          }
          return sum;
          }

          int main() {
          setlocale(LC_ALL, "rus");
          const int size = 10;
          int mas[size]{ 5,5,8,9,11,6,10,7,14,17 };

          int s = summa(mas, size);
          cout << s;

          cin.get(); cin.get();
          }

  • Владислав
    Здравствуйте. Спасибо за Ваш труд. Хотелось бы узнать причину, если можно, ошибки программы, в которой при передаче указателя на динамический двумерный массив в функцию(для расширения массива на одну строку, например) при попытке обращения к любому элементу массива происходит крушения программы:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    int **mass;
      mass = (int**)malloc(kolvert * sizeof(int*));
      for (int i = 0; i < kolvert; i++)
        {
          mass[i] = (int*)malloc(koledge * sizeof(int));
        }
            add(&kolvert,koledge,&mass);
            return 0;
    }
    void add(int *kolvert, int koledge, int ***mass)
    {
      int now = *kolvert;
      *kolvert = *kolvert + 1;
      *mass = (int**)realloc(*mass, *kolvert * sizeof(int*));
      *mass[now] =(int*)malloc(koledge * sizeof(int));
      for (int i = now; i < *kolvert; i++)
        for(int j = 0; j < koledge; j++)
          *mass[i][j] = 0;
      for (int i = 0; i < *kolvert; i++)
        {
          for(int j = 0; j < koledge; j++)
            {
              printf("%3i",*mass[i][j]);
              if(j == koledge-1)
                {
                  printf("\n");
                }
            }
        }
    }

    • Елена Вставская
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      #include <iostream>
      using namespace std;
      void add(int* kolvert, int koledge, int** mass)
      {
        int now = *kolvert;
        *kolvert = *kolvert + 1;
        mass = (int**)realloc(mass, *kolvert * sizeof(int*));
        mass[now] = (int*)malloc(koledge * sizeof(int));
        for (int i = now; i < *kolvert; i++)
          for (int j = 0; j < koledge; j++)
            mass[i][j] = 0;
        for (int i = 0; i < *kolvert; i++)
        {
          for (int j = 0; j < koledge; j++)
          {
            printf("%3d", mass[i][j]);
            if (j == koledge - 1)
            {
              printf("\n");
            }
          }
        }
      }
      int main()
      {
      int** mass;
      int kolvert = 1;
      int koledge = 1;
      mass = (int**)malloc(kolvert * sizeof(int*));
      for (int i = 0; i < kolvert; i++)
      {
        mass[i] = (int*)malloc(koledge * sizeof(int));
        for (int j = 0; j < koledge; j++)
          mass[i][j] = 0;
      }
      add(&kolvert, koledge, mass);
      getchar();
      return 0;
      }

      • Владислав
        По прежнему в функции main невозможно обратиться ни к какому элементу массива, программа рушится.

        • Елена Вставская
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          #include <iostream>
          using namespace std;
          int** add(int* kolvert, int koledge, int** mass)
          {
            int now = *kolvert;
            *kolvert = *kolvert + 1;
            mass = (int**)realloc(mass, *kolvert * sizeof(int*));
            mass[now] = (int*)malloc(koledge * sizeof(int));
            for (int i = now; i < *kolvert; i++)
              for (int j = 0; j < koledge; j++)
                mass[i][j] = 0;
            for (int i = 0; i < *kolvert; i++)
            {
              for (int j = 0; j < koledge; j++)
              {
                printf("%3d", mass[i][j]);
                if (j == koledge - 1)
                {
                  printf("\n");
                }
              }
            }
            return mass;
          }
          int main()
          {
          int** mass;
          int kolvert = 1;
          int koledge = 1;
          mass = (int**)malloc(kolvert * sizeof(int*));
          for (int i = 0; i < kolvert; i++)
          {
            mass[i] = (int*)malloc(koledge * sizeof(int));
            for (int j = 0; j < koledge; j++)
              mass[i][j] = 0;
          }
          mass = add(&kolvert, koledge, mass);
          for (int i = 0; i < kolvert; i++)
          {
            for (int j = 0; j < koledge; j++)
              cout << mass[i][j] << " ";
          }
          getchar();
          return 0;
          }

          • Владислав
            Да, получается что через return функции все работает. Спасибо большое!

  • Первая работа посвящена линейным вычислительным процессам. Такие процессы реализуются с помощью простых программ, в которых все операторы выполняются линейно, один за другим сверху вниз( слева направо). Варианты заданий предлагают решить задачу вычисления и вывода значений функций y = f1(x) и z = f2(y, a, b). корень из (X в Квадрате + 16)поделить на Х=2 x a b 3,5 1,8 3,7 Подскажите как решить

    • Елена Вставская
      А что конкретно не получается? Пока не вижу попыток решения

      • double x = 3.5, a = 1.8, b = 3.7; double y, z; y = sqrt(((x * 2) + 16) / (x + 2)); printf("|y = %8.4lf| \n", y); z = y + sqrt(sin(a + 3 + b)) / (y * 2) + sqrt(sin(a + 3)); printf("| z = %8.4lf| \n", z); мне z выводит - nan (ind) когда компилирую а Y нормально

        • Елена Вставская
          Очень похоже, что синус отрицательный под корнем получился.

  • Александра
    Здравствуйте, Елена, подскажите пожалуйста, стоит задача описать метод в void Start(), у которого нет аргументов и возвращаемого значения. Само сообщение я написала в void, но не понимаю, как его объявить в void Start() без упоминания аргументов =(

    • Елена Вставская
      Не совсем поняла вопрос. Что за метод void Start()? О каком сообщении речь?

  • Здравствуйте, Елена! При определении функции тип возвращаемого значения и тип формальных аргументов в функции обязательно должны быть одинаковыми? Спасибо

  • Владимир
    Здравствуйте, Елена! Вопрос по передаче параметров в функцию. Я передаю в функции (с переменным и с фиксированным количеством параметров) однобайтные константы, но компилятор MinGW_64 кладет их в стек через 8 байт.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    func1( char a, ...)
      {
      char *p = &a;
      for (char i = 0; i < 5; ++i) { // заведомо знаю что передаю 5 параметров
        xx = *p;
        s.append(' '+QString::number(xx)); //формирование строки
        p += 8;  // через 8 байт надо скакать по стеку
        // соответственно p += sizeof( char ) - не работает
        }
      ui->textEdit->append( s ); //вывод строки
      }  // это в Qt Creator
    Мне надо написать универсальный код под разные компиляторы. Вопрос: как в программе мне узнать с каким шагом компилятор кладет параметры в стек? Существует ли макрос, единый для всех C/C++ компиляторов, который показывал бы этот шаг? PS передавать указатель на массив неудобно - код становится не удобочитаемым и затрудняет отладку


    • Елена Вставская
      Размер параметров в стеке зависит от разрядности компилятора

      • Владимир
        у меня MinGW_64 почему-то некорректно компилит va_list, va_start, va_arg, va_end - приложение вылетает с ошибкой, поэтому самый верный способ - работа через указатели. для определения шага пока применяю единственный верный метод:
        1
        2
        3
        4
        uint8_t func_step_stack( uint8_t a, ... ) {
          uint8_t* p = ( &amp;a ) + 16;
          return  *p;
          }
        а в начале инициализации определяю шаг таким образом:
        1
        2
        3
        4
        5
        6
        ...
        uint8_t step =0;  // глобальная переменная
        ...
        step =  func_step_stack( 0, 16, 8, 100, 4, 102, 103, 104, 2, 105, 106, 107, 108, 109, 110, 111, 1 );
        if((step!=1)||(step!=2)||(step!=4)||(step!=8)||(step!=16)) { /*ошибка*/ }
        ...
        в функции указатель p = (&a)+16 ставим на 16 байт после первого параметра. И смотрим на какой параметр попадаем. Ключевые параметры 16,8,4,2,1 - они и показывают шаг. Искренне надеюсь что с шагом в 3 байта (или 5, 6, 7, 11) компилятор не будет складывать однобайтные параметры.
        Таким образом определяем минимальный шаг с которым компилятор складывает параметры функции в стек. В рабочих функциях с переменным числом аргументов делаю p+=step для доступа к каждому последующему параметру. И без разницы какой компилятор будет компилить мою библиотеку. А работать библиотеке надо одинаково на windows, android, STM32 (разных серий).

        • Владимир
          Елена, прошу помощи. Функция func_step_stack прекрасно работает в режиме debug. Но в режиме release даёт неправильные результаты. Я так понимаю что это из-за оптимизатора, который ввиду короткого кода делает эту функцию как inline (чтобы избежать потерь времени на push-call-pop-ret). Дело в том что если я добавляю в тело функции проверочный код (под Windows выводящий в textEdit 64 байта стека), тогда она в release отрабатывает как задумано. Но с другой стороны если функция объявлена с переменным числом аргументов, тогда как компилятору её правильно инлайнить? Вопрос №1 - какими директивами можно заставить компилятор не оптимизировать функцию и её вызов? Другая проблема - я объявляю глобальную переменную с инициализацией uint8_t step = 0; но в режиме release начальное значение почему-то оказалось равно 3. if( step == 0 ) func_step_stack(0, 16, 8, 100 ...); Здесь проверяю если step!=0, то лишний раз не вызываю func_step_stak с потерей процессорного времени на push-call-pop-ret, а в release получаю семантическую ошибку (не те байты обрабатываются в моих функциях, которые передаю переменным числом параметров). Если это оптимизатор, то какой его механизм и почему может так изменить начальную инициализацию? Просто я считал это догмой, а теперь выходит что надо самостоятельно задавать начальные значения переменным? Вопрос №2 в чём может крыться причина неправильной инициализации переменной в release-режиме?

  • Прохожий
    Ранее использовали понятия function declaration и function definition, что по-русски есть объявление (сигнатура или прототип) и определение функции. Функция должна быть ОБЪЯВЛЕНА до ее первого вызова. Определение включает в себя заголовок функции, поэтому может выполнить функции объявления и может выноситься перед первым вызовом этой функции. Вариант:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void f(void); /* объявление */
    void f1(void)
    {
        f(); /* первый вызов f() */
    }

    /* определение */
    void f(void)
    {
      prinf("Hello from f()\n");
    }
    и вариант:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /* определение */
    void f(void)
    {
      prinf("Hello from f()\n");
    }

    void f1(void)
    {
        f(); /* первый вызов f() */
    }
    Верны оба варианта. Просто функцию main во втором варианте Вам придется искать в конце файла, что не очень удобно. Для удобства сопровождения кода проще функции разместить в отдельных файлах, а их прототипы в заголовочном.

  • Хочу скомпилировать такой код:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include<stdio.h>
    #include<math.h>

    int main()
    {
      double a,b,c;
      scanf("%lf %lf %lf", &a, &b, &c);
      double S;
      double p = (a + b + c)/2.0;
      S = sqrt(p * (p-a) * (p-b) * (p-c));
      printf("%.2f\n", S);
      return 0;
    }

    Выдает такую ошибку:
    $ gcc ex01.c -o app /tmp/ccfxQVzx.o: In function `main': ex01.c:(.text+0x9b): undefined reference to `sqrt' collect2: error: ld returned 1 exit status (в чем подвох??????)

    • Елена Вставская
      Не знаю, в Visual Studio всё откомпилировалось.
      Судя по тексту ошибки, компилятор не может найти тело функции sqrt().

    • Прохожий
      gcc ex01.c -o app -lm Автору Вашего дистрибутива большого человеческого Счастья. Математическую библиотеку (объявления функций и сивольные константы которой живут в math.h) не находит компоновщик. Добавляйте -lm для подстраховки. Хотя, корень из константы, например, 4 или 2 Вы бы нашли. Такая реализация. Исходник Ваш - рабочий. Площадь треугольника со сторонами 3,4,5 находит.

  • Вероника
    Здравствуйте, а подскажите пожалуйста как можно поменять два значения в функции и вернуть их обратно?

  • Здраствуйте, у меня есть функция которая принимает два значения, могу ли я передать ей одно значение?

    • Елена Вставская
      Зависит от конкретной реализации. Например, если второй аргументы задан по умолчанию, то можете.

  • Арсений
    Как написать функцию bool Even(int K) логического типа, возвращающую True, если целый параметр K является четным, и False в противном случае.

  • Зелимхан
    Елена, а может ли функция вернуть два значения? Причем разного типа... допустим Int и Char... К примеру:
    1
    2
    3
    intchar funcName(void){
    return(25, "Saratov");
    }
    Понятно что такая семантика не будет работать, но как сделать, что то похожее? если это возможно...

    • Елена Вставская
      Функция, к сожалению, может возвращать только одно значение. Но действительно, возникают ситуации, когда требуется передать несколько значений. В этом случае значения (кроме одного), которые должны быть вычислены функцией, передаются в общем списке аргументов как местодержатели. Причем передача таких аргументов производится по ссылке: prog-cpp.ru/cpp-amp/. Например, функция должна посчитать минимум и максимум:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      #include <iostream>
      using namespace std;
      void minimax(int a, int b, int c, int &min, int &max)
      {
        min = a;
        max = a;
        if (b < min) min = b;
        else max = b;
        if (c < min) min = c;
        if(c > max) max = c;
        return;
      }
      int main()
      {
        int min, max;
        minimax(3, 8, 4, min, max);
        cout << "min = " << min << endl;
        cout << "max = " << max << endl;
        cin.get();
        return 0;
      }

  • Написал код согласно первому примеру темы в компиляторе DevC++:
    1
    2
    3
    4
    5
    6
    7
    8
    void main()
    {}
    float function(float x, float z)
    {
    float y;
    y=x+z;
    return (y);
    }
    Почему-то командная строка упрямо возвращает мне единицу

    • Елена Вставская
      Функцию я вижу, а вот вызова ее - нет.
      1
      2
      3
      4
      void main()
      {
      printf("%f", function(3,2));
      }
      Тогда должно появиться 5.000000


        • Елена Вставская
          Потому что цель этой статьи - показать, как использовать функции, на простом примере.

  • Елена,у меня возник вопрос ,есть ли ограничение на количество формальных/фактических параметров функции? Просто написал программу , вычисляющую интеграл методом Симпсона , где содержится 3 функции(функция ввода данных,функция реализующая заданный алгоритм и функция вывода данных), отмечу , что в функции алгоритма использовал указатель на функцию , мол, препод отдельно требовал вычислить значения y[i] ,чтобы функция вызывалась для этого отдельно.  Это всё я то сделал , но вскоре захотелось чуть намудрить и сделать ,чтобы в функции вывода было не только значение интеграла , но и выводилась таблица , содержащая расчёты x[i],y[i], проблема в том , что добавляю дополнительный формальный параметр и все катится к чертям

    • Елена Вставская
      Я не знаю ограничения на количество передаваемых аргументов. Скорее всего, это будет определяться свободной областью памяти в стеке. Единственное ограничение - если Вы используете аргументы со значениями по умолчанию, то они обязательно должны находиться в конце в списке аргументов. А так - зависит от кода.

  • Валерий
    Елена, добрый день. Мне попался примерно такой программный текст на Си: Основная программа:
    1
    2
    func(0,1);      // Вызов функции func()

    Функция:
    1
    2
    3
    func(bool x=TRUE, bool y=TRUE)   { // удивительно то, что формальным параметрам задают значения

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

    • Елена Вставская
      Здравствуйте, Валерий! Действительно, формальным аргументам функции могут быть присвоены значения по умолчанию. Эти значения будут использоваться в том случае если они не переданы в функцию при вызове. Например, в Вашем случае можно вызвать функцию func(0); // равносильно вызову func(0,1); или func(); // равносильно вызову func(1,1); То есть если в функции есть значения по умолчанию, то значения фактических параметров для них могут не передаваться. Но значения по умолчанию могут иметь только формальные параметры, находящиеся справа в перечне параметров. Иными словами, если для аргумента задано значение по умолчанию, то правее его аргумент без заданного значения по умолчанию стоять не может. Также некорректным будет вызов функции func(,0); // компилироваться не будет Это свойство стало доступно в языке C++, но не было доступно в Си. Подробнее смотрите здесь.

  • Добрый день. При изучении языка Си у меня возник вопрос, каким образом написаны функции стандартных библиотек. К примеру, функции ввода-вывода. При помощи только операторов языка Си, или еще, что-то используется, например другие функции. Тогда как эти функции созданы? Или есть какие-то первичные функции, которые написаны при помощи основных примитивов языка Си (операторы, определение переменных и т.д. без применения каких либо функций)?   Можно ли например увидеть код функции printf(), или getch()?

  • Алексей
    void main() и int main(void) дадут одинаковый результат? В обоих случаях не будет возвращаться результат?

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

  • Алексей
    Добрый день! Елена, подскажите плз, возможен ли вариант double main(), float main(), char main(), string main() и т.д.? И в чём будет практическое отличие, например, int main() и int main(void)? Как это отобразиться на финальном результате программы?

    • Елена Вставская
      Тип возвращаемого значения функции main() - это значение, возвращаемое ей операционной системе. Операционная система анализирует целочисленное значение, поэтому используется int main() {...} Возможен также вариант функции main() не возвращающей значение. При этом ее можно записать как void main() {...} В этом случае последняя команда return 0; в функции main() отсутствует. Насчет аргументов, которые могут передаваться в функцию main() можно посмотреть здесь.

      • Добрый день! Елена нужна ваша в задании надо заполнить массив int последовательными целыми числами. Ввести начальное и конечное значение в интерактивном режиме. Рассчитать сумму четных чисел, опуская нечетное число в цикле просмотра

        • Елена Вставская
          Обращайтесь в личку (через сайт или ВК). И уточните, что не получается. Полностью решать задачу за Вас я не буду.

  • 3D Mountain Bike
    В языке СИ нет требования, чтобы определение функции обязательно предшествовало ее вызову. Определения используемых функций могут следовать за определением функции main, перед ним, или находится в другом файле.

    • Елена Вставская
      Согласна отчасти. В языке Си нет требования, чтобы определение функции было до вызова. Но это требование среды разработки Visual Studio. Для того, чтобы в Visual Studio программа корректно откомпилировалась, до вызова функции должна быть описана хотя бы сигнатура функции. В противном случае при компиляции возникнет ошибка. Если функция находится в другом файле, и этот файл добавляется в проект, то до вызова функции также должна быть описана сигнатура функции. Способом не включать сигнатуру функции в файл является подключение заголовочного файла, внутри которого содержится описание функции, с помощью директивы #include. В этом случае всё содержимое заголовочного файла вставляется в начало файла кода на этапе компиляции.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *