как я могу получить имена файлов в папке в VBA? [Дубликат]

Это, вероятно, более подробный ответ, чем вы хотели, но я считаю, что оправдано обоснованное объяснение.

В C и C ++ один исходный файл определен как одна единица перевода . По соглашению файлы заголовков содержат объявления функций, определения типов и определения классов. Фактические реализации функций находятся в единицах трансляции, то есть .cpp-файлах.

Идея заключается в том, что функции и функции-члены класса / структуры скомпилированы и собраны один раз, а затем другие функции могут вызывать этот код из одного места без дублирования.

/* Function prototype, usually found in headers. */
/* Implicitly 'extern', i.e the symbols is visible everywhere, not just locally.*/
int add(int, int);

/* function body, or function definition. */
int add(int a, int b) 
{
   return a + b;
}

Если вы хотите, чтобы функция была локальной для единицы перевода, вы определяете ее как «статический». Что это значит? Это означает, что если вы включаете исходные файлы с внешними функциями, вы получите ошибки переопределения, потому что компилятор сталкивается с одной и той же реализацией более одного раза. Итак, вы хотите, чтобы все ваши единицы перевода отображали прототип функции, но не тело функции.

Итак, как все это получается в конце? Это работа линкера. Компонент считывает все объектные файлы, которые генерируются на этапе ассемблера и разрешает символы. Как я уже говорил, символ - это просто имя. Например, имя переменной или функции. Когда единицы перевода, которые вызывают функции или объявляют типы, не знают реализации этих функций или типов, эти символы считаются неразрешенными. Компоновщик разрешает неразрешенный символ, подключая блок перевода, который содержит неопределенный символ вместе с тем, который содержит реализацию. Уф. Это справедливо для всех внешне видимых символов, независимо от того, реализованы они в коде или предоставлены дополнительной библиотекой. Библиотека - это просто архив с многоразовым кодом.

Есть два примечательных исключения. Во-первых, если у вас есть небольшая функция, вы можете сделать ее встроенной. Это означает, что сгенерированный машинный код не генерирует вызов функции extern, а буквально конкатенируется на месте. Поскольку они обычно малы, размер накладных расходов не имеет значения. Вы можете представить, что они статичны в том, как они работают. Таким образом, безопасно реализовать встроенные функции в заголовках. Функциональные реализации внутри определения класса или структуры также часто компилируются автоматически.

Другим исключением являются шаблоны. Поскольку компилятор должен видеть определение всего шаблона при их создании, невозможно отделить реализацию от определения, как с автономными функциями, так и с обычными классами. Ну, возможно, это возможно сейчас, но получение широко распространенной поддержки компилятора для ключевого слова «экспорт» заняло много времени. Таким образом, без поддержки «экспорта» единицы перевода получают свои собственные локальные копии экземпляров и шаблонов с шаблонами, аналогичные тем, как работают встроенные функции. С поддержкой «экспорта» это не так.

Для двух исключений некоторые люди считают, что «лучше» помещать реализации встроенных функций, шаблонных функций и шаблонных типов в файлы .cpp, а затем # включить файл .cpp. Является ли это заголовком или исходным файлом, не имеет большого значения; препроцессор не заботится и является просто соглашением.

Краткое резюме всего процесса из кода C ++ (несколько файлов) и окончательного исполняемого файла:

  • Препроцессор , который анализирует все директивы, начинающиеся с символа '#'. Например, директива #include объединяет включенный файл с неполным. Он также выполняет макрозамен и токены.
  • Фактический компилятор работает в промежуточном текстовом файле после этапа препроцессора и испускает код ассемблера.
  • Ассемблер работает на сборке файл и испускает машинный код, это обычно называют объектным файлом и следует за двоичным исполняемым форматом соответствующей операционной системы. Например, Windows использует PE (переносимый исполняемый формат), в то время как Linux использует формат Unix System V ELF с расширениями GNU. На этом этапе символы по-прежнему отмечены как неопределенные.
  • Наконец, компоновщик запущен. Все предыдущие этапы выполнялись на каждой единицы перевода по порядку. Тем не менее, этап компоновщика работает на всех сгенерированных объектных файлах, которые были сгенерированы ассемблером. Компилятор разрешает символы и делает много магии, как создание разделов и сегментов, что зависит от целевой платформы и двоичного формата. Программистам не обязательно знать это в целом, но в некоторых случаях это наверняка помогает.

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

-10
задан Community 9 July 2018 в 19:34
поделиться