我不断收到错误消息的C代码有什么错误?

时间:2019-07-07 21:36:33

标签: c

所以我要开始我的项目。现在,我正在尝试制作头文件并将其包含在代码中。但是我不确定我是否做对了。

下面是项目:我只包括我已经完成的部分,因为我不想完成一个项目。我想了解。

目标:创建一个C脚本,该脚本将基于系数(a1和a2)和以下项找到二阶线性时不变系统D 2 y + a1Dy + a2 = 0的零输入响应初始条件(y(0)和y'(0))。 (D = d / dt)

要求:

  1. 应该提示用户输入线性系统的系数和两个初始条件:D 2 y + a1Dy + a2 =0。

  2. 找到二阶非平凡解的根。 D 2 y + a1Dy + a2 = 0 =>λ 2 +a1λ+ a2 = 0

为此步骤创建头文件。

我创建的头文件roots.h

#ifndef roots_h
#define roots_h

#include <stdio.h>

// Function Declaration
float posroot(float, float);
float negroot(float, float);

#endif /* roots_h */

roots.c:

#include <math.h>

int posroot(float a1, float a2){
    float root1;
    root1=(((-1)*(a1)) + sqrt((pow(a1,2)) - (4*a1*a2))) / (2);
    return root1;
}

#include <math.h>

int negroot(float a1, float a2){
    float root2;
    root2= (((-1)*(a1)) - sqrt( (pow(a1,2)) - (4*a1*a2))) / (2);
    return root2;
}

main.c:

#include <stdio.h>
#include "roots.h"//header file

int main(){
    //Variables
    float a1, a2, y0, dy0,root1, root2;

    //User asked to type in coeffecients
    printf("Enter a1 a2 y(0) and y'(0) seperated by a space: ");
    scanf("%f %f %f %f", &a1, &a2, &y0, &dy0);

    //Using the functions 
    root1=posroot(a1, a2);
    root2=negroot(a1, a2);

    //print the roots
    printf("The roots of the second order nontrivial solution: %f and %f", root1,root2);
    return 0;
}

在头文件上,它一直说“ Initializer元素不是编译时常量”。

2 个答案:

答案 0 :(得分:1)

您似乎对头文件的用途有根本的误解-它们的存在是为了确保不同的源(.c)文件都在全局事物(变量类型等)上达成共识。

您似乎正在尝试将函数代码放入标头中。线

float Header( float l1, float l2);

是全局例程Header的前向声明,该例程带有两个参数,两个参数都是浮点数。

但是随后您似乎正在放入应该在.c文件中的Header()函数的内容。由于在声明行的末尾有分号,因此出现编译错误。该功能应该看起来像

float Header( float l1, float l2)
{
    float a1, a2, return_value;
    float l1= (((-1)*(a1)) + sqrt( (pow(a1,2)) - (4*a1*a2))) / (2);
    float l2= (((-1)*(a1)) - sqrt( (pow(a1,2)) - (4*a1*a2))) / (2);
    return some_value;
}

此代码仍然是错误的(正在引用未分配的变量a1和a2,并覆盖传入的变量l1和l2。而且返回值从未分配过-大概是要对l1和l2和返回结果。

如果您纠正了这些错误并使Header()函数正常工作,如果您将其从.h文件中#include到.c文件中,则它实际上会进行编译,但这是一个非常糟糕的主意。这意味着,如果两个.c文件都被#include了,那么最终将导致链接错误,因为将定义两个Header()实例。在文件中只有 时间是在声明static inline函数的情况下。


对您的新代码的评论:

您的roots.h文件看起来不错。

roots.c文件应仅#include <math.h>一次。多次执行此操作是安全的,因为它周围有#ifndef指令,但是没有理由这样做。您还应该在其中#include“ roots.h”,以确保以其他文件期望的方式声明函数。在您提供的代码中,您错误地认为posroot()和negroot()被定义为返回整数,但是roots.h文件表示它们返回浮点数。使用#include的“ roots.h”,可以保证得到编译错误(这是您想要的)。没有它,您将需要调试代码以找出错误的原因。

main.c文件看起来不错,尽管我不明白为什么您在不使用它们时要求用户输入y0和dy0。

答案 1 :(得分:1)

在函数外部声明变量时,其初始化程序表达式必须是可以在编译时求值的表达式。这不包括任何调用函数的初始化程序。

您似乎希望变量l1l2在函数内 。在main()中的代码上下文中,关于头文件roots.h的意义不大。

虽然您需要功能 definition ,但通常不应将此类定义放在头文件中(除非已将其声明为inlinestatic,但这是不常见的)在非平凡的应用程序中可能会导致“代码膨胀”,因此即使对于平凡的代码,这也不是您要养成的习惯。
头文件通常是 declarative ;也就是说,它们声明在其他地方定义的符号。然后,您可以使用单独的编译单元和各个翻译单元的链接。

在这种情况下,您可能会:

roots.h

#ifndef roots_h
#define roots_h

// Find the roots of the second order nontrivial solution
void roots( float a1, float a2, float* l1, float* l2 ) ;

#endif /* roots_h */

roots.c

#include <math.h>
#include "roots.h"

void roots( float a1, float a2, float* l1, float* l2 )
{
    float r = sqrt( a1*a1 - 4*a1*a2) ;
    *l1 = (-a1 + r) / 2 ;
    *l2 = (-a1 - r) / 2 ;
}

main.c

#include <stdio.h>
#include "roots.h"  //header file

int main()
{
    printf("Enter a1 and a2 separated by a space: ");
    float a1, a2;
    scanf("%f %f", &a1, &a2);

    float l1, l2;
    roots( a1, a2, &l1, &l2) ;

    printf( "l1 = %f, l2 = %f\n", l1, l2 ) ;

    return 0;
}

您必须分别编译roots.c和main.c,然后链接生成的目标文件。通常,您将通过makefile或IDE项目管理来管理单独的编译和链接-否则,即使只有很少的翻译单元,它也会变得非常繁琐且容易出错。

对于琐碎的代码(我感谢这是一个较大的项目的一部分),您可以简单地避免这样做,并将代码放在单个文件中:

#include <stdio.h>
#include <math.h>

void roots( float a1, float a2, float* l1, float* l2 )
{
    float r = sqrt( a1*a1 - 4*a1*a2) ;
    *l1 = (-a1 + r) / 2 ;
    *l2 = (-a1 - r) / 2 ;
}

int main()
{
    printf("Enter a1 and a2 separated by a space: ");
    float a1, a2;
    scanf("%f %f", &a1, &a2);

    float l1, l2;
    roots( a1, a2, &l1, &l2) ;

    printf( "l1 = %f, l2 = %f\n", l1, l2 ) ;

    return 0;
}