2015-03-30 2 views
2

Итак, у меня есть следующий код, и он отлично работает и работает, пробовал различные значения, и все хорошо. Вы заметите, что я использую функцию log10, и я не включаю cmath или math.h. Почему он все еще строит и работает нормально? Нужны ли эти библиотеки? Почему, почему нет? Это имеет какое-то отношение ко мне, используя визуальную студию? Например, не будет ли компиляция, если скажу, что я использовал другую IDE или командную строку для ее компиляции?Действительно ли <cmath> или <math.h> действительно нужен? Компилирует без него

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main() { 

    cout << "Classify solutions as acidic or nonacidic" << endl<< endl; 

    //declaring double molar concentration 
    double mc = 1; 

    //using while and if statements to calculate pH in fixed notaion and acidic or nonacidic 
    while (mc != 0) 
    { 
     cout << "Please enter a molar concentration (or enter 0 to exit): "; 
     cin >> mc; 

     if (mc != 0) 
     { 
      cout << "Molar Conentration = " << scientific << mc << endl; //scientific notation 

      double pH = -log10(mc); 
      cout << "pH = " << fixed << setprecision(6) << pH << endl; //6 deciumals 

      if (pH > 7) 
      { 
       cout << "Nonacidic" << endl << endl; 
      } 
      else if (pH < 7) 
      { 
       cout << "Acidic" << endl << endl; 
      } 
      else 
       cout << "Neutral" << endl << endl; 
     } 
    } 

    //end program when inputing 0 
    cout << "End of Program" << endl; 

    return 0; 
} 
+1

заголовков разрешено включают другие заголовки. – chris

+4

У меня возникли проблемы с попыткой создания нового компилятора, и он не может быть создан, потому что некоторые заголовки не были включены напрямую. –

ответ

3

Как вы заметили, фрагмент кода, который вы предоставили, работает в Visual Studio, но не с другими компиляторами. Это связано с тем, как стандартная библиотека реализована для каждого компилятора.

Оказывается, когда вы включаете реализацию Visual Studio <iostream>, вы в конечном итоге включаете пучок других заголовков косвенно, а один из этих заголовков - <cmath>.

Чтобы увидеть точную цепочку, перейдите к каталогу стандартной библиотеки. Для меня (я использую Visual Studio 2013 Community Edition), это находится в

C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ VC \ включают

  1. Открыть iostream. Обратите внимание на строку
  2. Открыть istream. Обратите внимание на строку #include <ostream>
  3. Открыть ostream. Обратите внимание на строку #include <ios>
  4. Открыть ios. Обратите внимание на строку #include <xlocnum>
  5. Открыть xlocnum. Обратите внимание на строку #include <cmath>

Угадайте, что? Вы включили cmath, когда вы включили iostream ... так что ваш код хорош, по крайней мере, на Visual Studio. Но, не полагайтесь на детали реализации, или ваш код сломается, если вы попытаетесь перенести его на другую платформу/toolchain.

Например, пытаясь собрать предоставленный фрагмент кода с помощью г ++ по результатам Cygwin в следующей ошибки:

temp.cpp: In function ‘int main()’: 
temp.cpp:22:34: error: ‘log10’ was not declared in this scope 
      double pH = -log10(mc); 

Это должно означать г ++ реализация 's из <iostream> не зависит от <cmath>

+0

Спасибо, это действительно полностью ответило на мой вопрос и определило, что именно в визуальной студии делает работу. Я не забудьте включить его. Есть ли способ сделать визуальный студийный флаг, который я забыл в офшоре? – cb1295

+1

Хотел бы я знать ... может быть, кто-то другой. Когда это возможно, я скомпилирую код C/C++, используя как минимум 2 разных компилятора. Это помогает сохранить код чистым, совместимым и портативным. Вы будете удивлены различными ошибками, сообщаемыми каждым компилятором. В Visual Studio вы можете просмотреть все заголовки, включенные в проект, путем расширения фильтра «Внешние зависимости» проекта в обозревателе решений. –

+0

А, это, наверное, хорошая идея. Спасибо за эти два совета – cb1295

6

Код:

i = i++ + ++i; 

может также компилировать в порядке, но это не делает его хорошей идеей :-)

Было бы целесообразно включить заголовки для библиотеки функции, которые вы используете. Вы не делаете , но вы гарантируете, что функциональность будет работать (несмотря на неправильное использование).


Подробный анализ следует.

Даже если реализация расслаблена об этом, стандарт предусматривает ее. C++11 17.6.2.2 Headers /3 состояния:

A translation unit shall include a header only outside of any external declaration or definition, and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.

gcc компилятор, например, будет ворчать горько код:

xyzzy.cpp: In function 'int main()': 
xyzzy.cpp:22:34: error: 'log10' was not declared in this scope 
      double pH = -log10(mc); 
           ^

Что касается почему VC++ на первый взгляд нарушает это правило, это связано с тем фактом, что заголовочным файлам разрешено включать другие файлы заголовков.

Если вы скомпилировать код, чтобы произвести вывод до процессора (с /P), вы найдете линию похоронена глубоко внутри него таким образом (по крайней мере в VS2013):

#line 1 "c:\\blah\\blah\\vc\\include\\cmath" 

и немного анализа появляется следующая иерархия включает в себя:

iostream 
    istream 
     ostream 
      ios 
       xlocnum 
        cmath 

(<xlocnum>, один из внутренних заголовков, используемых <locale>, по-видимому, необходим ldexp() из <cmath> библиотеки, хотя там может быть флористика rs также).

Вот также свидетельствует тот факт, что VC++ делает жалуются на следующий код:

//#include <iostream> 
using namespace std; 

int main() { 
    double oneHundred = 100; 
    int two = log10 (oneHundred); 
    return two; 
} 

с:

error C3861: 'log10': identifier not found 

, но эта ошибка исчезает в тот момент, раскомментировать iostream включения линии.


Однако, как было сказано ранее, что не поведение вы должны полагаться.Если вы собираетесь использовать библиотечную функцию (или макрос/шаблон/безотносительно), то до вы получите, чтобы включить правильный заголовок.

В противном случае ваша программа, составленная правильно, является просто случайностью.

+0

Ха-ха, правда. Мои вопросы все еще остаются. Поэтому, очевидно, я должен включить его, но почему визуальная студия все еще строится и не дает мне предупреждения, когда онлайн-компилятор, например http://www.tutorialspoint.com/compile_cpp_online.php, запускает ошибку и не компилирует тот же код? – cb1295

+2

@ChristopherBonilla Нет * гарантии *, что ваш код будет скомпилирован успешно. Измените компиляторы или даже используйте другую версию Visual Studio, ваш код не может компилироваться, если требуемые заголовки отсутствуют. – PaulMcKenzie

Смежные вопросы