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

函数的隐式声明';enterChar';[-Wimplicit函数声明],c,C,关于我的C程序,我这里有两个问题: 1) 在main()中,行C=enterChar(),N=enterNum(),左对齐pic(C,N),右对齐pic(C,N)都给了我函数的隐式声明。这到底是什么意思?我已经习惯了Java,它在C语言中的代码是否有点不同 2) 在方法enterChar()中,我得到了“enterChar”的冲突类型,并且再次不理解它的含义和发生的原因。我正在研究Eclipse(Cygwin GCC),如果它与问题有关的话 smb能否详细说明这类错误和警告?我很感激 #incl

关于我的C程序,我这里有两个问题: 1) 在
main()
中,行
C=enterChar()
N=enterNum()
左对齐pic(C,N)
右对齐pic(C,N)都给了我
函数的隐式声明
。这到底是什么意思?我已经习惯了Java,它在C语言中的代码是否有点不同

2) 在方法enterChar()中,我得到了“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;
}
#包括
#包括
int main()
{
printf(“欢迎来到菜单!”);
printf(“菜单是:\n1.输入/更改字符\n2.输入/更改编号\n3.打印三角形类型1(左对齐)\n4.打印三角形类型2(右对齐)\n5.退出”);
printf(“\n”);
printf(“现在从菜单1到5输入一个数字:\n”);
int num=0;
scanf(“%d”和&num);
字符C;
int N=0;
开关(num){
案例1:
C=enterChar();
打破
案例2:
N=enterNum();
打破
案例3:
左对齐pic(C,N);
打破
案例4:
右旋pic(C,N);
打破
违约:
printf(“Smth错了!”);
}
返回0;
}
char enterChar(){
printf(“以字符形式输入您的输入。只允许使用'C'和'C'!\n”);
字符输入=0;
scanf(“%c”,&input);
while(输入!=“c”|输入!=“c”){
如果(输入!=“C”|输入!=“C”){
printf(“您必须输入'C'或'C'。再试一次!”);
}
}
返回输入;
}

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

这就是所谓的隐式声明

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

main
中使用函数之前,可以通过提供函数的显式声明来解决该问题

char enterChar();
char enterChar(); // and other function declarations

int main(void) {
  ....
}

// function definitions
char enterChar() { .... }
在使用之前提供所有函数的显式声明是一种很好的做法。

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

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

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

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

您有对未声明函数的“前向引用”。它们需要一个函数原型,或者在被调用之前实现。在不知道函数接受或返回什么的情况下,编译器假定
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;
}
#包括
#包括
char enterChar();//功能原型
内部主(空)
{
字符C;
//...
C=enterChar();//函数调用
//...
返回0;
}
char enterChar()//函数实现
{
字符输入=0;
//...
返回输入;
}

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

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

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();
  ...
}
是的,这使代码读起来“向后”,但它消除了一些头痛的问题

如果函数是在调用它们的不同源文件中定义的,请确保在调用之前有该函数的声明(使用!)。声明可能出现在文件范围内(任何函数的外部),也可能出现在进行调用的函数内:

// 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
,则它还必须在调用之前有一个声明。无论如何,声明必须在调用之前

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

实施文件:

/**
 * 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”//包括我们自己的标题,以确保我们的声明
//而且定义是一致的。
字符输入字符(无效)
{
//enterChar主体
}
int enterNum(无效)
{
//肠体
}

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

main之前的方法声明?还是main之前的变量声明?@John我特别要说的是在函数使用之前尚未声明的函数声明。谢谢你的回复,@juanchopanza!还有一个问题:在C中,在调用另一个函数之前,我必须声明一个函数吗?@Jo
/**
 * 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
}