
- •Происхождение языка с
- •Язык среднего уровня
- •Структурированный язык
- •Язык программирования
- •Компиляторы против интерпретаторов
- •Вид программ на с
- •Библиотеки и компоновка
- •Раздельная компиляция
- •Карта памяти с-программы
- •Переменные, константы, операторы и выражения
- •Идентификаторы
- •Типы данных
- •Модификаторы типов
- •Модификаторы доступа
- •Объявление переменных
- •Локальные переменные
- •Формальные параметры
- •Глобальные переменные
- •Спецификаторы хранения
- •Статические переменные
- •Статические локальные переменные
- •Статические глобальные переменные
- •Регистровые переменные
- •Оператор присваивания
- •Многочисленное присваивание
- •Преобразование типов при присваивании
- •Инициализация переменных
- •Константы
- •Символьные константы с обратным слэшем
- •Операторы
- •Арифметические операторы
- •Увеличение и уменьшение
- •Операторы отношения и логические операторы
- •Битовые операторы
- •Оператор ?
- •Операторы указания & и *
- •Оператор sizeof
- •Оператор «запятая»
- •Операторы [ ] u ()
- •Приоритеты в с
- •Выражения
- •Преобразование типов в выражениях
- •Принудительные преобразования
- •Пробелы и круглые скобки
- •Сокращенные операторы в с
- •Операторы управления программой
- •Истина и ложь в с
- •Операторы выбора
- •Вложенные if
- •Лесенка if-else-if
- •Оператор ?
- •Вложенные операторы switch
- •Вариации цикла for
- •Бесконечный цикл
- •Циклы for без тела
- •Метки и goto
- •Функции
- •Оператор return
- •Выход из функции
- •Возвращаемые значения
- •Значения, возвращаемые функцией main()
- •Правила видимости для функций
- •Аргументы функции
- •Передача по значению и передача по ссылке
- •Создание передачи по ссылке
- •Передача массивов в функции
- •Аргументы функции main()
- •Функции, возвращающие нецелые значения
- •Использование прототипов функции
- •Прототипы стандартных библиотечных функций
- •Создание прототипов функций, не имеющих параметров
- •Возврат указателей
- •Рекурсия
- •Сопоставление классического и современного объявления параметров
- •Указатели на функции
- •Особенности реализации
- •Параметризированные функции и функции общего назначения
- •Эффективность
- •Массивы
- •Одномерный массив
- •Создание указателя на массив
- •Передача одномерных массивов в функции
- •Двумерные массивы
- •Массивы строк
- •Многомерные массивы
- •Индексация с помощью указателей
- •Размещение массивов
- •Инициализация массива
- •Инициализация безразмерных массивов
- •Пример программы игры в крестики-нолики
- •Указатели
- •Указатели - это адреса
- •Переменные-указатели
- •Операторы для работы с указателями
- •Выражения с указателями
- •Присваивание указателей
- •Арифметические действия с указателями
- •Сравнение указателей
- •Динамическое выделение и указатели
- •Указатели на константы
- •Указатели на константы
- •Указатели на константы
- •Указатели и массивы
- •Указатели на символьные массивы
- •Массивы указателей
- •Указатели на указатели - многочисленное перенаправление
- •Инициализация указателей
- •Указатели на функции
- •Проблемы, связанные с указателями
- •Структуры, объединения и определяемые пользователем типы
- •Структуры
- •Доступ к членам структуры
- •Присваивание структур
- •Массивы структур
- •Программа инвентаризации
- •Передача структур в функции
- •Передача членов структур в функции
- •Передача всей структуры в функцию
- •Указатели на структуры
- •Объявление указателя на структуру
- •Использование указателей на структуру
- •Массивы и структуры в структурах
- •Битовые поля
- •Объединения
- •Перечисления
- •Использование sizeof для обеспечения переносимости
- •Ввод, вывод, потоки и файлы
- •Потоки и файлы
- •Текстовые потоки
- •Двоичные потоки
- •Консольный ввод/вывод
- •Чтение и запись символов
- •Чтение и запись строк: gets() и puts()
- •Форматированный консольный ввод/вывод
- •Печать символов
- •Вывод чисел
- •Вывод адресов
- •Спецификатор %n
- •Модификаторы формата
- •Спецификатор минимума ширины поля
- •Спецификатор точности
- •Выровненный вывод
- •Работа с другими типами данных
- •Модификаторы * u #
- •Спецификаторы формата
- •Ввод чисел
- •Ввод беззнаковых целых
- •Чтение отдельных символов с помощью scanf()
- •Чтение строк
- •Ввод адреса
- •Спецификатор %n
- •Использование множества сканирования
- •Пропуск нежелательных специальных символов
- •Обычные символы в управляющей строке
- •В scanf() следует передавать адреса
- •Модификаторы формата
- •Подавление ввода
- •Файловая система ansi с
- •Указатель на файл
- •Открытие файла
- •Запись символа
- •Чтение символа
- •Использование fopen(), getc(), putc() и fclose()
- •Использование feof()
- •Две расширенные функции: getw() и putw()
- •Работа со строками: fgets() и fputs()
- •Fseek() и произвольный доступ
- •Удаление файлов
- •Работа с консолью
- •Препроцессор и комментарии
- •Директивы условной компиляции
- •Использование defined
- •Операторы препроцессора # и ##
- •Предопределенные макросы
- •Комментарии
Использование defined
Помимо #ifdef существует второй способ узнать, определен ли макрос. В сочетании с директивой #if можно использовать оператор времени компиляции defined. Оператор defined имеет следующий вид: defined имя_макроса
Если имя_макроса определено, то выражение становится истинным. В противном случае оно становится ложным. Например, для того, чтобы узнать, определен ли макрос MYFILE, можно использовать одну из двух команд препроцессора: #if defined MYFILE или #ifdef MYFILE
Перед defined можно также поместить ! для изменения состояния. Например, следующий фрагмент компилируется, только если DEBUG не определен. #if ! defined DEBUG printf ("Final version!\n"); #endif
#line
Директива #line используется для изменения содержимого __LINE__ и __FILE__, являющихся предопределенными макросами. __LINE__ содержит номер компилируемой строки, а __FILE__ имя компилируемого файла. Стандартный вид команды #line следующий: #line число "имя_файла"
где число - это любое положительное число, а необязательный параметр имя_файла является любым допустимым файловым идентификатором. Номер строки заносится в __LINE__, а имя файла — в __FILE__. #line предназначена для отладочных целей и специальных приложений.
Например, следующая директива определяет, что отсчет строк будет начинаться со 100. Оператор printf() выводит число 102, поскольку он стоит в третьей строке программы после оператора #line. #include <stdio.h> #line 100 /* переустановка счетчика строк*/ int main(void) /* строка 100 */ { /* строка 101 */ printf ("%d\n",__LINE__); /* строка 102 */ return 0; }
#pragma
Директива #pragma определяется стандартом ANSI С для реализации директив, предоставляющих компилятору различные инструкции. Стандартный вид #pragma следующий: #pragma имя
где имя — это имя директивы #pragma. Borland определяет 14 директив #pragma: argused anon_struct codeseg comment exit hdrfile hdrstop inline intrinsic message option saveregs startup warn
Директива argused должна стоять перед функцией. Она используется для устранения предупреждений, если аргумент функции, перед которой стоит #pragma, не используется в теле функции.
Чтобы разрешить использовать анонимные структуры, укажите директиву anon_struct. С помощью директивы codeseg можно указать сегмент, класс или группу, используемую функцией.
Используя директиву comment, в выходной файл, например, в файл с расширением obj или ехе можно поместить комментарии.
Директива exit определяет одну или несколько функций, вызываемых при завершении программы. Директива startup определяет одну или несколько функций, вызываемых при запуске программы. Они имеют следующий вид: #pragma exit имя_функции приоритет #pragma startup имя_функции приоритет
Приоритет — это значение от 64 до 255 (значения от 0 до 63 зарезервированы). Приоритет определяет порядок вызова функций. Если приоритет не указан, то по умолчанию предполагается значение 100. Все функции, выполняющиеся в начале или конце программы, должны объявляться следующим образом: void f(void);
Следующий пример определяет функцию start(), выполняющуюся в начале программы. #include <stdio.h> void start(void); #pragma startup start 65 int main(void) { printf("In main\n"); return 0; } void start (void) { printf("In start\n"); }
В результате работы программы на экране появится: In start In main
Как показывает данный пример, необходимо предоставить прототип функции до использования директивы #pragma.
С помощью директивы hdrfile можно определить имя файла, используемого для хранения пред- компилированных заголовочных файлов. Он имеет вид #pragma hdrfile "имя_файла. csm"
где имя_файла — это имя файла (с расширением csm).
Директива hdrstop сообщает Borland С++ о необходимости остановить предкомпиляцию заголовочных файлов.
Также имеется директива inline, имеющая следующий вид: #pragma inline
Она сообщает компилятору, что программа содержит внутренний ассемблерный код. При создании самого быстрого кода компилятор должен знать, что в программе содержится ассемблерный код.
Используя директиву intrinsic, можно указать компилятору на необходимость подстановки кода функции вместо ее вызова. Директива имеет вид: #pragma intrinsic имя_функции
где имя_функции — это имя функции, которую необходимо сделать внутренней.
Если выбрать опцию Inline Intrinsic Function в ИСР (интегрированной среде разработчика) или воспользоваться опцией -Oi при компиляции с помощью строчного компилятора, то Borland автоматически сделает внутренними следующие функции: alloca memcpy stpcpy strcpy strncpy fabs memset strcat strlen strnset memchr rotl strchr strncat strrchr memcmp rotr strcmp strncmp
Воспользовавшись директивой intrinsic, можно отменить функции, которые станут внутренними: #pragma intrinsic имя_функции
Директива message позволяет определить сообщение, выводимое в качестве предупреждения при компиляции программы. Например: #include <stdio.h> #pragma message This will be displayed as a warning. int main(void) { int i=10; printf ("This is i: %d\n", i); #pragma message This is also displayed as a warning. return 0; }
При компиляции появятся два сообщения #pragma, выводящиеся в качестве предупреждений. При использовании ИСР они появятся в стандартном окне сообщений.
Директива option позволяет определить опции командной строки вместо того, чтобы данные опции явно указывать в командной строке. Она имеет следующий вид: #pragma option список_опций
Например, следующая директива приводит к тому, что содержащая ее программа будет компилироваться в модели large: #pragma option -ml
Следующие опции не могут использоваться с директивой option: -В -с -D -е -Е -F -h -l -М -о -Р -Q -S -Т -U -V -X -Y
Для использования некоторых опций директива option должна стоять перед любыми объявлениями, включая прототипы функций. Поэтому имеет смысл помещать данную директиву самой первой.
Директива saveregs запрещает функции, объявленной как huge, изменять какие-либо регистры. Данная директива должна стоять перед функцией, и она влияет только на функцию, перед которой стоит.
Директива warn позволяет запретить или разрешить различные предупреждения. Она имеет вид: #pragma warn установки
где установки — это опции для определения предупреждений.