C 函数原型声明

C 函数原型声明,c,function,prototype,C,Function,Prototype,我正在用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); } 我想知道,为什么上面的程序编译,而不是给出错误,因为我了解到目前为止是 c中的函数必须用特定的原型声明,但此程序不包含原型 为什么程序会给cha

我正在用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);
}
我想知道,为什么上面的程序编译,而不是给出错误,因为我了解到目前为止是

c中的函数必须用特定的原型声明,但此程序不包含原型

为什么程序会给char变量指定输出“x”

c中的函数是否能够接受该值,而无需像函数声明中所做的那样声明类型参数

当您从main调用printit时,main需要了解printit。解决此问题的一种方法是在main上定义printit。 printf应该打印15.5,然后是换行符,然后是C。
我对这个问题感到困惑。printit的声明应为void printitfloat a,char ch; 当您从main调用printit时,main需要了解printit。解决此问题的一种方法是在main上定义printit。 printf应该打印15.5,然后是换行符,然后是C。
我对这个问题感到困惑。printit的声明应为void printitfloat a,char ch;
这段代码几乎应该是:

#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);
}
我强烈建议使用-Wall-Werror-pedantic编译,将类似这样的警告转换为错误并中止编译,从而强制您编写正确的代码,从而减少以后的bug

2我得到15.5分,然后在一条新线路上得到C。我不确定Z是从哪里来的


3您不必指定类型-但是,如果您不指定类型,编译器会在类型不兼容时警告您,您将无法从中获益。一种非常常见的情况是将数据传递给程序集。它不是严格需要的,但它可能违反了标准C,并且肯定不是最佳实践。

这段代码几乎肯定应该是:

#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);
}
我强烈建议使用-Wall-Werror-pedantic编译,将类似这样的警告转换为错误并中止编译,从而强制您编写正确的代码,从而减少以后的bug

2我得到15.5分,然后在一条新线路上得到C。我不确定Z是从哪里来的

3您不必指定类型-但是,如果您不指定类型,编译器会在类型不兼容时警告您,您将无法从中获益。一种非常常见的情况是将数据传递给程序集。它不是严格需要的,但它可能违反了标准C,并且肯定不是最佳实践

在C语言中,如果在使用函数之前没有定义它,编译器会推断出一个隐式定义 如果没有为函数参数或其返回值指定类型,则默认为int 之所以得到“x”,是因为编译器将ch参数用作整数。 在C语言中,如果在使用函数之前没有定义它,编译器会推断出一个隐式定义 如果没有为函数参数或其返回值指定类型,则默认为int 之所以得到“x”,是因为编译器将ch参数用作整数。 问题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);
}
问题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);
}

首先,在C语言中,没有要求在调用函数之前为其提供原型。在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 printitdouble a、int ch或void printitfloat a、char ch或其他-由您决定。

首先,在调用函数之前,C语言中不需要为函数提供原型。在C99版本的语言中,需要在调用函数之前声明函数 led,但仍然没有提供原型的要求

因为您的编译器没有抱怨,所以您必须使用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 printitdouble a、int ch或void printitfloat a、char ch或其他—由您决定。

闻起来像青少年homework@Jack-是以101的名义泄露的吗?弗洛伊德式滑倒?闻起来像青少年homework@Jack-是以101的名义泄露的吗?弗洛伊德的失误?我对这个问题感到困惑。函数需要定义参数。不,在C.C的默认为int规则中没有。这意味着printit本质上需要int。我对这个问题感到困惑。函数需要定义参数。不,它们不在C中。C的默认为int规则意味着printit固有地接受int。我认为您的进一步分析代码不再有任何意义。。。有点强,;从标准的角度来看,这是正确的,因为行为是未定义的,但是如果你正在做一些不可移植的事情,你可能需要了解调用约定等的低级细节,特别是如果是家庭作业:@Mike Dinsdale:是的,但这需要大量的附加信息,比如使用了哪个编译器,什么硬件/操作系统平台等等。是的,你完全正确。在这种情况下,很容易猜测为什么15.5看起来打印正确,但我不知道如何回答OP的问题,为什么他在没有更多信息的情况下得到一个“x”作为字符!我认为你的观点认为进一步分析代码不再有任何意义。。。有点强,;从标准的角度来看,这是正确的,因为行为是未定义的,但是如果你正在做一些不可移植的事情,你可能需要了解调用约定等的低级细节,特别是如果是家庭作业:@Mike Dinsdale:是的,但这需要大量的附加信息,比如使用了哪个编译器,什么硬件/操作系统平台等等。是的,你完全正确。在这种情况下,很容易猜测为什么15.5看起来打印正确,但我不知道如何回答OP的问题,为什么他在没有更多信息的情况下得到一个“x”作为字符!