Подтвердить что ты не робот

Ситуации, где "старые" функции C могут быть лучше, чем более новые С++?

Недавно у меня возникла дискуссия с моим боссом (разработчиком долгого времени C), который не поощрял меня использовать потоки С++ и придерживаться "старых добрых" printf и друзей. Теперь я могу понять, почему он говорит это и верит, что я не следовал его советам.

Но все же это подслушивает меня - есть ли вещи в C, которые в некоторых случаях еще лучше, чем более новые версии С++ той же/подобной вещи? К лучшему я имею в виду, например, производительность, стабильность или даже читаемость кода/ремонтопригодность. И если да, может ли кто-нибудь привести мне примеры? В основном я говорю о подобных различиях, таких как printf/streams, а не о таких функциях, как наследование или ООП. Причина, по которой я все это спрашиваю, это то, что я считаю себя разработчиком С++, и поэтому я всегда пытаюсь закодировать С++ путь.

4b9b3361

Ответ 1

C printf() - вывод стиля, как правило, быстрее, чем вывод С++ ostream. Но, конечно, он не может обрабатывать все типы, которые могут выводиться на выходе С++. Это единственное преимущество, о котором я знаю - обычно, из-за агрессивной вставки, С++ может быть намного быстрее, чем C.

Ответ 2

Есть одна вещь, которую иногда указывают программисты C, и это стоит учитывать: если вы избегаете макросов, то в основном очевидно, что делает строка кода C. Возьмем, например, следующее:

x = y;

В C это назначение и только назначение. Значение y (после возможного преобразования) копируется в x.

В С++ это может буквально означать что-либо.

  • Простое назначение,
  • пользовательский оператор преобразования в y, который удаляет Интернет и возвращает значение, которое имеет тот же тип, что и x
  • Существует конструктор, который делает объект типа x из y, после плавления атомной электростанции. Это значение присваивается x.
  • Существует пользовательский оператор присваивания, который позволяет назначать из группы других типов, для которых y имеет оператор преобразования или какие-либо другие способы, доступные из y. Оператор присваивания имеет ошибку, которая может создать черную дыру, поскольку она является частью программного обеспечения для работы с LHC.
  • более того.

Чтобы сделать его еще более интересным, каждая отдельная операция может вызвать исключение в С++, а это означает, что каждая строка должна быть написана так, чтобы она могла отменить то, что она изменила, что иногда сложно, когда вы не можете сказать, что линия фактически делает. И чтобы усугубить ситуацию, ваша программа может мгновенно сработать, потому что исключение происходит, потому что назначение вызывается во время исключения. В С++ вещи, как правило, становятся "вертикально сложными", что создает свои собственные требования к возможностям и навыкам общения разработчиков.

Ответ 3

Когда вы пишете С++, пишите С++. Когда вы пишете C, пишите C. Тот, кто говорит разные, вероятно, неудобно с различиями или думает о С++ как о "лучше C". Это не так; С++ - это собственный язык с его собственными функциями и в основном C-совместимый с единственной целью облегчения преобразования.

Ответ 4

Что касается производительности, я был конкурентом USACO. Я быстро обнаружил, что 98% одной из исполняемых программ моей программы были потрачены на использование С++ IOStreams. Переход на fscanf уменьшил накладные расходы в десять раз. С точки зрения производительности, конкурса вообще нет.

Ответ 5

Я думаю, что стиль C лучше, когда вам нужно необработанное управление памятью. Это немного громоздко сделать с конструкциями С++, и у вас нет realloc(), например.

Кто-то, кто проголосовал за это, вероятно, никогда не пытался изучить тему.


Я удивляюсь, как люди не могут представить себя в разных позициях. Я не говорю, что каждый должен использовать конструкции стиля С. Я говорю, что стиль C лучше, если вы используете НЕОБХОДИМО необработанное управление памятью. Кто-то должен написать все эти безопасные классы/библиотеки (включая стандартную библиотеку, сборщики мусора, пулы памяти). Ваш опыт, в котором он вам никогда не нужен, не распространяется на все случаи.


