Изучение C, когда Вы уже знаете C++?

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

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

Конкретно:

  1. Там широко пользуются библиотеки общего назначения, которые каждый программист C должен знать о (как повышение для C++)?
  2. Каковы самые важные идиомы C (как RAII для C++)?
  3. Я должен изучить C99 и использовать его или придерживаться C89?
  4. Какие-либо ловушки/прерывания для разработчика C++?
  5. Что-либо еще полезное для знания?
19
задан KeatsPeeks 18 February 2014 в 17:50
поделиться

10 ответов

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

Библиотека:

  • Я поставил это первым, потому что это на мой взгляд, это самая большая разница на практике. Стандартная библиотека C очень (!) Разрежена. Он предлагает минимум услуг. Что касается всего остального, вам нужно создать свою собственную или найти библиотеку для использования (и многие люди это делают). У вас есть файловый ввод-вывод и некоторые очень простые строковые функции и математика. Что касается всего остального, вам придется либо самостоятельно, либо найти библиотеку для использования. Я обнаружил, что при переходе с C ++ на C сильно скучаю по расширенным контейнерам (особенно картам), но есть много других.

Идиомы:

  • Оба языка имеют ручное управление памятью (ресурсами), но C ++ дает вам некоторые инструменты, чтобы скрыть необходимость. В C вы будете чаще отслеживать ресурсы вручную, и вам нужно к этому привыкнуть. Конкретными примерами являются массивы и строки (C ++ vector и string экономят вам много работы), интеллектуальные указатели (вы не можете использовать «интеллектуальные указатели» как таковые в C. может выполнять подсчет ссылок, но вы должны увеличивать и уменьшать количество ссылок самостоятельно, что очень чревато ошибками - причина, по которой интеллектуальные указатели были добавлены в C ++ в первую очередь), и отсутствие RAII в целом который вы заметите везде, если привыкли к современному стилю программирования на C ++.
    • Вы должны четко говорить о строительстве и разрушении. Вы можете спорить о достоинствах недостатков этого, но в результате получается гораздо более явный код.
  • Обработка ошибок. Исключения C ++ может быть сложно исправить, поэтому не все их используют, но если вы все же используете их, вы обнаружите, что вам нужно уделять много внимания тому, как вы делаете уведомление об ошибках. Необходимость проверять возвращаемые значения для всех важных вызовов (некоторые будут утверждать, что все вызовы) требует большой дисциплины, и большая часть кода C не делает этого.
  • Строки (и массивы в вообще) не носите с собой их размеры. Чтобы справиться с этим, вам нужно передать множество дополнительных параметров в C.
  • Без пространств имен вы должны тщательно управлять своим глобальным пространством имен.
    • Здесь нет явной привязки функций к типам, как в class в C ++. Вы должны придерживаться соглашения о добавлении префиксов ко всему, что вы хотите связать с типом.
  • Вы увидите намного больше макросов. Макросы используются в C во многих местах, где у C ++ есть языковые функции, которые делают то же самое, особенно символические константы (C имеет enum , но во многих более старых кодах вместо этого используется #define ), а также для дженерики (где C ++ использует шаблоны).

Совет:

  • Рассмотрите возможность поиска расширенной библиотеки для общего использования. Взгляните на GLib или APR .
    • Даже если вам не нужна полная библиотека, подумайте о поиске карты / словаря / хеш-таблицы для общего пользования. Также подумайте о том, чтобы объединить простой «строковый» тип, содержащий размер.
  • Привыкайте ставить префиксы модулей или «классов» на все публичные имена. Это немного утомительно, но избавит вас от многих головных болей.
  • Активно используйте прямое объявление, чтобы сделать типы непрозрачными. Если в C ++ у вас могут быть личные данные в заголовке и полагаться на private предотвращает доступ, в C вы хотите как можно больше помещать детали реализации в исходные файлы. (На самом деле, на мой взгляд, вы тоже хотите сделать это в C ++, но C упрощает это, поэтому это делают больше людей.)

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

     // Чхх
    класс C
    {
     общественность:
     void method1 ();
     int method2 ();
    
     частный:
     int value1;
     char * value2;
    };
    

    C помещает определение «класса» в исходный файл. Заголовок - это все предварительные объявления.

     // Ch
    typedef struct CC; // предварительное объявление
    
    void c_method1 (C *);
    интервал c_method2 (C *);
    
    // Копия
    структура C
    {
     int value1;
     char * value2;
    }; 
    
27
ответ дан 30 November 2019 в 02:20
поделиться

Glib является хорошей отправной точкой для современного C и позволяет вам привыкнуть к таким понятиям, как непрозрачные типы и полуобъектная ориентация, которые стилистически распространены в современном C. На другом конце спектра стандартные API POSIX являются добрыми. из «классического» C.

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

12
ответ дан 30 November 2019 в 02:20
поделиться

Рассмотрим ваши вопросы по порядку:

  1. К сожалению, нет ничего лучше Boost для C.
  2. Ничего подобного RAII тоже.
  3. Единственный компилятор, который пытается это сделать. реализация C99 - это Comeau.
  4. Боюсь, их много повсюду.
  5. Совсем немного. C придерживается совершенно другого мышления, чем C.

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

Есть много идиом, но многие из них связаны с тем, как вы редактируете свой код, например, имитируя RAII, быстро записывая fopen () и соответствующий fclose () , и только потом писать промежуточный код для обработки данных.

Ловушки / ловушки, которые ждут за каждым углом, в основном проистекают из отсутствия динамических структур данных, таких как строка и вектор, поэтому вам часто приходится писать такие вещи самостоятельно. Без перегрузки операторов, конструкторов и т. Д. Значительно сложнее сделать их действительно универсальными. Они есть во многих библиотеках, но в конечном итоге вы все равно катаетесь самостоятельно, потому что:

  1. библиотека делает не совсем то, что вы хотите, или
  2. использование библиотеки требует больше работы, чем она того стоит.

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

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

Edit (поскольку люди поднимают вопросы о поддержке C99): Хотя мое заявление об отсутствии поддержки C99 может показаться резким, факт в том, что это правда.

MS VC ++: поддерживает C95 и имеет несколько функций C99 (например, разделители комментариев в стиле C ++), в основном потому, что C99 стандартизировал то, что раньше было расширением.

Gnu: Согласно на странице C99 Features Status самая последняя итерация gcc (4.4) имеет некоторые функции C99, но некоторые (включая VLA) характеризуются как «сломанные», а другие как «отсутствующие». Некоторые из недостающих «функций» на самом деле являются целыми областями , а не отдельными функциями.

PCC: Сайт PCC заявляет о соответствии C99 только как цели на будущее, а не как

Embarcadero Technologies (урожденная Borland), похоже, вообще ничего не говорит о соответствии с C99 - судя по всему, последний раз они работали над компилятором C, возможно, еще до того, как был выпущен C99.

Microsoft открыто заявляет , что у них нет текущих планов поддержки C99, и они даже не собираются рассматривать это до выхода VS 2010. Хотя я не могу найти никаких публичных заявлений об этом, Embarcadero выглядит примерно так же: нет намека на текущий план и даже на то, что они собираются рассмотреть возможность работы над ним в ближайшее время.

Хотя кажется, что оба gcc и pcc иметь планы, в настоящее время это просто планы. Они оба открыто признают, что в настоящее время они даже не очень близки к тому, чтобы соответствовать C99.

re не собираюсь даже рассматривать это, пока не выйдет VS 2010. Хотя я не могу найти никаких публичных заявлений об этом, Embarcadero выглядит примерно так же: нет намека на текущий план и даже на то, что они собираются рассмотреть возможность работы над ним в ближайшее время.

Хотя кажется, что оба gcc и pcc иметь планы, в настоящее время это просто планы. Они оба открыто признают, что в настоящее время они даже не очень близки к тому, чтобы соответствовать C99.

re не собираюсь даже рассматривать это, пока не выйдет VS 2010. Хотя я не могу найти никаких публичных заявлений об этом, Embarcadero выглядит примерно так же: нет намека на текущий план и даже на то, что они собираются рассмотреть возможность работы над ним в ближайшее время.

Хотя кажется, что оба gcc и pcc иметь планы, в настоящее время это просто планы. Они оба открыто признают, что в настоящее время они даже не очень близки к тому, чтобы соответствовать C99.

4
ответ дан 30 November 2019 в 02:20
поделиться

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

2
ответ дан 30 November 2019 в 02:20
поделиться

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

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

Но не слушайте меня. . Я был слишком ленив и глуп, чтобы изучать C ++ :)

2
ответ дан 30 November 2019 в 02:20
поделиться

Что-нибудь еще полезно знать?

C99 - это не подмножество любой версии C ++, а отдельный язык.

2
ответ дан 30 November 2019 в 02:20
поделиться

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

1
ответ дан 30 November 2019 в 02:20
поделиться

Поскольку C ++ является почти надмножеством C89, вы уже должны знать почти весь C89. Вероятно, вы захотите сосредоточиться на различиях между C89 и C99.

0
ответ дан 30 November 2019 в 02:20
поделиться

Q5. Что-нибудь еще полезное?

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

6
ответ дан 30 November 2019 в 02:20
поделиться

Пожалуй, самым большим шоком, который я испытал, когда я вернулся к C, было то, что переменные определены на уровне функций - т.е. вы не можете переменные области видимости внутри блока (оператор if или цикл ) внутри функции.

1
ответ дан 30 November 2019 в 02:20
поделиться