объявления прототипов функций - PullRequest
1 голос
/ 10 апреля 2010

Я практикую функцию в c и сталкиваюсь с программой ....

#include<stdio.h>

int main()
{
    float a=15.5;
    char ch ='C';
    printit(a,ch);
    return 0;
}

printit(a,ch)
{
    printf("%f\n%c",a,ch);
}

Я хочу знать, почему вышеупомянутая программа компилируется и не выдает ошибку, как я понял до сих пор ...

  1. Функция в c должна быть объявлена ​​с конкретным прототипом (но эта программа не содержит прототип)

  2. почему программа выдает вывод 'x' для переменной char?

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

Ответы [ 5 ]

4 голосов
/ 10 апреля 2010

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

Поскольку ваш компилятор не жаловался, вы должныиспользуя компилятор C89 / 90, а не компилятор C99.

Во-вторых, в C89 / 90, когда вы вызываете необъявленную функцию, передавая аргументы типа float и char, как в

printit(a,ch);

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

printit(a, ch)  
{
   ...

Это определение означает, что оба параметра имеют тип int.Это нарушает вышеуказанное требование.Поведение вашего кода не определено.Больше не имеет смысла больше анализировать код или догадываться, почему он печатает что-то так, как печатает.Поведение вашего кода, опять же, не определено.

Правильное определение вашей (необъявленной) функции может выглядеть следующим образом

int printit(double a, int ch)  
{
   ...

В качестве альтернативы, оно может быть определено в стиле K & R как

printit(a, ch)  
float a;
{
   ...

Это, вероятно, заставит ваш код работать правильно.Тем не менее, гораздо лучший подход - предоставить прототип для printit перед его вызовом.Какой прототип вы хотите использовать - void printit(double a, int ch) или void printit(float a, char ch) или что-то еще - вам решать.

2 голосов
/ 10 апреля 2010
  1. В C, если вы не определили функцию перед ее использованием, компилятор выведет неявное определение
  2. Если вы не укажете тип для аргумента функции или его возвращаемого значения, по умолчанию используется значение int
  3. Вы получаете 'x', потому что компилятор использует аргумент ch в качестве целого числа.
0 голосов
/ 10 апреля 2010

Проблема 1: printit определяется после main, решение состоит в том, чтобы поместить прототип функции сверху. Проблема 2: Объявите прототип функции должным образом (вы не написали возвращаемый тип и тип аргумента) Решение:

#include <stdio.h>

void printit(float a, char ch);

int main()
{
    float a=15.5;
    char ch ='C';
    printit(a,ch);
    return 0;
}

void printit(float a, char ch)
{
    printf("%f\n%c",a,ch);
}
0 голосов
/ 10 апреля 2010

Этот код должен почти наверняка читаться:

#include <stdio.h>

void printit(float a, char ch);

int main()
{
    float a=15.5;
    char ch ='C';
    printit(a,ch);
    return 0;
}

void printit(float a, char ch)
{
    printf("%f\n%c\n",a,ch);
}

Если вы хотите написать это аккуратно. Однако для решения вышесказанного:

1) Вы должны включить прототип, да. Однако, поскольку вы компилируете только один модуль (файл .c), компилятор может довольно легко определить, где находится ваша функция и, следовательно, что вы имели в виду. Я получаю это:

test.c:11: warning: conflicting types for ‘printit’
test.c:7: note: previous implicit declaration of ‘printit’ was here

Я настоятельно рекомендую компилировать, используя -Wall -Werror -pedantic, чтобы преобразовывать подобные предупреждения в ошибки и прерывать компиляцию, заставляя вас писать правильный код и уменьшая количество ошибок в дальнейшем.

2) Я получаю 15,5, затем C на новой строке. Я не уверен, откуда идет Z.

3) Вам не нужно указывать типы - однако, если вы этого не сделаете, компилятор не предупредит вас, если типы несовместимы. Один из действительно распространенных случаев - передача данных в сборку. В этом нет особой необходимости, но, вероятно, это является нарушением стандарта C и определенно не является наилучшей практикой.

0 голосов
/ 10 апреля 2010
  1. Когда вы вызываете printit () из main, main нужно знать о printit. Один из способов исправить это - определить printit над main.
  2. printf должен вывести «15,5», затем новую строку, затем «C».
  3. Я запутался в вопросе. Объявление для printit () должно быть void printit (float a, char ch);

    void printit(float a, char ch) {
        printf("%f\n%c",a,ch);

    }

    int main()
    {
        float a=15.5;
        char ch ='C';
        printit(a,ch);
        return 0;
    }

...