Меню Закрыть

Чем отличается printf от cout

Содержание

Я использую Visual C ++ 2012 и компилирую из командной строки следующие файлы:

Связывание с MSVCRT.LIB, а не LIBCMT, чтобы избежать ошибки времени выполнения R6002.
Значение, которое выводится, составляет 0,00000 для этой программы.

Однако, если я выполняю ту же самую вещь в C ++

Теперь он печатает 6, как и должно быть.

Какая разница? Это связано с самими языками (C vs C ++) или методами вывода (cout vs printf), или это просто причуды с MSVC?

Решение

Выражение 18/4+18%4 оценивает int , и вы запрашиваете поплавок. Вы должны всегда компилировать с включенными предупреждениями и обращать на них внимание (говорят предупреждение — ошибка, ожидающая, и они правы).

Это то, что говорит мне мой компилятор (GCC 4.8.1) (и даже без принуждения -Wall ):

С другой стороны, std::cout Операция может определить тип вашего выражения и правильно транслировать его на экран.

Другие решения

Функция C передается целое число, но вы говорите это (с %f ) ожидать числа с плавающей запятой двойной точности, поэтому оно не выполняется. Функция C ++ знает, что ей передается целое число, поэтому она работает правильно.

в С пример этого выражения 18/4+18%4 будет оценивать ИНТ так как все операнды целочисленные константы но вы указываете, что это двойной в printf и поэтому он будет обработан неправильно. С другой стороны, если бы вы использовали Плавающая постоянная в части деления выражения, например, 18.0/4+18%4 все выражение оценило бы к двойной. В качестве альтернативы вы могли бы использовать "%d" в спецификаторе формата.

Это тоже неопределенное поведение неправильно указать формат printf и это также демонстрирует, почему важно строить с предупреждениями, используя gcc -Wall Я получаю следующее предупреждение (видеть это жить ):

В C ++ станд :: соиЬ «s оператор имеет перегрузку для int и поэтому это будет называться в этом случае. Мы можем видеть эту перегрузку, многие другие требуются Проект стандарта C ++ , в разделе 27.7.3.1 Шаблон класса basic_ostream мы находим следующее объявление оператора:

Для полноты, возвращаясь к неопределенному поведению, Проект стандарта C99 в разделе 7.19.6.1 Функция fprintf который printf секция ссылается на формат строки абзаца 9 говорит:

Если спецификация преобразования недопустима, поведение не определено. […]

Но Printf строка формата «% .5f» ожидает двойной.

С помощью c ++ и ostreams язык может автоматически определять тип вывода.

Просто измените свой C-код следующим образом:

Другие правильно указали на несоответствие int / double в вашем выражении printf (). Я просто хочу прокомментировать ваше утверждение: «Связывание с MSVCRT.LIB, а не с LIBCMT, чтобы избежать ошибки времени выполнения R6002». Такая простая программа не должна чрезмерно обременять среду выполнения, поэтому такая ошибка во время выполнения должна быть красным флагом неопределенного поведения в вашем коде.

Быстрый Google «MSVCRT R6002» говорит:

C Run-Time Ошибка R6002
поддержка плавающей запятой не загружена

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

  1. Программа была скомпилирована или связана с опцией, такой как / FPi87, для которой требуется сопроцессор, но программа была запущена на машине, на которой не был установлен сопроцессор.
  2. Строка формата для функции printf_s или scanf_s содержала спецификацию формата с плавающей запятой, а программа не содержала значений или переменных с плавающей запятой.
  3. Компилятор минимизирует размер программы, загружая поддержку с плавающей точкой только при необходимости. Компилятор не может определить спецификации формата с плавающей точкой в ​​строках формата, поэтому он не загружает необходимые подпрограммы с плавающей точкой.
  4. Используйте аргумент с плавающей точкой, чтобы соответствовать спецификации формата с плавающей точкой, или выполните присвоение с плавающей точкой в ​​другом месте программы. Это приводит к загрузке поддержки с плавающей точкой.
  5. В программе на разных языках библиотека C была указана перед библиотекой FORTRAN, когда программа была связана. Перепроверьте и укажите библиотеку C в последнюю очередь.
Читайте также:  Fido uaf что это за программа

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

В C потому что вы явно указываете плавающую точку («% f») в вашем спецификаторе формата printf, поэтому он ожидает аргумент с плавающей точкой. Но вы даете этому аргумент «int», отсюда и проблема.

В зависимости от того, что вы пытаетесь сделать, вы можете:

1) Кастинг (иначе целое числоВыражение плавать

2) Использование setprecision в потоке cout, так же, как вы использовали бы «% .5f» в C:

3) Если вы хочу целое число, использовать printf ("%d", 18/4+18%4);

Если вы хотите такое же поведение (и ответ), вам лучше написать код

чтобы получить int вместо ответа с плавающей точкой. Вы получите тот же результат, что и выбран оператор

В противном случае вы можете использовать явно

