Файл не должен быть исполняемым что значит?

6 ответов на вопрос “Файл не должен быть исполняемым что значит?”

  1. Sadar Ответить


    Задумаемся, каким образом в представленной выше программе функция main() «узнает» о существовании функций l2r() и r2l(). Ведь в исходном коде файла main.c нигде не указано, что мы подключаем файл superprint.c, содержащий эти функции. Действительно, если попытаться получить из main.c отдельный исполняемый файл, т.е. скомпилировать программу без superprint.c:
    gcc main.c
    , то ничего не получиться. Компилятор сообщит об ошибке вызова неопределенных идентификаторов. Получить из файла superprint.c отдельный исполняемый файл вообще невозможно, т.к. там отсутствует функция main(). А вот получить из этих файлов отдельные объектные файлы можно. Представим, что одни объектные файлы как бы «выставляют наружу» имена определенных в них функций и глобальных переменных, а другие — вызовы этих имен из тел других функций. Дальше объектные файлы «ожидают», что имена будут связаны с их вызовами. Связывание происходит при компиляции исполняемого файла из объектных.

    Создание заголовочных файлов

    Продолжим разбирать приведенную выше программу. Что будет, если в функции main()осуществить неправильный вызов функций l2r() и r2l()? Например, указать неверное количество параметров. В таком случае создание объектных файлов пройдет без ошибок, и скорее всего удастся получить исполняемый файл; но вот работать программа будет неправильно. Такое возможно потому, что ничего не контролирует соответствие вызовов прототипам (объявлениям) функций.
    Куда правильней сообщать о неверном вызове функций уже при получении объектного файла. Поэтому хотя можно обойтись и без этого, но очень желательно сообщать функции main()прототипы функций, которые из нее вызываются. Это можно сделать, прописав объявления функций в файле main.c:
    … void l2r (char **c, int n); void r2l (char **c, int n);   main () { …
    Теперь, если мы передадим неправильные параметры, ошибка возникнет уже на этапе получения объектных файлов.
    А теперь представим, что программа у нас несколько больше и содержит десяток файлов исходного кода. Файл aa.c требует функций из файла bb.c, dd.c, ee.c. В свою очередь dd.c вызывает функции из ee.c и ff.c, а эти два последних файла активно пользуются неким файлом stars.c и одной из функций в bb.c. Программист замучится сверять, что чего вызывает откуда и куда, где и какие объявления надо прописывать. Поэтому все прототипы (объявления) функций проекта, а также совместно используемые символические константы и макросы выносят в отдельный файл, который подключают к каждому файлу исходного кода. Такие файлы называются заголовочными; с ними мы уже не раз встречались. В отличие от заголовочных файлов стандартной библиотеки, заголовочные файлы, которые относятся только к вашему проекту, при подключении к файлу исходного кода заключаются в кавычки, а не скобки. Об этом упоминалось в предыдущем уроке.
    Итак, более грамотно будет не добавлять объявления функций в файл main.c, а создать заголовочный файл, например, myprint.h и поместить туда прототипы функций l2r() и r2l(). А в файле main.c следует прописать директиву препроцессора:
    #include “myprint.h”
    В принципе смысла подключать myprint.h к файлу superprint.c в данном случае нет, т.к. последний не использует никаких сторонних функций, кроме стандартной библиотеки. Но если планируется расширять программу и есть вероятность, что в файле superprint.c будут вызываться сторонние для него функции, то будет надежней сразу подключить заголовочный файл.
    Обратим внимание еще на один момент. Стоит ли в описанном в этом уроке примере выносить константу N в заголовочный файл? Здесь нельзя дать однозначный ответ. Если ее туда вынести, то она станет доступна в обоих файлах, и поэтому можно изменить прототипы функций так, чтобы они принимали только один параметр (указатель), а значение N будет известно функциям их заголовочного файла. Однако стоит ли так делать? В функции r2l() второй параметр изменяется в процессе ее выполнения, что делать с константой будет невозможно. Придется переписывать тело функции. Кроме того, вдруг в последствии нам захочется использовать файл superprint.c в другом проекте, где будут свои порядки, и константы N в заголовочном файле не найдется.
    В таком случае лучше N не выносить в заголовочный файл. Хотя имейте в виду, в каких-то проектах символическая константа может использоваться так часто и во множестве функций, что ее будет лучше поместить в заголовочный файл.

    Особенности использования глобальных переменных

    Помните, если можно отказаться от использования глобальных переменных, то лучше это сделать. Желательно стремиться к тому, чтобы любой файл проекта, скажем так, «не лез к соседу за данными, а сосед не разбрасывал эти данные в виде глобальных переменных». Обмен данными между функциями должен осуществлять за счет передачи данных в качестве параметров и возврата значений с помощью оператора return. (Массивов это не касается.)
    Однако в языке программирования C есть проблема. С помощью return можно вернуть только одно значение. Но могут быть случаи, когда функция должна изменить несколько переменных (здесь не имеются ввиду элементы массива). В таком случае без глобальных переменных обойтись сложно.
    Если в файле aa.c объявлена переменная за пределами любой функции (например, так: intcount), то она является глобальной для всех файлов проекта. Чтобы получить значение этой переменной в файле aa.c достаточно просто указать ее имя (если в функции нет локальной переменной с тем же именем). Чтобы получить значение из других файлов, надо указать, что имеется в виду глобальная переменная, а не локальная. Делается это с помощью ключевого слова extern (например, extern count).
    Бывают ситуации, когда в одном файле для нескольких содержащихся в нем функций нужна глобальная переменная. Но эта переменная не должна быть доступна функциям, содержащимся в других файлах. В таком случае глобальная переменная объявляется с ключевым словом static (например, static int count). Тем самым мы как бы скрываем глобальную переменную.
    Задание
    Напишите простые наглядные примеры, использования глобальных функций:
    Объявите глобальную переменную в одном файле, а получите ее значение в другом файле (выведите на экран).
    Объявите в одном файле статическую глобальную переменную. Выведите ее значение на экран из функции данного файла. Попытайтесь сделать это из функции другого файла.
    Создайте две глобальные переменные в одном файле. В другом файле напишите функцию, которая меняет их значение.
    Курс с решением части задач:
    android-приложение, pdf-версия.
    Источник: younglinux.info

  2. VNIkaю В AlKogolь Ответить

    Исполняемыми файлами
    называются файлы, содержащие в себе
    готовые к запуску компьютерные
    программы.

    Исполняемый файл –
    словосочетание, довольно часто
    встречающееся, в основном, в
    документации. В живом общении (в том
    числе и в виртуальном) для
    обозначения данного вида файлов
    пользователи используют менее
    громоздкие термины, более точно
    отражающие, что именно они имеют в
    виду.
    Итак, что же скрывается за этим
    словосочетанием? Исполняемыми
    файлами называются файлы,
    содержащие в себе готовые к запуску
    компьютерные программы. В
    зависимости от того, в каком виде
    записана программа в исполняемом
    файле, выделяют две большие
    подгруппы файлов данного класса.
    Первая подгруппа – это бинарные
    файлы; они содержат в себе запись
    программы в виде специальных
    машинных кодов, которые, чаще всего,
    передаются непосредственно
    процессору. Такие файлы ещё
    сокращённо называют бинарниками. В
    противоположность им существуют
    исполняемые файлы, в которых
    программа записана в виде текста –
    то есть, в том самом виде, в каком с
    ней работал создавший её
    программист. Такие исполняемые
    файлы называют скриптами. Также
    этот термин нередко употребляют и
    по отношению к самим программам,
    которые хранятся в подобных файлах.
    Для выполнения программ из
    большинства бинарных исполняемых
    файлов достаточно только
    операционной системы, которая их
    поддерживает. Для выполнения
    скриптов нужен интерпретатор,
    который будет переводить текст
    программы последовательно в
    процессорные команды. Для запуска
    некоторых исполняемых файлов
    бинарного формата также нужны
    интерпретаторы.
    В Windows наиболее распространены
    бинарные исполняемые файлы. Самый
    часто встречающийся их вид – это
    приложение. Приложения имеют
    расширения EXE и могут запускаться
    самостоятельно. Помимо них,
    существуют динамические
    библиотеки (их расширение – DLL),
    которые содержат в себе общие для
    разных приложений функции. Ещё есть
    драйверы (DRV или VXD) – специальные
    программы, нужные для того, чтобы
    система могла взаимодействовать с
    конкретными моделями тех или иных
    устройств. Исполняемые файлы (в Windows
    особенно) могут зависеть друг от
    друга: например, для запуска любого
    приложения нужны определённые
    системные динамические библиотеки,
    а им, в свою очередь, нужны драйверы.

  3. VideoAnswer Ответить

  4. VideoAnswer Ответить

  5. VideoAnswer Ответить

Добавить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *