C语言 函数 'enterChar' 的隐式声明 [-Wimplicit-function-declaration]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32703675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 12:09:17  来源:igfitidea点击:

implicit declaration of function 'enterChar' [-Wimplicit-function-declaration]

c

提问by R Sahu

I have two questions here regarding my C program: 1) In main(), the lines C = enterChar();, N = enterNum();, leftJustifiedPic(C, N);, rightJustifiedPic(C, N);are all giving me implicit declaration of function. What does that even mean? I'm used to Java and is it a little bit different in C with regards to the code?

我在这里有两个关于我的 C 程序的问题:1) 在 中main(),行C = enterChar();, N = enterNum();, leftJustifiedPic(C, N);,rightJustifiedPic(C, N);都给了我implicit declaration of function. 那有什么意思?我已经习惯了 Java,它在 C 中的代码是否有点不同?

2) In method enterChar(), Im getting conflicting types for 'enterChar'error and again do not understand what it means and why it happens. I'm working on Eclipse (Cygwin-GCC) if it has anything to do with the problem.

2) 在方法 enterChar() 中,我收到conflicting types for 'enterChar'错误并且再次不明白它的含义以及它发生的原因。如果它与问题有关,我正在研究 Eclipse (Cygwin-GCC)。

Could smb please detail me on this types of errors and warnings? I appreciate it!

smb 能否详细介绍一下此类错误和警告?我很感激!

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Welcome to the menu!");
    printf("The menu is:\n1. Enter/Change Character\n2. Enter/Change Number\n3. Print Triangle Type 1(Left Justified)\n4. Print Triangle Type 2(Right Justified)\n5. Quit");
    printf("\n");
    printf("Now enter a number from the menu from 1 through 5: \n");
    int num = 0;
    scanf("%d", &num);

    char C;
    int N = 0;
    switch(num){
        case 1:
            C = enterChar();
            break;
        case 2:
            N = enterNum();
            break;
        case 3:
            leftJustifiedPic(C, N);
            break;
        case 4:
            rightJustifiedPic(C, N);
            break;
        default:
            printf("Smth is wrong!");
    }

    return 0;
}

char enterChar(){
   printf("Enter your input as a character. Only 'C' and 'c' are allowed!\n");
   char input = 0 ;
   scanf("%c", &input);
   while(input != 'c' || input != 'C'){

       if(input != 'C' || input != 'c'){
            printf("You have to enter 'C' or 'c'. Try again!");
       }

   }
   return input;
}

回答by juanchopanza

1) You haven't declared the functions before you use them, and the dialect of C that you are using has "implicit function declarations". This means the function are implicitly declared to return intand take any number of parameters of any type.

1) 您在使用函数之前没有声明函数,并且您使用的 C 方言具有“隐式函数声明”。这意味着该函数被隐式声明为返回int并接受任意数量的任意类型的参数。

2) Because you have an implicit function declaration int enterChar(), that clashes with the definition char enterChar().

2) 因为你有一个隐式函数声明int enterChar(),这与定义冲突char enterChar()

The solution is to provide function declarationsbefore main().

解决方案是在之前提供函数声明main()

char enterChar(); // and other function declarations

int main(void) {
  ....
}

// function definitions
char enterChar() { .... }

Depending on your use-case, it may be worth investigating using a more recent version of C, which doesn't have these implicit function declarations (e.g. C99 or C11)

根据您的用例,使用更新版本的 C 可能值得研究,它没有这些隐式函数声明(例如 C99 或 C11)

回答by R Sahu

When the prototype of a function is not declared, the compiler assumes that the return type is an int.

当未声明函数的原型时,编译器假定返回类型是int.

That is what it calls an implicit declaration.

这就是所谓的隐式声明。

and then, you go to declare enterCharthat returns a char. Since the compiler had used an implicit declaration when it was called it in main, it complains about the conflicting types.

然后,你去声明enterChar返回 a char。由于编译器在 中调用它时使用了隐式声明main,因此它会抱怨类型冲突。

You can resolve that problem by providing an explicit declaration of the function before using it in main.

您可以通过在main.

char enterChar();

It's a good practice to provide explicit declarations of all functions before they are used.

在使用之前提供所有函数的显式声明是一个很好的做法。

回答by John Bode

Functions must at least be declaredbefore they are called; if possible, they should be definedbefore they are called.

函数至少必须在调用之前声明;如果可能,应该在调用它们之前定义它们。

When the functions are defined in the same source file from which they are called, move the definitionof the function to precede the caller, like so:

当函数在调用它们的同一个源文件中定义时,将函数的定义移动到调用者之前,如下所示:

char enterChar( void )  // void indicates function takes no arguments
{
    // body of enterChar
}

int enterNum( void )
{
  // body of enterNum
}

int main( void )
{
  ...
  c = enterChar();
  ...
  N = enterNum();
  ...
}

Yes, this makes the code read "backwards", but it eliminates some headaches.

是的,这会使代码“向后”读取,但它消除了一些麻烦。

When functions are defined in a differentsource file from which they are called, make sure you have a declarationof that function (using prototype syntax!) in place before the call. The declaration may appear at file scope (outside of any function), or within the function from which the call is made:

当函数在调用它们的不同源文件中定义时,请确保在调用之前有该函数的声明(使用原型语法!)。声明可能出现在文件范围内(在任何函数之外),或在进行调用的函数内:

// enterChar and enterNum are *defined* in a different source file

int enterNum( void ); // declaration at file scope, valid for remainder
                      // of file

int main( void )
{
  char enterChar( void ); // declaration within a block, only valid for
                          // duration of current block
  ...
  c = enterChar();  
  ...
}

In the case above, the declaration of enterNumis valid over the entire file, while the declaration for enterCharis only valid within the body of main; if any other function in the same source file wants to call enterChar, it must also have a declaration before the call. Either way, the declaration mustprecede the call.

在上面的例子中,of 的声明enterNum在整个文件中有效,而 for 的声明enterChar只在main; 如果同一个源文件中的任何其他函数想要调用enterChar,它也必须在调用之前有一个声明。无论哪种方式,声明都必须在调用之前。

The usual practice for handling declarations of functions defined in a different source file is to create a header filewhich contains the function declarations(not definitions!) and include that header in the file that defines the calling function(s):

处理在不同源文件中定义的函数声明的通常做法是创建一个包含函数声明(不是定义!)的头文件,并将该头文件包含在定义调用函数的文件中:

/**
 * main.c
 */
#include <stdio.h>
#include "utils.h" // contains declarations for enterChar and enterNum

int main( void )
{
   ...
   c = enterChar();
   ...
   N = enterNum();
}

Header file:

头文件:

/**
 * utils.h
 */
#ifndef UTILS_H    // Include guard; prevents header file from being processed
#define UTILS_H    // more than once per translation unit

char enterChar( void ); // void in the argument list indicates the function takes no arguments
int  enterNum( void );  // an empty argument list in a declaration specifies that
                        // the function takes an *unspecified* number of arguments
                        // which is not the same thing, and not necessarily safe

#endif

Implementation file:

实现文件:

/**
 * utils.c
 */
#include <stdio.h>
#include <stdlib.h>

#include "utils.h" // including our own header to make sure our declarations
                   // and definitions line up.

char enterChar( void )
{
  // body of enterChar
}

int enterNum( void )
{
  // body of enterNum
}

You'll notice that utils.calsoincludes utils.h. This is to make sure that our declarations and definitions are in sync.

您会注意到utils.c包括utils.h. 这是为了确保我们的声明和定义是同步的。

回答by Weather Vane

You have "forward references" to undeclared functions. They need a function prototype, or implementing before being called. Without knowing what the function takes or returns, the compiler assumes inttypes, although I suspect some compilers will flag an error anyway.

您对未声明的函数有“前向引用”。他们需要一个函数原型,或者在被调用之前实现。在不知道函数接受或返回什么的情况下,编译器假定int类型,尽管我怀疑有些编译器无论如何都会标记错误。

You only posted one function, so I limit my example to that.

你只发布了一个函数,所以我的例子仅限于此。

#include <stdio.h>
#include <string.h>

char enterChar();           // function prototype

int main(void)
{
    char C;
    //...
    C = enterChar();       // function call
    //...
    return 0;
}

char enterChar()           // function implementation
{
    char input = 0;
    //...
    return input;
}