получить 6.00000 результат.

Пусть одно из ваших чисел будет значением с плавающей запятой:

Я использую Visual С++ 2012 и компилирую из командной строки следующие файлы:

Связывание с MSVCRT.LIB, а не LIBCMT, чтобы избежать ошибки времени выполнения R6002.
Выводимое значение составляет 0,00000 для этой программы.

Однако, если я выполняю то же самое в С++

Теперь он выдает 6, как и должно.

Какая разница? Это касается самих языков (C vs С++) или методов вывода (cout vs printf), или это просто причуда с MSVC?

c++ c floating-point printf cout

9 ответов

64 Решение Escualo [2013-09-30 23:06:00]

Выражение 18/4+18%4 оценивается как int , и вы запрашиваете float. Вы всегда должны компилировать с включенными предупреждениями и обращать на них внимание (они говорят, что предупреждение — это ошибка, ожидающая появления, и они правы).

Вот что говорит мой компилятор (GCC 4.8.1) (и даже без применения -Wall ):

С другой стороны, операция std::cout позволяет выводить тип вашего выражения и корректно передавать его на экран.

37 Gabe [2013-09-30 23:05:00]

Функция C передает целое число, но вы говорите ему (с %f ), чтобы ожидать число с плавающей запятой с двойной точностью, поэтому он терпит неудачу. Функция С++ знает, что ей передается целое число, поэтому оно работает правильно.

В примере C это выражение 18/4+18%4 будет вычисляться как int, так как все операнды являются целыми константами, но вы указываете, что это двойное значение printf , и поэтому оно будет обрабатываться некорректно. С другой стороны, если бы вы использовали плавучую константу в части деления выражения, например 18.0/4+18%4 , все выражение оценивалось бы двойным. В качестве альтернативы вы могли бы использовать "%d" в спецификаторе формата.

Это также undefined поведение, чтобы неправильно указать формат printf , и это также демонстрирует важность построения с предупреждениями, используя gcc -Wall Я получаю следующее предупреждение (см. live):

Для полноты, обращаясь к поведению undefined, черновик проекта C99 в разделе 7.19.6.1 Функция fprintf, которая printf ссылается на строку форматирования в абзаце 9:

Если спецификация преобразования недействительна, поведение undefined. [. ]

оценивает значение int.

Но строка формата printf "%.5f" ожидает двойной.

С С++ и ostream, язык может автоматически определять тип вывода.

Просто измените свой C-код на следующий:

8 Drew Hall [2013-10-01 14:03:00]

Другие правильно указали совпадение int/double в вашем заявлении printf(). Я просто хочу прокомментировать ваше выражение: "Связывание с MSVCRT.LIB, а не LIBCMT, чтобы избежать ошибки R6002 во время выполнения". Программа, такая простая, не должна излишне налагать налоговую нагрузку на среду выполнения, поэтому такая ошибка должна быть красным значком поведения undefined в вашем коде.

Читайте также:  Эксплуатация зимней резины летом

Быстрый Google "MSVCRT R6002" говорит:

C Ошибка времени выполнения R6002поддержка с плавающей запятой не загружена

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

  • Программа была скомпилирована или связана с опцией, например /FPi 87, для которой требуется сопроцессор, но программа была запущена на машине, на которой не было установлен сопроцессор.
  • Строка формата для функции printf_s или scanf_s содержала спецификацию формата с плавающей запятой, и программа не содержала никаких значений или переменных с плавающей запятой.
  • Компилятор минимизирует размер программы, загружая поддержку с плавающей запятой только тогда, когда это необходимо. Компилятор не может определить спецификации формата с плавающей запятой в строках формата, поэтому он не загружает необходимые процедуры с плавающей запятой.
  • Используйте аргумент с плавающей запятой, чтобы соответствовать спецификации формата с плавающей запятой, или выполнить назначение с плавающей запятой в другом месте программы. Это приводит к загрузке поддержки с плавающей запятой.
  • В программе на смешанном языке библиотека C была указана перед библиотекой FORTRAN при подключении программы. Переименуйте и укажите последнюю библиотеку C.

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

4 paulsm4 [2013-09-30 23:05:00]

В C, потому что вы явно указываете с плавающей точкой ( "% f" ) в спецификаторе формата printf, поэтому он ожидает аргумент с плавающей запятой. Но вы даете ему аргумент "int", следовательно, проблема.

В зависимости от того, что вы пытаетесь сделать, вы можете:

1) Выделение выражения (в противном случае целого) для float

2) Используя setprecision в вашем потоке cout, так же, как вы используете "%.5f" в C:

3) Если вы хотите целое число, используйте printf ("%d", 18/4+18%4);

Если вам нужно одинаковое поведение (и ответ), вам лучше закодировать

чтобы получить ответ int вместо числа с плавающей точкой. Вы получите тот же результат, что и оператор , выбранный

В противном случае вы можете явно использовать

чтобы получить результат 6.00000 .

