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

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

04.06.2011, 09:22. Показов 25364. Ответов 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
Ответ Создать тему
Новые блоги и статьи
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии Введение Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np class PlantAgent: def __init__(self, name, strategy, initial_biomass): self. name = name self. strategy = strategy # "greedy" (широколиственные) или. . .
сукцессия 9. Математика подлости: как растения предали грибных друзей
anaschu 27.06.2026
Статья 2. Глобальная фосфорная война: эволюционно-экономические механизмы распределения биомов Земли Введение: Экологический рынок как игра с нулевой суммой Традиционная экология долгое время. . .
сукцессия 8. Как я спорил с ИИ, которые - агенты растений и ненавистники грибов!
anaschu 27.06.2026
Статья 1. Хроники грибного восстания: как Сократов диалог разрушил академические догмы ИИ Введение: Синдром «цифрового учебника» Современные большие языковые модели (LLM) обладают колоссальным. . .
Главный вопрос моделирования сукцессии
anaschu 27.06.2026
главный вопрос. Если эктомикориза лучше добывает недоступный фосфор. И ее масса максимальна из всех. А широколиственный лес тоже имеет самую крутую биомассу. То почему не возникло их симбиоза? Это. . .
сукцессия 6. Питон реализация энилоджиковской модели, картинка про Центральную часть будущей модели
anaschu 26.06.2026
Етить. ИИ мне на основе моего старого файла R создал вот эту вот хмерь на пайтоне. Это уже новая модель, модель сукцессии грибной. потоки фосфора, азота. Углерода. 5 видов организмов. Я даже. . .
Как замкнутый ядерный цикл решит проблему недостатки фосфора? Био миграция фосфора со дна океана
anaschu 26.06.2026
Биологический лифт: Концепция подъема фосфора со дна океана с помощью ЗЯТЦ Предлагаю на обсуждение альтернативу тяжелому промышленному бурению океанического дна. Вместо сложной инженерии мы можем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru