Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/123: Рейтинг темы: голосов - 123, средняя оценка - 4.72
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135

Как перенести параметры из ф-ции printf() в самодельную

04.06.2011, 09:22. Показов 24655. Ответов 104
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ребят, подскажите как решить задачу.
Нужно перенести параметры функции printf() в самодельную ф-цию myfunk(). При условии если булева переменная Х==1. Если не равна 1, то не переносить.
Задача осложняется тем, что число параметров ф-ции может быть переменным.
Подскажите пожалуйста, буду очень признателен.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.06.2011, 09:22
Ответы с готовыми решениями:

Как перенести параметры с XP на 7
Не знаю в какой ветке разместить тему, то ли в XP, то ли в 7... Всё началось с того, что установив win7, я не смог установить драйвер на...

Передача ф-ции как параметра другой ф-ции
struct pupil{ char surname; int school; int answer; int num; } tmp, a; int usl(int i, pupil a) { }

Параметры printf
Здравствуйте дорогие форумчане ;) У меня есть вопрос по следующему куску кода. Решив по практиковаться с консольным приложением у меня...

104
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:08  [ТС]
Студворк — интернет-сервис помощи студентам
Гыыыыы.
Попробовал и так сделать, в итоге оказалось что при инициализации переменной "с" int не нужен:
C
1
2
3
4
5
6
7
8
9
10
static void printchar(char **str, int c)
{
    extern int  my_putchar([U][I]int[/I][/U] c); //убрал от сюда инт
 
    if (str) {
        **str = c;
        ++(*str);
    }
    else (void)putchar(c);
}
Добавлено через 2 минуты
Ну в принципе теперь компилится нормально, пару замечаний есть(warnings). Но я конечно и по убирал не мало кода, в основном некоторые циклы if, где ругался. Щас довести до ума осталось.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 14:09
Uklunok, во-первых, зачем в этом фрагменте вообще нужна строка #3?
Во-вторых, в языке С, если у параметров и возвращаемого значения функции опущены аннотации типов, то считается, что тип - int.
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:22  [ТС]
Ого себе. Этот компилятор оказывается сохранил весь код в ассемблере, поместил его в папку debug, исходный код на Си весит 6,8кБ, а этот на ассемблере 70кБ))

Добавлено через 3 минуты
Цитата Сообщение от Nameless One Посмотреть сообщение
Uklunok, во-первых, зачем в этом фрагменте вообще нужна строка #3?
Не знаю, разве Вы ещё не поняли, что я в Си мало что знаю??))) Ну если строка тут стоит - думаю её лучше оставить, мало ли...
Цитата Сообщение от Nameless One Посмотреть сообщение
Во-вторых, в языке С, если у параметров и возвращаемого значения функции опущены аннотации типов, то считается, что тип - int.
Честно сказать, не знал этого. Ну почему тогда компилятору это не понравилось... Программисты такие чтоль??

Добавлено через 4 минуты
Мистика какая-та. Сделал так:
C
1
2
3
4
5
6
7
8
9
10
static void printchar(char **str, int c)
{
    extern   my_putchar(int c);
 
    if (str) {
        **str = c;
        ++(*str);
    }
    else (void)putchar(c);
}
и тоже работает. Почему не ругается на my_putchar()?, её ведь нет нигде

Добавлено через 2 минуты
Может вобще так оставить?:
C
1
2
3
4
5
6
7
8
9
10
static void printchar(char **str, int c)
{
      putchar( c);
 
    if (str) {
        **str = c;
        ++(*str);
    }
    else (void)putchar(c);
}
Так тоже компилится
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 14:29
Uklunok, extern my_putchar - это прототип (объявление интерфейса) функции my_putchar, которая должна быть определена где-то в другой единице трансляции. my_putchar - прототип функции, которая определяется в текущей единице трансляции. Так как эта функция нигде не вызывается, то сам факт, что она не определена, к ошибкам не приводит.

Цитата Сообщение от Uklunok Посмотреть сообщение
Может вобще так оставить?:
Так - нельзя (потому что здесь уже не определение putchar, а ее вызов). Убери вообще 3 строку, она не нужна.
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:49  [ТС]
else (void)putchar(c); - эту тоже убрать?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 14:51
Uklunok, а вот это уже убирать не надо
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:54  [ТС]
Ещё ругается на эту строку:
if (*format == '%') goto out;
я её убрал
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 14:57
Uklunok, что именно говорит?

Добавлено через 1 минуту
Цитата Сообщение от Uklunok Посмотреть сообщение
я её убрал
а вот это зря, теперь ты не сможешь вывести символ % в своей функции printf
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 15:21  [ТС]
дак у меня комилятор виснет.
Тут такая штука получается:
C
1
2
3
4
5
6
7
8
if (*format == '%') goto out;
//дальше ещё if-ы
 
    else  {
        out:
        printchar (out, *format);
        ++pc;
       }
может как-нить по другому реализовать переход на out?

Ни какой ошибки не выдаёт, просто виснет компилятор((

Добавлено через 4 минуты
Хотя в самом исходнике для МК есть такие строки:
C
1
2
main_loop:
    goto main_loop;
значит через goto переходить можно.

Добавлено через 2 минуты
Всё разобрался, тут имя out такое у метки и у переменной одно и тоже.
сделал так:
if (*format == '%') goto out1;
//дальше ещё if-ы

else {
out1:
printchar (out, *format);
++pc;
}

Добавлено через 9 минут
А как быть с параметром %p:
C
1
my_printf("Pointers %p %p %p\n", &uart_iocb, &ch, &ush);
Его к сожалению нету...

Добавлено через 17 секунд
А как быть с параметром %p:
C
1
my_printf("Pointers %p %p %p\n", &uart_iocb, &ch, &ush);
Его к сожалению нету...
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.06.2011, 15:55
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
А во-вторых, надо знать, как НА САМОМ деле реализуются стандартные средства...
То, что написано - это НЕ "как на самом деле реализуются", а "как реализуются в программных соглашениях для архитектуры i386". Перенеси этот код на другую платформу - и он почти наверняка отработает неправильно.

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Все зависит от конкретной ситуации...
Гавнокод в большинстве случаев тоже является следствием конкретной ситуации

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Ибо в-третьих, профи придумали это механизм для себя любимых. Если этого не пробовать, как становиться профи...
У меня нет претензии к статье как таковой. У меня есть претензии к тому, что нигде ни разу не написано, что код не переносимый и так писать код не надо. И как-то неявно проскальзывает, что va_arg'и придумали чисто ради удобства, хотя на самом деле их придумали в первую очередь чтобы разные программные соглашения накрыть универсальным интерфейсом (чтобы коды были переносимыми)

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Вы про реализацию таблицы виртуальных функций помните? Указатель на указателе сидит, и указателем погоняет!
Только вот никто не пишет кодов таким образом, чтобы через поинтерную арифметику выковыривать из экземпляра класса таблицу виртуальных функций и конечный адрес метода

Добавлено через 1 минуту
Цитата Сообщение от Uklunok Посмотреть сообщение
Залез в <stdio.h> и прототипа ф-ции vprintf() не нашёл
vfprintf есть? В данном случае тебе покатит только функция, начинающаяся на "v" (от "vararg"), ибо она принимает указатель на стек, который в общем случае неизвестно как реализован, но получение этого значения накрыто интерфейсом va_start

Добавлено через 5 минут
Цитата Сообщение от Uklunok Посмотреть сообщение
Значит нужно сделать так, чтобы ф-ция myprintf() вызывала из библиотеки stdio ф-цию printf(), вставляла туда нужные нам параметры для вывода и вывела их на экран
В такой постановке задача невыполнима, потому что функции с переменны числом параметров можно вызвать только напрямую. Никакие функции-прокладки здесь уже не канают. Чтобы можно было делать прокладки, сделаны функции типа vprintf (а сам printf внутри себя так же вызывает vprintf). Если у тебя этой функции нет (ну или нет vfprintf, vsprintf, и т.п.), то единственный способ сделать твою задачу - это ручками написать весь код printf'а. Хотя, если речь идёт о микроконтроллере, то тебе нужен будет ограниченно-кастрированный вариант printf'а, в котором можно будет ограничиться самыми простыми описателями %s, %c, %d, %x
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 15:56
Цитата Сообщение от Uklunok Посмотреть сообщение
А как быть с параметром %p:
чтобы реализовать %p, нужно указатель привести к типу int и вывести его через спецификатор "%#x"
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.06.2011, 15:58
Цитата Сообщение от Nameless One Посмотреть сообщение
чтобы реализовать %p, нужно указатель привести к типу int и вывести его через спецификатор "%#x"
На 32-битных системах %p эквивалентен %x, на 64-битных - эквивалентен %lx. Эквивалентен в смысле реализации
1
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
05.06.2011, 16:00
Цитата Сообщение от Evg Посмотреть сообщение
То, что написано - это НЕ "как на самом деле реализуются", а "как реализуются в программных соглашениях для архитектуры i386". Перенеси этот код на другую платформу - и он почти наверняка отработает неправильно.
Вот к сожалению у меня нет никакой возможности в настоящее время проверить этот все на другой архитектуре. Хотя сам работал на множестве архитектур.
А было бы действительно интересно посмотреть...
Хотя навскидку - только преобразования типов указателей претендуют на специфику архитектуры.
Остальное - вполне стандартный С++...
Хотя на 64-битной - весьма вероятны проблемы. Но написано это было еще в 2003 году...
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 16:02  [ТС]
Нет, на "v" ничего не начинается. Только
va_start(ap, v) (ap = (va_list) & v + sizeof(v))
va_arg(ap, t) (*(t *) ((ap += sizeof(int)) - sizeof(int)))
va_end(ap) (ap = (va_list) 0)

Как господин Nameless One, сказал сделать, вроде должно работать, ведь проверяться будет на железе
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 16:03
Цитата Сообщение от Evg Посмотреть сообщение
На 32-битных системах %p эквивалентен %x, на 64-битных - эквивалентен %lx. Эквивалентен в смысле реализации
ну ТС'у код нужно написать под определенный контроллер, так что, думаю, это не проблема.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.06.2011, 16:06
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Хотя навскидку - только преобразования типов указателей претендуют на специфику архитектуры. Остальное - вполне стандартный С++...
Нет. То, что параметры передаются таким образом на стеке на intel'е - это не значит, что они передаются таким же образом на других архитектурах. Если параметры типа int на i386 будут передаваться в стеке с интервалом в 4 байта, но на 64-битных архитектурах даже если они и передаются на стеке, то будут скорее всего передаваться с интервалом 8 байт. параметры структурных типов так вообще где как передаются. На многих архитектурах часть параметров передаётся на регистрах. Чтобы все эти тонкости не знать, для того и придумали интерфейсы va_start, va_srg, va_end - на каждой платформе они реализованы таким образом, чтобы учитывать специфику "родного" ABI

Добавлено через 2 минуты
Цитата Сообщение от Uklunok Посмотреть сообщение
Как господин Nameless One, сказал сделать, вроде должно работать, ведь проверяться будет на железе
Не очень понял, что ты хотел сказать, но тебе придётся реализовывать свою собственную printf и от этого скорее всего никуда не денешься

Цитата Сообщение от Nameless One Посмотреть сообщение
ну ТС'у код нужно написать под определенный контроллер, так что, думаю, это не проблема
Ну я и имел в виду, что %p - это не есть что-то новое, а просто нужным образом заиспользовать то, что уже реализовано
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 16:11  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение

Не очень понял, что ты хотел сказать, но тебе придётся реализовывать свою собственную printf и от этого скорее всего никуда не денешься
Зачем реализовывать свою ф-цию? Если и так работает нормально, 7 параметров это не плохо, хотя их на самом деле 10 для компилятора МК FTDI. Я ведь не для себя, мне для отчётности надо. Если то что есть будет работать на железе, то великолепно. А так как компилятор нормально скомпилировал и собрал, то думаю должно работать)
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 16:15
Цитата Сообщение от Uklunok Посмотреть сообщение
А так как компилятор нормально скомпилировал и собрал, то думаю должно работать)
К сожалению, то, что программа на С/С++ скомпилировалась - не является достаточной гарантией того, что он работает. Напиши тесты и проверь. Тогда будешь полностью уверен.
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 17:05  [ТС]
Ну дак я ведь ещё и в билдере проверил. Перенёс код, скомпилировал и работает. Правда компилятор для ftdi выдал 4 warning-a, ну это не беда думаю...

Добавлено через 56 секунд
А что за тесты?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.06.2011, 17:07
Uklunok, программа, которая будет вызывать твою функцию (работоспособность которой нужно проверить) с различными аргументами, чтобы выяснить, правильно ли работает эта функция.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.06.2011, 17:07
Помогаю со студенческими работами здесь

Динамические параметры printf()
Есть код printf(&quot;%5s &lt;-- %14s\n&quot;, buffer0.c_str(), &quot;n/a&quot;); Что делать если я не знаю на этапе компиляции числа 5 и 14? Для...

Форматы и параметры printf/scanf
Задали вопрос что если в выводе : 1) форматов&gt;переменных 2)переменных&gt;форматов Я делал программки и смотрел что получается,но не...

Как припаять PLS на самодельную плату
Возник вопрос: как припаять PLS разъём на самодельную плату? Примерно как здесь ...

Не могу понять как исправить ошибку Warning: printf() [function.printf]: Too few arguments in Z:\home\ksards.ru\www\id\1.php on line 76
Помогите связать бд с сайтом я новичок в этом вот код php &lt;?php do { printf(&quot;&lt;div class='blog'&gt;&lt;a...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru