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

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

04.06.2011, 09:22. Показов 24496. Ответов 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
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru