теория-билеты экзамен по информатике. Система счисления это совокупность приемов и правил, по которым числа записываются и читаются
Скачать 144.81 Kb.
|
{ int i; for (i = 1; i <= argc; i++) printf("%s%c", argv[i], (i < argc-1) ? ' ' : '\n'); } Поместив теперь загрузочный модуль этой программы в файл echo.exe и обратившись к ней при помощи команды C:\> echo first second third получим на экране терминала такое сообщение first second third C:\> Поскольку массив указателей в определенном смысле эквивалентен "указателю на указатель", мы могли бы определить переменную argv в заголовке функции main() как косвенный указатель типа char : char **argv; что полностью равносильно предыдущему описанию. В этих терминах наша программа echo могла бы выглядеть, например, следующим образом: #include main(int argc, char **argv) { while (--argc > 0) printf((argc > 1) ? "%s " : "%s\n", *++argv); } где выражение ++argv увеличивает на единицу значение указателя, заставляя его ссылаться на очередную строку, полученную от командного процессора Билет 15, 28 Внешние объекты программы (extern). Статические переменные и функции (static). Регистровые переменные (register). Объекты, описанные внутри функции с добавлением класса памяти extern или описанные вне функции без указания класса памяти, относятся к внешним. Внешние объекты хранятся вне любой функции, входящей в состав программы, и существуют в течение выполнения всей программы.Они могут быть использованы для передачи значений между различными, в том числе и отдельно компилируемыми, функциями.Сами функции также являются внешними объектами, поскольку правила языка Си не позволяют определять одни функции внутри других. Внешние переменные можно инициализировать только выражения с константами и указателями на ранее описанные объекты. По умолчанию(если не задана инициализация) внешние объекты получают нулевые начальные значения. Внешние объекты делятся на внешние глобальные и внешние статические. Важно различать описание внешнего объекта и его определение. Описание указывает свойство объекта( тип, размер, и т. д.); определение же вызывает еще и отведение памяти установке начального значения, если используется инициализация. Указание static, примененное к внешней переменной или функции, ограничивает область видимости соответствующего объекта концом файла. Это способ скрыть имена. Статическая память специфицируется словом static, которое помещается перед обычным объявлением. Если рассматриваемые нами две функции и две переменные компилируются в одном файле, то никакая другая программа не будет иметь доступ ни к этим переменным, и этими именами можно свободно пользоваться в других файлах для совсем иных целей. Точно так же, помещая указание static перед объявлениями переменных, с которыми работают только push и pop( для стека), мы можем скрыть их от остальных функций. Указание static чаще всего используется для переменных, но с равным успехом его можно применять и к функциям. Обычно имена функций глобальны и видимы из любого места программы. Если же функция помечена словом static, то ее имя становится невидимым вне файла, в котором она определена. Объявление static можно использовать и для внутренних переменных. Как и автоматические переменные, внутренние статические переменные локальны в функциях, но в отличие от автоматических, они не возникают только на период работы функции, а существуют постоянно. Это значит, что внутренние статические переменные обеспечивают постоянное сохранение данных внутри функции. Объекты, описанные внутри блока с классом памяти register, называются регистровыми переменными. Они подчиняются всем правилам, касающимся автоматических переменных. Описание register указывает компилятору, что данная переменная будет часто использоваться. Описание может выглядеть, например, так: register int n; register char c; register int *px; Использование регистровых переменных приводит к меньшим по размерам и более быстрым программам. Компилятор C++ автоматически выполняет оптимальное распределение регистров в соответствии с потоком данных. Этим снята необходимость обязательного указания переменных программы как регистровых, так что описание register идентично по смыслу описанию auto и никакого другого смысла не имеет. Регистровый класс памяти могут иметь только простые переменные (char, int, указатели и т.д.). Регистровые переменные инициализируются каждый раз при входе в функцию или блок. Для регистровых переменных инициализирующее выражение не обязательно должно быть константой: оно может быть любым выражением, включающим определенные ранее величины и обращения к функциям. Если явная инициализация отсутствует, то регистровые переменные имеют в таком случае неопределенные значения. Следует заметить, что не обязательно все регистровые переменные будут действительно храниться в регистрах. Компилятор должен сравнить ваши требования с количеством доступных регистров, поэтому вы можете и не получить то, что хотите. В этом случае переменная становится простой автоматической. К регистровым переменным не может быть применена операция "&" (получения адреса), таким образом, если в программе не используются адреса некоторых переменных, то эффективнее использовать для этих переменных регистры. Таким образом, класс памяти определяет область действия переменной и продолжительность ее существования в памяти. Класс памяти устанавливается при описании переменной с соответствующим ключевым словом. Переменные, определенные вне функции, являются автоматическими и локальными, если только не используются другие ключевые слова. Внешние переменные, определенные раньше функции, доступны ей, даже если не описаны внутри ее. Билет 16, 27 Препроцессор языка Си. (#define #undef #include #if, #ifdef, #ifndef, #else, #elif и #endif) Написать на языке "С" или "С++" функцию, удовлетворяющую следующим требованиям, вызвать ее в программе main( ) Прототип: int f( int *a, int n ); Параметры: a - указатель исходного массива, n - pазмеp исходного массива. Назначение: в исходном массиве все элементы, встречающиеся больше одного раза заменить на нули. Директива #define Эта директива, позволяющая присваивать текстовым строкам символические имена, может иметь один из следующих форматов: #define identifier или #define identifier(parameter-list) где угловыми скобками (< >) обозначена необязательная часть конструкций Замена выполняется лишь для отдельно стоящих имен и не имеет места в тех случаях, когда identifier входит в состав текстовых строк или является составной частью более длинного идентификатора Список аргументов parameter-list включает в себя один или большее число формальных параметров, разделенных запятыми и имеющих уникальные имена. В этом случае препроцессор заменяет имена параметров, входящие в text, именами соответствующих фактических аргументов, и лишь после этого будет выполнена реальная подстановка текста на место идентификатора Символьная строка text может иметь произвольную длину, возможно даже превосходящую длину одной строки экрана Для формирования длинного текста необходимо набрать символ \, нажать клавишу Enter и продолжить ввод символов с начала новой экранной строки С другой стороны, параметр text может вообще отсутствовать в составе директивы, что соответствует определению идентификатора identifier без присвоения ему какого-либо конкретного значения 1. Наиболее характерным применением этой директивы является назначение символических имен констант: #define WIDTH 100 #define LENGTH (WIDTH + 30) Здесь идентификатор WIDTH объявлен числовой константой, равной 100, а имя LENGTH определено при помощи WIDTH и целого числа 30, причем круглые скобки во втором случае являются существенными Директива #undef Данная директива имеет формат #undef identifier и заставляет препроцессор игнорировать все последующие вхождения определенного ранее в инструкции #define имени identifier Это позволяет ограничить область исходной программы, в пределах которой identifier обрабатывается препроцессором и имеет специальное значение В следующум примере область действия идентификаторов WIDTH и ADD ограничена лишь частью исходного файла, в пределах которой они принимаются во внимание препроцессором языка Си: #define WIDTH 100 #define ADD(x, y) (x) + (y) ... #undef WIDTH #undef ADD ... Инструкция #undef может быть помещена в произвольное место файла, содержащего исходный текст программы Директива #include Формат этой директивы в общем случае определяется следующей схемой: #include "pathname" или #include где угловые скобки (<>) являются составной частью конструкции. Здесь pathname есть правильное имя файла в смысле операционной системы Директива #include позволяет включать текст файла с именем pathname в состав файла, содержащего обращение к этой директиве Если pathname задает полное имя файла от корневого каталога, то две приведенные выше формы записи директивы эквивалентны В том же случае, когда задано относительное имя файла, использование двойных кавычек ( " " ) заставляет препроцессор прежде всего искать требуемый файл в текущем каталоге, затем просматривать каталог, определенный в команде вызова компилятора и, наконец, в случае необходимости продолжить поиск в стандартном каталоге Однако при заключении имени файла в угловые скобки текущий каталог не просматривается Препроцессор допускает последовательные вложения инструкций #include максимально до десяти уровней. Это означает, что всякий файл, подключаемый с помощью этой директивы, может содержать внутри себя новое обращение к #include В составе исходного текста программы директива #include может размещаться в произвольном месте содержащего ее файла Директивы #if, #ifdef, #ifndef, #else, #elif и #endif Директивы #if, #ifdef, #ifndef, #else, #elif и #endif используются для условной избирательной компиляции различных фрагментов программы Главная идея состоит в том, что если выражение, стоящие после директив #if, #ifdef и #ifndef, оказывается истинным, то будет скомпилирован код, расположенный между одной из этих трех директив и директивой #endif. В противном случае данный код будет опущен Директива #endif используется для обозначения конца блока Директиву #else можно использовать с любой из перечисленных выше директив для предоставления альтернативного варианта компиляции Общая форма записи директивы #if: #if константное выражение Если константное_выражение является истинным, будет скомпилирован код, расположенный непосредственно за этой директивой Общая форма записи директивы #ifdef: #ifdef имя_макроса Если имя_макроса определено в операторе #define, то будет скомпилирован блок кода, следующий за оператором #ifdef С помощью директив #if и #elif и оператора препроцессорной обработки #defined можно также выяснить, определено ли имя конкретного макроса директивой препроцессора #define. Для этого используется следующая общая форма записи: #if defined имя_макроса последовательность операторов #endif Если имя_макроса определено, последовательность_операторов будет скомпилирована. В противном случае она будет опущена Оператор #defined можно также предварить оператором отрицания (!), и тогда условная компиляция будет выполнена в том случае, если заданное имя макроса не определено Общая форма записи #ifndef имя_макроса: #ifndef имя_макроса Если имя_макроса не определено в операторе #define, то будет скомпилирован блок кода, следующий за оператором #ifndef #ifndef HDR #define HDR /* здесь содержимое hdr.h */ #endif Общая форма записи директивы #elif: #elif выражение_константа Данная директива используется для создания оператора if-else-if Для обработки сразу нескольких альтернатив можно использовать ряд директив #elif |