函数'enterChar'的隐式声明[-Wimplicit-function -

时间:2015-09-21 20:07:12

标签: c

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

2)在方法enterChar()中,我得到conflicting types for 'enterChar'错误,并再次不明白它意味着什么以及它为什么会发生。我正在研究Eclipse(Cygwin-GCC),如果它与问题有关。

请问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;
}

4 个答案:

答案 0 :(得分:8)

1)您在使用它们之前尚未声明这些函数,而您使用的C语言具有&#34;隐式函数声明&#34;。这意味着函数被隐式声明为返回int并获取任意类型的任意数量的参数。

2)因为你有一个隐含的函数声明int enterChar(),它与定义char enterChar()冲突。

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

char enterChar(); // and other function declarations

int main(void) {
  ....
}

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

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

答案 1 :(得分:3)

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

这就是它所谓的隐含声明。

然后,您将声明返回enterChar的{​​{1}}。由于编译器在char中调用它时使用了隐式声明,因此它会抱怨冲突类型。

您可以在main中使用函数之前提供函数的显式声明来解决该问题。

main

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

答案 2 :(得分:1)

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

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

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();
  ...
}

是的,这使代码读取&#34;向后&#34;,但它消除了一些令人头疼的问题。

当函数在调用它们的不同源文件中定义时,请确保您具有该函数的声明(使用prototype syntax!)在通话前到位。声明可以出现在文件范围内(在任何函数之外),也可以出现在进行调用的函数中:

// 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();  
  ...
}

在上述情况中,enterNum的声明对整个文件有效,而enterChar的声明仅在main的正文中有效;如果同一源文件中的任何其他函数想要调用enterChar,它还必须在调用之前有一个声明。无论哪种方式,声明必须在调用之前。

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

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

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

标题文件:

/**
 * 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

实施档案:

/**
 * 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
}

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

答案 3 :(得分:0)

你有&#34;转发参考&#34;未申报的职能。他们需要一个函数原型,或者在被调用之前实现。在不知道函数采用或返回的内容的情况下,编译器会假定int类型,但我怀疑某些编译器会标记错误。

你只发布了一个功能,所以我将我的例子限制在那个。

#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;
}