Чи корисна звичка використовувати вирази C у коді C ++?


19

У школі ми почали вивчати C цього року, незважаючи на те, що я випереджаю клас, і я навчився Java, 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 і в які контексти.

Це стосується також файлу IO, оскільки я завжди вважав, що FI IO простіший у C, ніж у C ++. Це питання стосується майже кожного загального вираження в C, застосованого до C ++. Примітно також, що я використовую сучасний компілятор, але, тим не менш, це не має значення, оскільки я запитую, чи є хороша звичка програмування використовувати вирази C у коді C ++.

Мабуть, є мінуси і плюси в цьому, але я шукаю лише відповідь "так", "ні", "чому".

Крім того, якщо є якісь деталі, я не залишив коментар.


12
Будьте ретельно обережні щодо змішування stdioта iostream. У сім'ї гарантується певний порядок і синхронізація, які не обов'язково застосовуються поза нею.
Девід Торнлі

Дякую за пораду, але цей брухт коду був чистим прикладом. Все одно, дякую.
Багстер

25
Якщо ви вивчаєте програмування; Ви повинні навчитися правильному відступі!
бітмаска

5
scanf () - не чудовий приклад; настільки страшно схильні до використання, що я б радив вам уникати цього в C або C ++.
Рассел Борогов

1
Можливо, це був лише зразок коду, але коментар Девіда дійсно потрапляє до основи проблеми, чому ви не повинні використовувати ідіоми C при програмуванні на C ++. Вони зовсім інші мови; не плутайте їх більше, ніж ви плутаєте Java та C, або C ++ та Visual Basic.
Коді Грей

Відповіді:


36

Ні, це шкідлива звичка. Зробивши це на життя, ви, швидше за все, порушите посібники зі стилю, яких дотримується ваша команда (або принаймні зазнають збитків під час перегляду коду).

Так, це працює, але якщо є еквівалент c ++, використовуйте його. (наприклад, намагайтеся не змішувати printfsз couts)


+1 - Короткий і до точки. І це підкреслює головний момент моєї відповіді, що керівництво команди допомагає згуртувати людей та об'єднати їх, щоб вони могли працювати разом.
jmort253

Цей коментар в значній мірі відповідає на моє питання належним чином і приводить вагомий аргумент. Дякую.
Багстер

1
@ThePlan спасибі всі мали чудові відповіді на це запитання.
jglouie

1
Примітка: printfпослідовне використання працюватиме так само добре, як і coutпослідовно використовувати . Єдині проблеми - це змішування їх між собою та стилю.
користувач253751

Чи можете ви навести приклад функції в C, яка не має еквівалента C ++?
клот

20

Взагалі, C і C ++ дивляться так, ніби це дві абсолютно окремі мови. Тому можна вважати поганою формою використання синтаксису C у програмі C ++.

Ви праві; однак, цей код C складеться чудово. Це дійсно залежить від того, наскільки гнучка ваша компанія щодо дотримання наступних стандартів. Якби мені коли-небудь задавали питання в інтерв'ю, я був би впевнений, щоб повідомити інтерв'юеру, що C працює на C ++, але також, що C і C ++ є двома окремими мовами, і, ймовірно, їх не слід змішувати, якщо б не було дуже, дуже вагома причина для цього.

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

Підсумовуючи це, те, що ти можеш щось робити, не означає, що ти повинен, а те, що ти не повинен щось робити, не означає, що ти не можеш :)


Я бачу. Як щодо функціональності, чи є конкретні випадки, коли синтаксис C кращий, ніж синтаксис C ++?
Багстер

10

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

Однак я вважаю це неправильною практикою змішування коду. Якщо ви використовуєте scanf- використовуйте printf, якщо ви використовуєте operator >>- використовуйте operator <<. Причина полягає в тому, що перевантажені оператори C ++ можуть увімкнути функціональні можливості, про які ви не знаєте, а їхнє невідповідність призведе до того, що ваша програма робитиме речі, які ви цього не хотіли.

Немає особливих причин віддавати перевагу синтаксису C у коді C ++, це різні мови, а коли ви використовуєте синтаксис C у коді C ++ - ви все ще пишете код C ++ , просто не використовуючи багато його потужних інструментів.


5
Несумісність між C і C ++ - це більше, ніж просто ключові слова. Система набору тексту змінюється, і в C (особливо C99) є функції, які не існують у C ++. (Наприклад, масиви змінної довжини).
Арафангіон

9

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

  • Що таке С? C90, C99 або C11? Можуть виникнути різні проблеми сумісності залежно від того, який стандарт C ви використовуєте. Булевий тип, // коментарі, функції C99, такі як VLA, призначені ініціалізатори тощо

  • C ++ має суворіший тип введення, ніж C. Для того, щоб скласти код C у C ++, вам, швидше за все, потрібно додати різні типи передач, щоб отримати очікуваний тип. Це означає, що вам, можливо, доведеться переписати ідеально чудовий, якісний код C, щоб він працював у C ++.

  • Друкарські шрифти, заграновані більш строгим набором тексту, як правило, є лише хорошою справою, але в деяких випадках вони можуть вводити або приховувати помилки. Візьмемо приклад сумнозвісного анонсу результату від malloc (). Це слід вводити на C ++, але ніколи в C. (1)

  • Змішування функцій C і C ++ може призвести до помилок та не визначеної поведінки. Наприклад, не вийде виділити з malloc () та звільнити при видаленні . (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 - це, IMHO, хороша ідея. Таким чином люди починають розуміти обладнання, на яке вони пишуть програмне забезпечення.

Змішування цих двох мов не є хорошою ідеєю. Тому що ви отримуєте божевільну складність С ++ у поєднанні з подвійним подрібненням біт, загальним для С.

Як ви бачите, навіть у такому простому прикладі, як ваш, є проблеми синхронізації з різними типами потоків та внутрішньою буферизацією. Але також підхід C&C ++ не є більш гнучким у будь-якому випадку. Перейдіть до класу x, і немає операторів, які б використовували потокове та інше.

Це складно...

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

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

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

Класи обгортки RAII, шаблони, перевантаження, коректність const та чисті абстрактні класи для загальних інтерфейсів (не використовуйте тут f-ng Java-спосіб. ПРОСЯМО!) Хоча хороші кандидати. Тому що вони додають безпеку, загальність та простоту використання, які дуже важливі для реальних проектів. Не забудьте пам’ятати про такі речі, як віртуальне знищення, вибухова природа конструювання копій за замовчуванням, накладні витрати, правильність const тощо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.