Что не так с моим кодом на c ? для a = 90 Z должно быть равно -1, но я получаю совершенно другой ответ. Почему?

#c #trigonometry

Вопрос:

Я пытался создать код, который может вычислять тригонометрическую функцию, но все пошло не так, и я не знаю, что делать, потому что я просто не вижу никаких ошибок

 using namespace std;
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <conio.h>
#include <cmath>

int main()
{`

    const double pi = M_PI;
    double Z, a, sin1, cos1, X, Y;

    //printf("Input a =");
    printf("%s", "Input a = ");
    scanf("%g", amp;a);
    a = a * pi / 180;
    sin1 = sin(3 * pi - 2 * a);
    X = (sin1 * sin1)*2;
    cos1 = cos(5 * pi - 2 * a);
    Y = cos1 * cos1;
    Z = X - Y;
    printf("Z = %gnn", Z);

    _getch();
    return 0;


}`
 

Комментарии:

1. Добро пожаловать в Stack Overflow! Похоже, вам, возможно, потребуется научиться использовать отладчик для пошагового выполнения кода. С хорошим отладчиком вы можете выполнять свою программу построчно и видеть, где она отклоняется от того, что вы ожидаете. Это необходимый инструмент, если вы собираетесь заниматься каким-либо программированием. Дальнейшее чтение: Как отлаживать небольшие программы и руководство по отладке

2. scanf("%g", amp;a); переводится на английский так, чтобы прочитать a float от пользователя и сохранить его по адресу a double . Хороший компилятор с достаточным уровнем предупреждения предупредит вас об этом, но, к сожалению, это все еще законный код, и компилятор должен уважать ваши пожелания и предоставить вам программу, которая не может работать . Демонстрация: godbolt.org/z/oEc4YKh6n

3. Исправление для этого заключается в использовании C IO cin >> a; , чтобы убедиться, что все типы совпадают, иначе он не будет компилироваться. Это легко испортить scanf . Мне пришлось отредактировать свой комментарий выше, потому что у меня было double и float то, и другое, и я делал это десятилетиями.

Ответ №1:

Как упоминалось в приведенных выше комментариях, включение предупреждающих сообщений компилятора должно указывать на проблему и предлагать решение, поэтому удаление _CRT_SECURE_NO_WARNINGS может помочь просмотреть проблему и решение:

 (15,11): warning C4477: 'scanf' : format string '%g' requires an argument of type 'float *', but variadic argument 1 has type 'double *'
(15,11): message : consider using '%lg' in the format string
(15,5): error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
 

При использовании предложения компилятора:

 scanf("%lg", amp;a);
 

как также упоминалось в приведенных выше комментариях, мы по-прежнему получаем предупреждение об использовании scanf :

 (15,5): error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
 

Таким образом, чтобы продолжать использовать scanf , когда мы включаем _CRT_SECURE_NO_WARNINGS и получаем ожидаемый результат, однако использование предложенного компилятора scanf_s (и удаление _CRT_SECURE_NO_WARNINGS ) также приводит к ожидаемому результату.

Однако, поскольку вы включили iostream , c предоставляет cin объект класса iostream, поэтому самым простым решением может быть использование cin , как указано в приведенном выше комментарии.

Комментарии:

1. И самое забавное в том, что scanf_s это безопаснее только для определенных определений безопасности. Лично я нахожу, что эти определения не имеют отношения к безопасности.