русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Списки аргументів довільної довжини


Дата додавання: 2014-11-28; переглядів: 891.


Цей розділ містить втілення мінімальної версії printf для демонстрації того, як написати функцію, яка би обробляла список аргументів довільної довжини у машинонезалежний спосіб. Оскільки ми, головним чином, зацікавлені в опрацьовуванні аргументів, minprintfоброблятиме форматувальний ланцюжок і аргументи, але викликатиме дійсний printf для перетворень формату. Чинним оголошенням printf є

int printf(char *fmt, ...)

де ... означає, що кількість і типи цих аргументів може відрізнятися. Оголошення ... може тільки з'являтися в кінці списку аргументів. Нашу minprintf оголошено як

void minprintf(char *fmt, ...)

оскільки ми не повертатимемо відлік символів, як це робить printf.

Делікатний момент полягає в тому, як minprintf просувається через список аргументів, в той час як сам список навіть не має імені. Стандартний файл заголовка <stdarg.h> містить набір макросів, який визначає, як проходити список аргументів. Втілення цього файла заголовка може відрізнятися на різних машинах, але інтерфейс, який він представляє є однорідним.

Тип va_list використовується для оголошення змінної, яка посилатиметься по-черзі до кожного аргументу; в minprintf ця змінна називається ap, як скорочення від "argument pointer" (покажчик на аргумент). Макрос va_start ініціалізує ap таким чином, щоб вона вказувала на перший безіменний аргумент. Макрос потрібно викликати один раз до того, як використовувати ap. Необхідно, щоб був щонайменше один аргумент з іменем; останній названий аргумент використовується va_start, щоб розпочати роботу.

Кожний виклик va_arg повертає один аргумент і переводить ap до наступного; va_argвикористовує назву типу, щоб визначити, який тип повернути і наскільки великим повинен бути крок. І, накінець, va_end здійснює очистку, якщо треба. Її потрібно викликати до того, як програма поверне своє значення.

Ці властивості складають базу для нашої спреощеної printf:

#include <stdarg.h>

 

/* minprintf: мінімальна printf зі списком аргументів *

* змінної довжини */

void minprintf(char *fmt, ...)

{

va_list ap; /* покажчик на кожний безімений аргумент *

* по черзі */

char *p, *sval;

int ival;

double dval;

 

va_start(ap, fmt); /* заставляє ap бути покажчиком *

* на 1-ий безіменний аргумент */

for (p = fmt; *p; p++) {

if (*p != '%') {

putchar(*p);

continue;

}

switch (*++p) {

case 'd':

ival = va_arg(ap, int);

printf("%d", ival);

break;

case 'f':

dval = va_arg(ap, double);

printf("%f", dval);

break;

case 's':

for (sval = va_arg(ap, char *); *sval; sval++)

putchar(*sval);

break;

default:

putchar(*p);

break;

}

}

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

}

Вправа 7-3. Виправіть minprintf так, щоб вона втілювала додаткові можливості printf.


<== попередня лекція | наступна лекція ==>
Форматований вивід - printf | Форматований ввід - scanf


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн