|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|
Как перенести параметры из ф-ции printf() в самодельную04.06.2011, 09:22. Показов 24701. Ответов 104
Метки нет (Все метки)
Ребят, подскажите как решить задачу.
Нужно перенести параметры функции printf() в самодельную ф-цию myfunk(). При условии если булева переменная Х==1. Если не равна 1, то не переносить. Задача осложняется тем, что число параметров ф-ции может быть переменным. Подскажите пожалуйста, буду очень признателен.
0
|
|
| 04.06.2011, 09:22 | |
|
Ответы с готовыми решениями:
104
Как перенести параметры с XP на 7
Параметры printf |
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|||||||
| 04.06.2011, 16:00 [ТС] | |||||||
|
Собственно, чтобы более понятно было, мне нужно добавить в этот код ( это код для примера работы с функцией printf()):
В общем сильно на меня не кричите)) Добавлено через 3 минуты Задание звучит так: реализация ф-ций с переменным числом параметров на языке "с" и передача значений в такую ф-цию.
0
|
|||||||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||||||
| 04.06.2011, 16:24 | ||||||
0
|
||||||
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|
| 04.06.2011, 16:32 [ТС] | |
|
Тут походу просто в бесконечном цикле по УАРТ передаётся информация (ф-ция printf() выводит сообщения)
0
|
|
|
|
|||
| 04.06.2011, 17:35 | |||
|
Вообще, внятно поставленный вопрос - это уже половина ответа. А мне думается, что никто до сих пор не понял, чего конкретно ты хочешь
0
|
|||
|
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 04.06.2011, 20:02 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Сообщение было отмечено как решение
Решение
Вот информация о функциях с переменным числом параметров.
Функции с переменным числом параметров Язык C++ вслед за С позволяет писать функции с переменным числом параметров. Одним из простых примеров может служить функция, вычисляющая среднее арифметическое своих аргументов. Другой уже классический пример — функция сцепления произвольного количества строк, которая является естественным обобщением функции сцепления двух строк. Переменный список параметров задается в заголовке функции многоточием:
Однако у программиста с написанием таких функций сразу возникают проблемы. Ведь имена параметров отсутствуют! Поэтому доступ можно осуществить только одним способом – косвенным, используя указатель. Вспомним, что все параметры при вызове помещаются в стек. Если мы каким-то образом установим указатель на начало списка параметров в стеке, то, манипулируя с указателем, мы, в принципе, можем «достать» все параметры! Таким образом, список параметров совсем пустой быть не может, должен быть прописан хотя бы один явный параметр, адрес которого мы можем получить при выполнении программы. Заголовок такой функции может выглядеть так:
Есть одно обстоятельство, которое ограничивает применение таких функций: при написании функции с переменным числом параметров помимо алгоритма обработки программист должен разрабатывать и алгоритм доступа к параметрам. Так что список необъявленных параметров не может быть совсем уж произвольным – в языке C++ не существует универсальных средств распознавания элементов этого списка. Это же означает, что передача аргумента не того типа, который задумывался, или не тем способом, который подразумевался при разработке, приведет к катастрофическим последствиям – компилятор-то ничего не проверяет. Попробуем написать функцию, вычисляющую среднее арифметическое своих аргументов. Для этого требуется решить несколько проблем - как установиться на список параметров в стеке; - как «перебирать» параметры; - как закончить перебор. Для доступа к списку параметров нам потребуется указатель, значением которого будет адрес последнего явного параметра в списке. Ответ на второй вопрос очевиден – надо изменять значение этого указателя, чтобы переместиться на следующий параметр. Отсюда следует, что указатель должен быть типизированным, поскольку с бестиповым указателем нельзя выполнять арифметические операции. Это же означает, что программист при разработке функции с переменным числом параметров должен отчетливо себе представлять типы аргументов, которые будет обрабатывать функция. Кроме того, способ передачи параметров должен быть одинаковым для всех параметров: либо все – по значению, либо все – по ссылке, либо все – по указателю. Ответ на последний вопрос не вызывает затруднений. Это можно сделать одним из двух способов: - явно передать среди обязательных параметров количество аргументов; - добавить в конец списка аргумент с уникальным значением, по которому будет определяться конец списка параметров; И тот, и другой способ имеют право на жизнь — все определяется потребностями задачи и вкусами программиста. В данном случае сначала попробуем второй способ: последним значением списка параметров будет ноль (листинг 7.7).
Реализация функции, которая в качестве первого параметра получает количество аргументов, на первый взгляд, не вызывает затруднений. Однако, если первый аргумент – целое число, то требуется преобразование указателя. И тут не все варианты проходят. Не будет работать такой вариант:
Мы использовали способ передачи параметров по значению. В этом случае в качестве фактических аргументов можно задавать произвольные выражения. Однако можно использовать и передачу ссылки – это несколько осложняет вызов, поскольку в этом случае в списке аргументов могут прописываться только переменные. Необходимо также помнить, что все фактические аргументы должны передаваться одинаковым способом. Тогда прототип первого варианта функции выглядит так (тело функции не изменяется):
Язык C++ в качестве элементов переменного списка аргументов разрешает прописывать указатели. Однако обработка такого варианта вызывает сложности – нам требуется двойной косвенный доступ, а указатель для доступа к стеку — «одноразовый». Таким образом, если передавать параметры-указатели, то в приведенной выше программе (с первым параметром-количеством) значение *рр – это не число типа double, а адрес этого числа. Тут без «обмана» компилятора не обойтись, поскольку он просто так не пропускает преобразование «одноразовой» косвенности в двойную. Но мы помним, что все типизированные указатели, независимо от типа и косвенности всегда представляют собой адрес, размер которого в Intel – 4 байта. Тогда можно использовать union (листинг 7.9).
Необходимо обратить внимание на то, что изменяем мы «двойной» указатель – «одноразовый» использовать нельзя, поскольку будет изменение на sizeof(double)=8 байт, а нам требуется изменение на sizeof(double*)= 4 байта. И при суммировании используется двойной косвенный доступ. Обращение к такой функции выполняется так: c
Напоследок осталось рассмотреть пример, в котором список указателей переменной длины составляют указатели на char. Мы выделяем этот случай по двум причинам: - размер данных (char) меньше, чем размер указателя (char*) – в остальных случаях размер данных больше или равен размеру указателя; - char* — это единственный указатель, вместо которого при вызове можно задавать не адрес. Типичной функцией, в которой можно применить переменный список параметров, является функция сцепления произвольного количества строк в одну. Заголовок такой функции может выглядеть так:
Стандартные средства В стандарт языка входит набор макросов для работы со списками параметров переменной длины, определенный в stdarg.h. При их использовании точно так же требуется указывать в списке явный параметр, объявить и установить на него указатель и перемещаться по списку, изменяя его. В конце списка должен стоять NULL. Макросы, обеспечивающие стандартный доступ к спискам параметров переменной длины, имеют следующий формат:
1. в теле функции с переменным числом параметров до первого использования указанных макросов должно появиться объявление объекта типа va_list, например va_list LastP; фактически это является объявлением указателя; 2. указанный объект связывается с последним явным параметром (перед многоточием) переменного списка параметров с помощью макроса va_start, например va_start(LastP,P); таким образом происходит инициализация указателя; 3. передвижение по переменному списку параметров выполняется макросом va_arg. Для этого, как указано выше, тоже необходимо явно указывать тип очередного параметра, то есть программист должен его знать в момент написания программы. Если все параметры в списке целого типа, то вызов va_arg выглядит так: va_arg(LastP,int); 4. после всей обработки ставится вызов va_end, например va_end(LastP). В качестве примера рассмотрим реализацию функции вычисления среднего арифметического (вариант с количеством аргументов) с использованием этих макросов (листинг 7.12).
7
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
| 04.06.2011, 23:39 | |
|
ValeryLaptev, в твоих примерах аргументы достаются не через va_arg, а через поинтерную арифметику. За такие статьи надо к стенке ставить, потому что начинающие начитаются такой ереси и начинают быдлокоды писать
0
|
|
|
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
|
||
| 05.06.2011, 09:59 | ||
|
А во-вторых, надо знать, как НА САМОМ деле реализуются стандартные средства... ![]() И не забывайте, что гроссмейстеры постоянно внушают: конь на краю доски - плохо! Но сами-то частенько так ходят! Все зависит от конкретной ситуации... ![]() Ибо в-третьих, профи придумали это механизм для себя любимых. Если этого не пробовать, как становиться профи... ![]() Вы про реализацию таблицы виртуальных функций помните? Указатель на указателе сидит, и указателем погоняет!
0
|
||
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|||||||||||||||||||||
| 05.06.2011, 11:56 [ТС] | |||||||||||||||||||||
|
Всё ребят, понял что нужно. Извините, что морочил Вам голову
![]() Постараюсь объяснить что требуется: Есть функция myprintf(), по сути она должна делать тоже самое что и printf(), т.е. выводить сообщение. К примеру нам нужно вывести на экран сообщение:
Значит нужно сделать так, чтобы ф-ция myprintf() вызывала из библиотеки stdio ф-цию printf(), вставляла туда нужные нам параметры для вывода и вывела их на экран. Прототип ф-ции находится в stdio.h а библиотека вот stdio.a. Как это сделать не знаю. В общем должно выглядеть так: код который я вставлял, в нём к примеру есть строка:
Вот как). Задача осложняется тем, что это не БИЛДЕР и не ВИЖАК, а компилятор микропроцессора, так что всё должно быть в очень примитивном виде (без сложных конструкций языка СИ) Спасибо за внимание. Добавлено через 2 минуты Кстати в файле stdio.h прототип ф-ции выглядит так:
0
|
|||||||||||||||||||||
|
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
|
|
| 05.06.2011, 12:00 | |
|
Ну так в уже упомянутом посте номер 6 и есть решение вашей задачи в чистом виде. Только макросы оказались ненужными
![]() И какие такие сложные конструкции языка?
0
|
|
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|
| 05.06.2011, 12:08 [ТС] | |
|
Я вставлял этот код в исходник в посте 21, компилятор ругался
![]() Может что ни так вставил?
0
|
|
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
| 05.06.2011, 12:11 | |
|
Uklunok, ну приведи что ли сообщения компилятора.
0
|
|
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|||||||||||
| 05.06.2011, 12:20 [ТС] | |||||||||||
|
Вот сделал без макросов:
Сейчас попробую вставить в исходник и откомпилировать.
0
|
|||||||||||
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
||
| 05.06.2011, 12:24 | ||
|
0
|
||
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
||||||
| 05.06.2011, 12:36 [ТС] | ||||||
|
Одна ошибка.
Можно поменять на другую? к примеру fprintf() ??? Добавлено через 53 секунды int fprintf(FILE *, const char *fmt, ...);
0
|
||||||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
| 05.06.2011, 12:39 | |
|
Uklunok, Без vprintf придется разбивать формат строку на токены и значения соответственно тоже (ну например массив указателей на void*) и вызывать printf с нужными параметрами
0
|
|
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
| 05.06.2011, 12:39 | |
|
0
|
|
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
|
| 05.06.2011, 12:41 [ТС] | |
|
Нету там, я же привёл в сообщение содержимое файла.
А что такое токены?
0
|
|
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
||
| 05.06.2011, 12:43 | ||
|
Если не найдешь vprintf, нужно будет писать разбор форматной строки самому либо гуглить по ключевым словам "printf implementation"
Токен - http://en.wikipedia.org/wiki/Token_(parser)#Token
0
|
||
|
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
|
||
| 05.06.2011, 12:49 [ТС] | ||
|
А на русском можно ссылочку по разбору строки? И сложно это делается?
0
|
||
| 05.06.2011, 12:49 | |
|
Помогаю со студенческими работами здесь
40
Как припаять PLS на самодельную плату Не могу понять как исправить ошибку Warning: printf() [function.printf]: Too few arguments in Z:\home\ksards.ru\www\id\1.php on line 76 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
|
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем.
. . .
|
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|