Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015

Тут можно читать онлайн Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - бесплатно полную версию книги (целиком) без сокращений. Жанр: Прочая старинная литература, издательство Вильямс, год 0101. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - описание и краткое содержание, автор Стивен Прата, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать книгу онлайн бесплатно, автор Стивен Прата
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Поскольку эти функции предназначены для работы с любым типом данных, два их аргумента имеют тип указателя на void. В С разрешено присваивать указателю типа void* указатель любого типа. Оборотная сторона такой гибкости состоит в том, что функции не способны распознавать, какого типа данные копируются. Поэтому в них присутствует третий аргумент, задающий количество копируемых байтов. Обратите внимание, что для массива количество байтов в общем случае не совпадает с количеством элементов. Таким образом, при копировании массива из 10 значений double в качестве третьего аргумента должно применяться выражение 10*sizeof (double), а не 10.

В листинге 16.20 показаны некоторые примеры использования этих двух функций. В нем предполагается, что тип double имеет в два раза больший размер, чем int, и для проверки этого предположения применяется средство _Static_assert из С11.

Листинг 16.20. Программа mems. с

708 глава 16 Вот как выглядит вывод Использование memcpy значения - фото 522

708 глава 16

Вот как выглядит вывод Использование memcpy значения исходные данные - фото 523

Вот как выглядит вывод:

Использование memcpy(): значения (исходные данные):

123456789 10

целевые данные (копия значений):

123456789 10

Использование memmove() с перекрывающимися областями: значения -- элементы 0-5 скопированы в элементы 2-7:

1 2 1 2 3 4 5 8 9 10

Использование memcpy() для копирования double в int: целевые данные -- 5 значений double в 10 позициях int:

0 1073741824 0 1091070464 536870912

1108516959 2025163840 1143320349 -2012696540 1179618799

Последний вызов memcpy() копирует данные из массива типа double в массив типа int. Это демонстрирует тот факт, что функция memcpy() ничего не знает, дай не заботится, о типах данных; она просто копирует байты из одной области в другую. (Вы могли бы, к примеру, копировать байты из структуры в массив символов.) Кроме того, никакого преобразования данных не происходит. Если организовать цикл, выполняющий поэлементное присваивание, то значения типа double будут преобразованы в тип int. В этом случае байты копируются в том виде, как есть, и программа затем интерпретирует комбинации битов, как если бы они имели тип int.

Препроцессор и библиотека С 709

Переменное число аргументов: файл stdarg.h

Ранее в этой главе обсуждались макросы с переменным числом аргументов. Заголовочный файл stdarg.h предоставляет похожую возможность для функций. Однако использовать ее немного сложнее. Вы должны выполнить следующие действия.

1. Подготовить прототип функции, в котором применяется троеточие.

2. Создать в определении функции переменную типа va_list.

3. Использовать макрос для инициализации этой переменной списком аргументов.

4. Применить макрос для доступа к списку аргументов.

5. Использовать макрос для очистки.

Давайте рассмотрим эти действия более подробно. Прототип для функции подобного рода должен иметь список, содержащий, по крайней мере, один параметр, за которым следует троеточие:

void f 1 (int n, ...); // допустимо

int f2(const char * s, int k, ...); // допустимо

char f3(char cl, char c2); // недопустимо, троеточие не в конце

double f3(...); /./ недопустимо, параметры отсутствуют

Крайний справа параметр (предшествующий троеточию) играет специальную роль; для его обозначения в стандарте используется термин parmN. В предшествующих примерах роль parmN играл параметр n в первом случае и к — во втором. Фактическим аргументом, передаваемым этому параметру, является количество аргументов, которые представлены разделом троеточия. Например, прототипироваиную ранее функцию fl() можно вызывать следующим образом:

f1 (2, 200, 400); //2 дополнительных аргумента

f1 (4, 13, 117, 18, 23); // 4 дополнительных аргумента

Тип va_list, объявленный в заголовочном файле stdargs.li, представляет объект данных, применяемый для хранения параметров, которые соответствуют разделу троеточия в списке параметров. Начало определения функции с переменным числом аргументов выглядит примерно так:

double sum(int lim,...)

{

va_list ар; // объявление объекта для хранения аргументов

В этом примере lim является параметром parmN и указывает количество аргументов в списке переменных-аргументов.

Затем функция будет использовать макрос va start(), также определенный в stdargs.li, для копирования списка аргументов в переменную va_list. Макрос принимает два аргумента: переменную va_list и параметр parmN. Продолжая предыдущий пример, переменная va list названа ар, а параметру parmN назначено имя lim, так что вызов будет иметь следующий вид:

va_start(ар, lim); // инициализация ар списком аргументов

На следующем этапе производится доступ к содержимому списка аргументов. Эго предусматривает применение еще одного макроса, va_arg(), который принимает два аргумента: переменную типа va list и имя типа. При первом вызове он возвращает первый элемент списка, при следующем вызове — следующий элемент списка и т.д.

710 Глава 16

Например, если первым аргументом в списке был double, а вторым — int, вы мог ли бы поступить так:

Но будьте внимательны Тип аргумента на самом деле должен соответствовать - фото 524

Но будьте внимательны. Тип аргумента на самом деле должен соответствовать спецификации. Если первым аргументом является 10.0, предыдущий код для tic работает нормально. Однако если аргументом оказывается 10, код может не заработать; автоматическое преобразование double в int, предпринимаемое для операции присваивания, здесь не происходит.

Наконец, вы должны провести очистку с помощью макроса va_end(). Например, может понадобиться освободить память, динамически выделенную для хранения аргументов. Этот макрос принимает в качестве аргумента переменную va_list:

va_end(ap); // очистка

После этого переменная ар может оказаться непригодной к употреблению до тех пор, пока вы не инициализируете ее повторно посредством макроса va_start.

Поскольку макрос va_arg() не обеспечивает копирование предыдущих аргументов для их возможного восстановления, может оказаться целесообразным сохранение копии переменной va list. Для этой цели в стандарте С99 предусмотрен макрос по имени va copy(). Он принимает два аргумента типа va list и копирует второй аргумент в первый:

На данном этапе попрежнему можно извлечь первые два элемента из арсору - фото 525

На данном этапе по-прежнему можно извлечь первые два элемента из арсору, несмотря на то, что они были удалены из ар.

В листинге 16.21 приведен краткий пример использования этих возможностей для создания функции, которая суммирует переменное число аргументов; здесь первым аргументом sum() является количество суммируемых элементов.

Листинг 16.21. Программа varargs.c

Препроцессор и библиотека С 711 Ниже показаны результаты пробного запуска - фото 526

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Стивен Прата читать все книги автора по порядку

Стивен Прата - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Язык программирования C. Лекции и упражнения (6-е изд.) 2015 отзывы


Отзывы читателей о книге Язык программирования C. Лекции и упражнения (6-е изд.) 2015, автор: Стивен Прата. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x