Это хорошая привычка использовать выражения C в коде C ++?

19

В школе мы начали изучать C в этом году, несмотря на то, что я намного опередил класс, и я изучал Java, C ++ и C, пока класс находится в основе C. Во всяком случае, я документировал себя, читал книги, статьи, и я спросил своего учителя, почему я должен изучать C, и она сказала, что это основа C ++. Когда я впервые начал программировать, я обнаружил, что C ++ намного легче, потом я изучил C. Но в книгах вы можете видеть, что код C работает на C ++, но не наоборот.

Мой вопрос довольно простой ~ Это хорошая привычка использовать выражения C в C ++? Позволь мне привести пример:

Если этот код

#include <stdio.h>
#include <iostream>

int main() {
int x;
scanf("%d", &x);
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

Будьте эффективнее или лучше, чем это:

#include <iostream>

int main() {
int x;
cin >> x;
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

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

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

Есть, вероятно, минусы и плюсы в этом, но я только ищу ответ типа да / почему, нет / почему.

Также, если есть какие-либо подробности, я оставил комментарий.

Bugster
источник
12
Будьте очень осторожны при смешивании stdioи iostream. В семье гарантирован определенный порядок и синхронизация, которые не обязательно применяются вне ее.
Дэвид Торнли
Спасибо за совет, но этот фрагмент кода был чистым примером. Спасибо, в любом случае.
Bugster
25
Если вы изучаете программирование; Вы должны изучить правильный отступ!
битовая
5
scanf () не хороший пример; это настолько ужасно подвержено ошибкам, что я бы посоветовал вам избегать этого в C или C ++.
Рассел Борогове
1
Возможно, это был только пример кода, но комментарий Дэвида действительно доходит до сути вопроса, почему вы не должны использовать идиомы C при программировании на C ++. Это совершенно разные языки; не путайте их больше, чем вы путаете Java и C, или C ++ и Visual Basic.
Коди Грей

Ответы:

36

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

Да, это работает, но если есть эквивалент C ++, используйте его. (например, старайтесь не смешивать printfsс couts)

jglouie
источник
+1 - коротко и точно. И это подчеркивает главное в моем ответе, что руководящие принципы команды помогают объединять людей и объединять их, чтобы они могли работать вместе.
jmort253
Этот комментарий в значительной степени отвечает на мой вопрос правильно и дает веские аргументы. Спасибо.
Bugster
1
@ThePlan спасибо. у всех были отличные ответы на этот вопрос.
jglouie
1
Примечание: использование printfпоследовательно будет работать так же хорошо, как использование coutпоследовательно. Единственными проблемами являются их смешение и стиль.
user253751
Можете ли вы привести пример функции в C, которая не имеет эквивалента в C ++?
klutt
20

В общем, C и C ++ рассматриваются так, как если бы они были двумя совершенно разными языками. Следовательно, использование синтаксиса C в программе на C ++ может считаться дурным тоном.

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

Еще одна вещь, которую следует учитывать, это то, что стандарты помогают создать платформу, где больше людей могут легко работать с кодом. Хотя вам повезло, что у вас есть учитель, который поощряет вас изучать язык С, не всем может повезти. Поэтому смешивание C в программе на C ++ может сбить с толку того, кто никогда не изучал C.

Таким образом, если вы можете что-то сделать, это не значит, что вы должны это делать, а то, что вы не должны что-то делать, не значит, что вы не можете :)

jmort253
источник
Понимаю. Как насчет функциональности, есть ли конкретные случаи, когда синтаксис C лучше, чем синтаксис C ++?
Bugster
10

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

Тем не менее, я считаю это плохой практикой смешивания кода. Если вы используете scanf- используйте printf, если вы используете operator >>- используйте operator <<. Причина в том, что перегруженные операторы C ++ могут инкапсулировать функции, о которых вы не знаете, и их несоответствие приведет к тому, что ваша программа сделает то, чего вы не хотели.

Нет особой причины предпочитать синтаксис C в коде C ++, это разные языки, и при использовании синтаксиса C в коде C ++ - вы все еще пишете код C ++ , просто не используя многие из его мощных инструментов.

littleadv
источник
5
Несовместимость между C и C ++ - это больше, чем просто ключевые слова. Система ввода текста меняется, и в C (особенно в C99) есть функции, которых нет в C ++. (Например, массивы переменной длины).
Арафангион
9

Если оставить в стороне стиль кодирования и эстетические проблемы, существуют также различные технические проблемы, с которыми вы сталкиваетесь при использовании C в коде C ++:

  • Что такое С? С90, С99 или С11? Могут быть различные проблемы совместимости в зависимости от того, какой стандарт C вы используете. // логический тип, // комментарии, функции C99, такие как VLA, назначенные инициализаторы и т. Д.

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

  • Типы, описанные в результате более строгой типизации, как правило, просто полезны, но в некоторых случаях они могут вносить или скрывать ошибки. Возьмите печально известное приведение результата от malloc () в качестве примера. Это должно быть типизировано в C ++, но никогда не в C. (1)

  • Смешивание функций C и C ++ может привести к ошибкам и неопределенному поведению. Например, не будет работать выделение с помощью malloc () и освобождение с помощью delete . (2)

  • Вопросы безопасности потоков. Стандартная библиотека C не является поточно-ориентированной. Стандартная библиотека C ++ может быть или не быть поточно-безопасной, если это так, то добавление вызовов функций библиотеки C в ваш код разрушит это.

    В качестве дополнения для программистов Windows: компилятор Visual C ++ довольно долго имел ошибку утечки, когда функция Windows API CreateThread () использовалась в той же программе, что и библиотека C. (3, 4)

  • Соглашение о вызовах может быть проблемой для некоторых компиляторов, вынуждая его использовать extern "C"для явного указания, какие функции должны быть связаны с «Соглашением о вызовах C».

  • Раздражающие детали. Запятая оператор ведет себя по-разному. Конечная запятая в объявлениях struct / enum разрешена в C99 / C11, но не в C ++. Объем различных типов переменных и функций обрабатывается по-разному. И т. Д.

Там, вероятно, еще больше случаев.


Ссылки:

  1. http://c-faq.com/malloc/cast.html
  2. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.3
  3. http://www.flounder.com/badprogram.htm#CreateThread
  4. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx

источник
7

Причина, по которой C ++ может компилировать C, заключается только в «обратной совместимости» (избегайте перезаписи существующего рабочего кода).

Но C ++ имеет другую философию относительно c. Смешение их не приносит им ничего хорошего.

То, как C и C ++ управляют вводом / выводом, может основываться на другом способе управления внутренним состоянием ввода / вывода. Поэтому, по крайней мере, используйте вход и выход последовательно.

И в программах на C ++ соблюдайте стиль C ++ (если это не требуется специально для других целей)

Эмилио Гаравалья
источник
5

Я бы сказал, что сначала изучение C - это, ИМХО, хорошая идея. Таким образом, люди начинают понимать оборудование, для которого они пишут программное обеспечение.

Однако смешивать эти два языка не обязательно. Потому что вы получаете безумную сложность C ++ в сочетании с обычным битовым твидлингом, характерным для C.

Как видите, даже в таком простом примере, как ваш, есть проблемы синхронизации с разными типами потоков и внутренней буферизации. Но также подход C & C ++ более не является гибким. Переключитесь на класс x, и нет операторов для использования потоковой передачи и прочего.

Это трудно...

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

Но изучение C ++, по крайней мере, более чем на 50%, требует более 5 лет профессионального кодирования, и вы просто не сможете справиться с этим в учебной программе, которая длится 6 месяцев и имеет около 20 часов практического опыта.

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

Классы-обертки RAII, шаблоны, перегрузки, правильность const и чисто абстрактные классы для общих интерфейсов (не используйте здесь f-ng способ ПОЖАЛУЙСТА, ПОЖАЛУЙСТА!) Являются хорошими кандидатами. Потому что они добавляют безопасность, универсальность и простоту использования, что очень важно для реальных проектов. Обязательно помните о таких вещах, как виртуальное уничтожение, взрывная природа создания копий по умолчанию, накладные расходы времени выполнения, правильность констант и т. Д.

кодировщик
источник