Другая ситуация - когда вы пишете библиотеку. С помощью C вы получаете симпатичную таблицу символов, которая может быть легко привязана ко многим другим языкам программирования. С С++ у вас будет name mangling, что делает библиотеку более сложной (но не невозможной) для использования в среде, отличной от С++.

Ответ 6

Старый добрый C! Ах, дни до ANSI... <sarcasm> Я, конечно, не имею практически никакого контроля типа на аргументах и ​​возвращает значения или что компилятор предполагает, что что-то неотображенное является int, а не ошибкой. </sarcasm>

Серьезно, однако, есть довольно хороший аргумент против использования исключений в качестве обработки ошибок. Я прочитал довольно достойный аргумент против исключений для работы на системном уровне, и в основном я думаю, что проблема в том, что вы не можете просто прочитать блок кода и знаете, что он не будет бросать на С++, тогда как вы можете прочитать большую часть C и сказать, что "все ошибки (на этом уровне) попадают в ловушку" или "те, которые не имеют значения".

Ответ 7

Я не мог дать вам окончательный ответ; однако я нашел это довольно датированное сравнение интересным.

http://unthought.net/c++/c_vs_c++.html

Ответ 8

Я не думаю, что использование функций стиля printf, как правило, над iostreams оправдано. iostreams просто значительно ускоряют время разработки и время отладки и гораздо меньше подвержены ошибкам (например, подумайте о переполнении буфера, неверных спецификаторах типа%, неправильном количестве аргументов... и самая большая проблема заключается в том, что компилятор не может помочь вам вообще), И если вы не используете endl, когда это не нужно, cout не так много медленнее, чем printf.

Как правило, вы должны идти с iOS-потоками С++, и только если профилирование показывает, что критические разделы занимают слишком много времени из-за вызовов iostream, а затем оптимизируйте эти разделы с помощью функций стиля C, но обязательно используйте более безопасные версии функций, таких как snprintf вместо sprintf.

Примеры:

У вас есть переменная int foo, которую вы printf в ряде мест, позже во время разработки, понимаете, что вам нужно foo вместо double. Теперь вам нужно изменить спецификаторы типов в каждом вызове стиля printf, который использует foo. И если вы пропустите одну строку, добро пожаловать в страну поведения undefined.

Недавно у меня был случай, когда моя программа разбилась, потому что я пропустил простую запятую, и из-за большой команды стиля printf мой компилятор мне не помог: printf("i will crash %s" /*,*/ "here");. Это не произошло бы с iostreams.

И, конечно же, вы не можете расширить поведение printf и друга, чтобы работать со своими собственными классами, как вы можете с помощью iostreams.

Ответ 9

Если использование функций С++ может быть проблематичным:

  • переносимость: IMHO C еще более портативен.
  • программирование на смешанном языке: вызов функции C с другого языка почти никогда не бывает проблематичным, а С++ у вас быстро возникают проблемы из-за манипуляции с именем и т.д.
  • проблемы с производительностью: функции, такие как шаблоны, могут привести к раздуванию кода, создание временных объектов может также иметь огромное влияние и т.д.
  • :. Поскольку С++ более сложна, чем C, ограничьте использование функций языка, которые вы ожидаете от человека, который впоследствии поддерживает ваш код.

Однако некоторые/большинство функций С++ весьма удобны и полезны при использовании с осторожностью. Помните высказывание "С С++ вам тяжело стрелять в колено, но если вы это сделаете, это обойдется вам всей ногой".

Ответ 10

Я иногда предпочитаю указатели и memcpy над итераторами и std::copy, когда мне не нужен общий код.

То же самое для iostreams, они удобны и расширяемы, но есть много ситуаций, когда [f | s] printf/scanf просты.