возможные недостатки в программировании на языке C, включая * .c файлы - PullRequest
3 голосов
/ 20 июня 2009

Я наткнулся на некоторые коды следующим образом

//file.c  
#include <stdlib.h>

void print(void){

    printf("Hello world\n");
}

и

//file main.c  
#include <stdio.h>
#include "file.c"

int main(int argc, char *argv[]){

    print();

    return EXIT_SUCCESS;
}

Есть ли какой-либо недостаток в этом стиле программирования? Я не могу разобрать недостаток, хотя я так и чувствую, потому что где-то я читал, что разделение реализации на файлы * .h и * .c помогает компилятору проверять согласованность. Я не понимаю, что подразумевается под последовательностью.
Я был бы глубоко благодарен за некоторые предложения.

- спасибо

Ответы [ 11 ]

9 голосов
/ 20 июня 2009

Считается, что компилятор должен компилировать .c файлы. .h файлы не передаются компилятору напрямую. Они обычно включаются только в файлы .c.

Таким образом, ожидается, что ваш код будет скомпилирован следующим образом:

gcc main.c file.c 

, а не только gcc main.c. Эта команда потерпит неудачу на этапе компоновки, так как видит дублирующиеся символы.

9 голосов
/ 20 июня 2009

Ничто не мешает вам включать .c файлы. Однако разделение декларации (в файлах .h) и реализации (и файлов .c), а затем включение только файлов .h имеет несколько преимуществ:

  • Время компиляции. Ваша декларация обычно меняется меньше, чем ваша реализация. Если вы включаете только файлы .h и вносите изменения в свою реализацию (в файле .c), то вам нужно перекомпилировать только один файл .c вместо всех файлов, которые содержат измененный файл. *

  • Читаемость и управление интерфейсами. Все ваши объявления можно проверить одним взглядом на (обычно) небольшой файл .h, тогда как файл .c заполнен строками и строками кода. Более того, он помогает определить, какой файл видеть, какие функции и переменные. Например, чтобы избежать включения глобальной переменной там, где она вам не нужна.

6 голосов
/ 20 июня 2009

У вас будут проблемы, если вы включите файл file.c в несколько файлов исходного кода, которые объединятся в библиотеку / исполняемый файл, поскольку у вас будут дублированные реализации методов. Вышесказанное кажется мне плохим средством совместного использования / повторного использования кода, и не рекомендуется.

2 голосов
/ 20 июня 2009

Нередко включать данные в другой файл, если удобнее отделить их от кода. Например, XPM или необработанные данные BMP в массиве символов могут быть включены для встраивания изображения в программу таким способом. Если данные генерируются с другого этапа сборки, то имеет смысл включить файл.

Я бы предложил использовать другое расширение файла, чтобы избежать путаницы (например, * .inc, * .dat и т. Д.).

2 голосов
/ 20 июня 2009

Да, это разрешено.

Использование этой расширенной темы.

  • Это замедляет время компиляции разработки (дешевле компилировать только то, что необходимо).
  • Ускоряет время компиляции развертывания (все файлы устарели).
  • Позволяет компилятору встроить функции через границы модуля.
  • Позволяет управлять экспортируемыми символами из библиотеки, сохраняя ее модульность.
  • Это может запутать отладчик.
0 голосов
/ 23 июня 2009

Это нормально для программ этой длины.

0 голосов
/ 20 июня 2009

зло макросов может быть усугублено:

file1.c

#define bottom arse

file2.c

int f()
{
    int arse = 4;
    bottom = 3;
    printf("%d", arse);
}

main.c

#include "file1.c"
#include "file2.c"

void main()
{
    f();
}

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

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

0 голосов
/ 20 июня 2009

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

Обратите внимание, что это довольно зло, не рекомендуется, и будет производить код, который трудно отлаживать и поддерживать, но вы можете сделать что-то вроде следующего:

mytemplate.c:

MyTemplateFunction_ ## MYTYPE(MYTYPE x)
{
  // function code that works with all used TYPEs
}

main.c:

#define MYTYPE float
#include "mytemplate.c"
#undef MYTYPE

#define MYTYPE int
#include "mytemplate.c"
#undef MYTYPE

int main(int, char*)
{
  float f;
  int i;
  MyTemplateFunction_float(f);
  MyTemplateFunction_int(i);
  return 0;
}
0 голосов
/ 20 июня 2009

Есть только две причины, по которым я знаю, для включения файлов C (и которые имеют смысл):

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

Недостатки:

  • вы несколько раз компилируете один и тот же код
  • если не использовать экономно, это быстро приводит к множеству определенных символов для общедоступных символов способом, который трудно отладить (включая файлы, которые включают другие файлы ...)
0 голосов
/ 20 июня 2009

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

Но с точки зрения программиста, да, это странно. Большинство программистов будут работать в предположении, что файл .c не будет включен, и это может вызвать проблемы из-за неверных предположений. Лучше всего избегать этой практики. Если вы обнаружите, что должны его использовать, это признак плохого дизайна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...