Можно ли определить функцию после main ()?

У меня есть код, который выглядит вот так и работает нормально,

#include <stdio.h>

int main( )
{
int i = 3, j = 4, k, l ;
k = addmult ( i, j ) ;
l = addmult ( i, j ) ;
printf ( "\n%d %d", k, l ) ;
}
int addmult ( int ii, int jj )
{
int kk, ll ;
kk = ii + jj ;
ll = ii * jj ;
return ( kk, ll ) ;
}

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

Ваша функция не возвращает двух значений. Вы должны прочитать о том, что делает оператор запятой. Кроме того, в C, если у вас нет прототипа, есть неявный, который предполагает, что вы возвращаете int. stackoverflow.com/questions/434763/…stackoverflow.com/questions/1737634/c-comma-operator

Retired Ninja 27.10.2018 08:15

Перед использованием необходимо объявить или прототипировать все функции в соответствующих заголовках. Компилятор с -Wstrict-prototypes предупредит вас об отсутствии объявления addmult(). Скомпилируйте код со всеми флагами предупреждений, например, для gcc -Wall -Wpedantic -Wstrict-prototypes -Werror test.c

Achal 27.10.2018 08:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
48
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

can we define a function afterwards without defining function prototype at the top

Вы можете объявить его прото в main. В вашем случае функция принимает int и возвращает int, поэтому прототип по умолчанию (живы ли они в Стандарте?) Работал нормально.

how can a function return two values?

  1. Он может возвращать структуру по значению:

    typedef struct { int first; int second; } int_pair;
    int_pair addmult(int x, int y) {
        return (int_pair){42, 314}; /* enough for the demo, lol (c) */
    }
    

    Или по указателю:

    int_pair *addmult(int x, int y) {
        int_pair *retVal = malloc(sizeof(int_pair));
        return retVal->first = 42, retVal->second = 314, retVal;
    }
    int_pair *multadd(int x, int y) {
        static int_pair retVal{314, 42};
        return &retVal;
    }
    
  2. Он может вернуть свежий массив в куче:

    /* 1. It is user's responsibility to free the returned pointer. */
    int *addmult(int x, int y) {
        int *retVal = malloc(2 * sizeof(int));
        return retVal[0] = 42, retVal[1] = 314, retVal;
    }
    
  3. Наконец, он может возвращать массив, не размещая его в куче:

    /* 1. It is user's responsibility to NEVER free the returned pointer. */
    int *addmult(int x, int y) {
        static int retVal[] = {42, 314};
        return retVal;
    }
    

    В этом случае возвращенный массив может быть повторно использован (переписан) последовательными вызовами, поэтому вы должны использовать его содержимое как можно скорее.

4) Начиная с C99, вы можете возвращать составной литерал: return (int_pair){42, 314};

David Ranieri 27.10.2018 08:27

Это в основном 1. но спасибо, я надеялся, что что-то подобное возможно.

bipll 27.10.2018 08:29

Да, в основном 1), для полноты картины ... :)

David Ranieri 27.10.2018 08:31

"Прототипы по умолчанию" мертвы с C99. На самом деле они никогда не существовали, но функция была бы неявно объявлена ​​(без прототипа) как возвращающая тип int, если бы она встречалась при вызове в C90. Но C99 останавливает это; каждая функция (кроме main()) должна быть определена или объявлена ​​перед использованием. Его по-прежнему необязательно объявлять с прототипом, но настоятельно рекомендуется всегда использовать явный прототип.

Jonathan Leffler 27.10.2018 08:32

@JonathanLeffler Следовательно, OP использует C90 (максимум), поэтому мне было интересно.

bipll 27.10.2018 08:34

@KeineLust Для полноты следует отметить возврат указателя на структуру. :)

bipll 27.10.2018 08:35

Также OP использует по крайней мере C90; прототипов не существовало в C до C90 (для всех практических целей). Итак, написанный код соответствует (более или менее) C90. Он не делает то, что нужно, но это несколько другая проблема.

Jonathan Leffler 27.10.2018 08:36

@JonathanLeffler Значит, код является логически неверным, если его просят указать?

Sahil Silare 30.10.2018 04:01

@bipll: Я не вижу преимуществ return retVal->first = 42, retVal->second = 314, retVal; по сравнению с retVal->first = 42; retVal->second = 314; return retVal; (разнесен на 3 строки для удобочитаемости). Кроме того, лучше не объявлять какие-либо прототипы функций внутри другой функции - это законно. Объявление должно находиться в области видимости файла.

Jonathan Leffler 30.10.2018 04:06

@SahilSilare: Я не уверен, о чем вы спрашиваете. return(kk, ll); не делает ничего полезного в коде вопроса (потому что это оператор запятой, поэтому первый аргумент оценивается на предмет побочных эффектов - а их нет - а затем результат отбрасывается). Следовательно, значение kk игнорируется, поэтому в вычислении нет необходимости, и оптимизирующий компилятор удалит его.

Jonathan Leffler 30.10.2018 04:10

Другие вопросы по теме