Какие мои ошибки в этом коде c я получаю сообщение об ошибке? - PullRequest
0 голосов
/ 08 июля 2019

Итак, я начинаю свой проект. Прямо сейчас я пытаюсь сделать заголовочный файл и включить его в код. Но я не уверен, правильно ли я это делаю.

Ниже приведен проект: я включил только ту часть, над которой я работал, поскольку я не хочу завершенный проект. Я хочу понять.

Цель: создать скрипт C, который найдет отклик нулевого ввода для системы с инвариантным линейным временем второго порядка D 2 y + a1Dy + a2 = 0 на основе коэффициентов (a1 и a2) и начального значения условия (у (0) и у '(0)). (D = D / дт)

Требования:

  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 ]

1 голос
/ 08 июля 2019

Когда вы объявляете переменную вне функции, ее инициализирующее выражение должно быть тем, которое может быть оценено во время компиляции. Это исключает любой инициализатор, который вызывает функцию.

Вероятно, вы предполагали, что переменные l1 и l2 будут внутри функцией. Еще немного о заголовке roots.h имеет большой смысл в контексте кода в main().

Хотя вам нужна функция определение , такое определение обычно не следует помещать в файл заголовка (если только оно не объявлено inline или static, но это было бы необычно и в нетривиальных приложениях может привести к «раздуванию кода», так что это не привычка, которую вы хотите использовать даже для тривиального кода.
Заголовочные файлы обычно декларативны ; то есть они объявляют символы, которые определены в другом месте. Затем вы используете отдельную компиляцию и связывание отдельных единиц перевода.

В этом случае вы можете иметь:

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

Вы должны отдельно скомпилировать оба файла root.c и main.c, а затем связать получившиеся объектные файлы. Чаще всего вы управляете отдельной компиляцией и связыванием через make-файл или управление проектом 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;
}
1 голос
/ 08 июля 2019

Похоже, у вас есть фундаментальное неправильное понимание назначения файлов заголовков - они существуют для того, чтобы гарантировать, что разные исходные (.c) файлы все согласуются с глобальными вещами (типами переменных и т. Д.).

Вы, похоже, пытаетесь вставить код функции в свой заголовок. Линия

float Header( float l1, float l2);

- это предварительное объявление для глобального заголовка подпрограммы, которое принимает два параметра, каждый из которых является плавающим.

Но тогда вы, кажется, вставляете то, что должно быть содержимым функции Header (), которая должна быть в файле .c. Вы получаете ошибки компиляции, потому что у вас есть точка с запятой в конце строки объявления. Функция должна выглядеть примерно так:

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 в файл .c, но это будет крайне плохая идея. Это означало бы, что если два файла .c оба # include'd его, вы получите ошибку ссылки, так как будут определены два экземпляра Header (). только время, когда у вас должна быть функция C в файле .h, если вы объявляете функцию static inline.


Комментарии к вашему новому коду:

Ваш файл roots.h выглядит нормально.

Файл roots.c должен только #include <math.h> один раз. Это безопасно делать несколько раз, так как вокруг него есть директивы #ifndef, но для этого нет причин. Вы также должны включить в него «inc.ins », чтобы гарантировать, что вы объявляете свои функции так, как ожидают вас другие файлы. В коде, который вы даете, у вас есть ошибка в том, что posroot () и negroot () определены как возвращающие int, но в файле roots.h говорится, что они возвращают float. С параметром #include «roots.h» вы гарантированно получите ошибку компиляции (а это именно то, что вам нужно. Без нее вам потребуется отладить код, чтобы выяснить, в чем дело).

Файл main.c выглядит нормально, хотя я не понимаю, почему вы просите пользователя ввести y0 и dy0, когда вы их ни для чего не используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...