1 smac89 [2013-09-30 23:16:00]

Пусть одно из ваших чисел будет значением с плавающей запятой:

Одна из возможных альтернатив — типизация литералов (или самого выражения):

Я использую Visual C++ 2012 и компилирую из командной строки следующие файлы:

связывание с MSVCRT.LIB, а не LIBCMT, чтобы избежать ошибки выполнения R6002.
Выходное значение для этой программы равно 0.00000.

однако, если я выполняю то же самое в C++

теперь он печатает 6, как и должно.

в чем разница? Это связано с самими языками (C vs C++) или с выходом методы (cout vs printf), или это просто причуда с MSVC?

9 ответов

выражение 18/4+18%4 оценивает в int , и вы запрашиваете поплавок. Вы всегда должны компилировать с включенными предупреждениями и обращать на них внимание (они говорят предупреждение-это ошибка ждет, и они правы).

это то, что мой компилятор (GCC 4.8.1) говорит мне (и даже без принуждения -Wall ):

С другой стороны, std::cout операция способна вывести тип вашего выражения и правильно передать его в ваш экран.

функция C передается целым числом, но вы говорите это (с %f ) ожидать числа с плавающей запятой двойной точности, поэтому он терпит неудачу. Функция C++ знает, что ей передается целое число, поэтому она работает правильно.

Читайте также:  Стоимость виндовс 7 максимальная

на C пример этого выражения 18/4+18%4 оценивают в int так как все операнды целочисленные константы но вы указываете, что это двойной to printf и поэтому он будет обработан неправильно. С другой стороны, если вы используете плавающие константы в части деления выражения, например 18.0/4+18%4 все выражение было бы оценено в a двойной. В качестве альтернативы вы могли бы использовать "%d" в спецификаторе формата.

это тоже неопределенное поведение неправильно указать формат в printf и это также демонстрирует, почему важно строить с предупреждениями, используя gcc -Wall Я получаю следующее предупреждение(видеть live):

для полноты, возвращаясь к неопределенному поведению,проект стандарта C99 в разделе 7.19.6.1 функция fprintf, который printf ‘ы раздел ссылается на строку формата paragraph 9 говорит:

если спецификация преобразования является недопустимым, поведение неопределено.[. ]

оценивает в int.

но printf формат строки "%.5Ф" ожидает двойная.

С помощью c++ и ostreams язык может автоматически определять тип вывода.

просто измените свой C-код на следующий:

Другие правильно указали на несоответствие int/double в вашем операторе printf (). Я просто хочу прокомментировать ваше заявление", — говорится в сообщении MSVCRT.LIB, а не LIBCMT, чтобы избежать ошибки выполнения R6002."Такая простая программа не должна чрезмерно облагать налогом среду выполнения, поэтому такая ошибка выполнения должна быть красным флагом неопределенного поведения в вашем коде.

быстрый Google "MSVCRT R6002" говорит:

C Ошибка Времени Выполнения R6002 поддержка с плавающей запятой не загружена

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

  1. программа была скомпилирована или связана с опцией, такой как /FPi87, для которой требуется сопроцессор, но программа была запущена на машине, на которой не был установлен сопроцессор.
  2. строка формата для функции printf_s или scanf_s содержит формат с плавающей запятой спецификация и программа не содержали никаких значений или переменных с плавающей запятой.
  3. компилятор минимизирует размер программы, загружая поддержку с плавающей запятой только при необходимости. Компилятор не может обнаружить спецификации формата с плавающей запятой в строках формата, поэтому он не загружает необходимые процедуры с плавающей запятой.
  4. используйте аргумент с плавающей запятой для соответствия спецификации формата с плавающей запятой или выполните назначение с плавающей запятой в другом месте программы. Это приводит к загрузке поддержки с плавающей запятой.
  5. в программе на смешанном языке библиотека C была указана перед библиотекой FORTRAN, когда программа была связана. Повторно свяжите и укажите библиотеку C последней.

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

В C, поскольку вы явно указываете плавающую точку ("%f") в описателе формата printf, поэтому он ожидает аргумент с плавающей точкой. Но вы даете ему аргумент "int", следовательно, проблема.

в зависимости от того, что вы пытаетесь сделать, вы можете:

1) литье (в противном случае целое) выражение для float

2) с помощью setprecision в поток cout, так же, как вы бы использовать "%.5Ф" в C:

3) Если вы хочу целое число, используйте printf ("%d", 18/4+18%4);

если вы хотите такое же поведение (и ответ) вы бы лучше код

чтобы получить ответ int Вместо ответа с плавающей запятой. Вы получите тот же результат, что и выбранный оператор

в противном случае, вы можете использовать явно

и 6.00000 результат.

пусть одно из ваших чисел будет значением с плавающей запятой:

одной из возможных альтернатив является типизация литералов (или самого выражения):

Рекомендуем к прочтению

Добавить комментарий

Ваш адрес email не будет опубликован.