powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Переменное число аргументов в функции
19 сообщений из 19, страница 1 из 1
Переменное число аргументов в функции
    #39928416
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Скажем так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void va_test(int num_args, ...)
{
    va_list valist; 
    
    va_start(valist, num_args); 
    
   for (int i = 0; i <= num_args; i++)
       int sum += va_arg(valist, int);
}



но если аргументы разных типов
va_test(4, 1, "аа" , 2, "бб" )
как мне проверить тип аргумента?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
void va_test(int num_args, ...)
{
    va_list valist; 
    
    va_start(valist, num_args); 
    
   for (int i = 0; i <= num_args; i++)
  {
       //if  arg int
       int sum = va_arg(valist, int);
       //if arg string
       char *str = va_arg(valist, char *);
  }
}
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928427
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7

так же как это сделано в printf
или вариадик темплеты.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928428
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИМХО по хорошему надо в структуру собрать все твои аргументы и ее передавать.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928436
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
ИМХО по хорошему надо в структуру собрать все твои аргументы и ее передавать.

и включить в структуру тип аргумента? громоздко как то получается...
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928439
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
OoCc
jenya7

так же как это сделано в printf
или вариадик темплеты.

я посмотрел на сорцы printf. отхожу от шока...
но принцип понятен - %s - означает строку, %d - означает число и так далее.
наверно нужно делать как Dima_T советует.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928446
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7
OoCc
jenya7

так же как это сделано в printf
или вариадик темплеты.

я посмотрел на сорцы printf. отхожу от шока...

и учти в printf() можно элементарно накосячить, для контроля этого в компиляторах есть специальные флаги для проверки во время компиляции.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928451
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7
Dima T
ИМХО по хорошему надо в структуру собрать все твои аргументы и ее передавать.

и включить в структуру тип аргумента? громоздко как то получается...

Если тип заранее неизвестен, то по другому никак.
В параметрах приходят только значения, а тип и размер задается заранее, во время компиляции. Т.е. вызываемая функция заранее знает какого типа ее параметры.

Как вариант не явно наполнять указывая типы, а сделать методы:
Код: plaintext
1.
2.
add(int x);
add(char* x);


и внутри каждого прописать добавления нужного типа.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928453
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7
OoCc
jenya7

так же как это сделано в printf
или вариадик темплеты.

я посмотрел на сорцы printf. отхожу от шока...
но принцип понятен - %s - означает строку, %d - означает число и так далее.
наверно нужно делать как Dima_T советует.

В твоём случае ненужна вся комплексити printf формата. Достаточно одного символа на параметр.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928455
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
ИМХО по хорошему надо в структуру собрать все твои аргументы и ее передавать.
по хорошему тут просматривается базовый класс и подклассы для обработки разных типов.

а в функцию либо массив указателей передавать, либо сами указатели, если хочется va_*** поюзать
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928459
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCc
jenya7
пропущено...

я посмотрел на сорцы printf. отхожу от шока...
но принцип понятен - %s - означает строку, %d - означает число и так далее.
наверно нужно делать как Dima_T советует.

В твоём случае ненужна вся комплексити printf формата. Достаточно одного символа на параметр.

А как оно в памяти расположится? Разные типы могут быть разного размера.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928466
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
OoCc
пропущено...

В твоём случае ненужна вся комплексити printf формата. Достаточно одного символа на параметр.

А как оно в памяти расположится? Разные типы могут быть разного размера.

так же как и printf разбирается с char и double. Строки и комплексные типы - передаются по указателю.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928498
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
я тут накропал. а если так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
typedef struct
{
      char *variable;
      int type;
}VAR;

void MyPrintf(int argc, ...)
{
    int i;
    int val;
    char *strp;
    VAR var;
    
    va_list valist; 
    
    va_start(valist, argc); 
    
    //first argument is a resulting string
    char *string = va_arg(valist, char *);
   
    for (i = 0; i < argc; i++)
    {
        var = va_arg(valist, VAR);
        switch (var.type)
        {
            case 1: val = *(uint8_t *)var.variable; break;
            case 2: val = *(uint16_t *)var.variable; break;
            case 3: val = *(uint32_t *)var.variable; break;
            case 4: strp = (char *)var.variable; break;
        }
        
        if (var.type < 4)
        {
            strp = loc_itoa(val);
            strcat(string, strp);
        }
        else
           strcat(string, strp);
            
    }
   
   va_end(valist); 
}
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928533
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
поменял на войдовый указатель
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
typedef struct
{
    void *value;
    int type;
}VAR;

void MyPrintf(int argc, ...)
{
    int i;
    int val;
    char *strp;
    VAR var;
    
    va_list valist; 
    
    va_start(valist, argc); 
    
    //first argument is a resulting string
    char *string = va_arg(valist, char *);
   
    for (i = 1; i < argc; i++)
    {
        var = va_arg(valist, VAR);
        switch (var.type)
        {
            case VTYPE_BYTE:  val = *(uint8_t *)var.value;  break;
            case VTYPE_SHORT: val = *(uint16_t *)var.value; break;
            case VTYPE_INT:   val = *(uint32_t *)var.value; break;
            case VTYPE_STR:   strp = (char *)var.value;     break;
        }
        
        if (var.type < VTYPE_STR)
        {
            strp = loc_itoa(val);
            strcat(string, strp);
        }
        else
           strcat(string, strp);     
    }
    
   strcat(string, "\0");
   
   va_end(valist); 
}



проверяю
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
uint32_t COM_Printf(uint32_t argc, char** args)
{
  char str[128] = { '\0' };
    
    VAR vars[4];
    
    vars[0].type = 1;
    vars[0].value = (uint8_t*)1;

    vars[1].type = 4;
    vars[1].value = (char *)"aa";

    vars[2].type = 3;
    vars[2].value = (uint32_t*)1234;

    vars[1].type = 4;
    vars[1].value = (char *)"bb\r";
    

    //хочеться так но так не работает
    //MyPrintf(5, str, vars);

   MyPrintf(5, str, vars[0], vars[1], vars[2], vars[3]);
    
   USART_SendString(SYS_USART, str);
      
   return MSG_OK;
}



должен увидеть 1aa1234bb
но вижу
87bb
29491202949120
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928603
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
так работает
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
void MyPrintf(int argc, ...)
{
    int i;
    int val;
    char *strp;
    VAR var;
     
    va_list valist; 
     
    va_start(valist, argc); 
     
    //first argument is a resulting string
    char *string = va_arg(valist, char *);
    
    for (i = 1; i < argc; i++)
    {
        var = va_arg(valist, VAR);
   
        switch (var.type)
        {
            case VTYPE_BYTE:  
            case VTYPE_SHORT:
            case VTYPE_INT:
              val = (int)var.value;
             break;
             
            case VTYPE_STR:
              strp = (char *)var.value; 
              break;
        }
    
        if (var.type < VTYPE_STR)
        {
            strp = loc_itoa(val);
            strcat(string, strp);
        }
        else
           strcat(string, strp);     
    }
     
   strcat(string, "\0");
    
   va_end(valist); 
}
 
uint32_t COM_Printf()
{
  char str[128] = { '\0' };
     
    VAR vars[4];
     
    vars[0].type = 1;
    vars[0].value = (void *)1;
    vars[1].type = 4;
    vars[1].value = (void *)"aa";
    vars[2].type = 3;
    vars[2].value = (void *)1234;
    vars[3].type = 4;
    vars[3].value = (void *)"bb\r";
     
   MyPrintf(5, str, vars[0], vars[1], vars[2], vars[3]);
    
   USART_SendString(SYS_USART, str);
       
   return MSG_OK;
}



напрягает инициализация и расстановка аргументов. но тут как мне кажеться упростить не удасться.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928631
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7
так работает ...

Это херь какая-то ((( Зачем передавать массив элементами ?

Есть еще куча претензий к твоему коду, завтра сформулирую.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928712
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
vars[0].type = 1;


Почему 1 ? у тебя же выше имена типов определены, используй их, а не магические числа
Код: plaintext
1.
case VTYPE_BYTE:  




Как уже написал тут непонятно зачем переменное число параметров
Код: plaintext
1.
MyPrintf(5, str, vars[0], vars[1], vars[2], vars[3]);


Достаточно указателя на массив и размера
Код: plaintext
1.
void MyPrintf(VAR var, int var_size, char *str)





Зачем куча приведений? Накосячишь, а компилятор не предупредит, т.к. будет считать что так задумано. Используй union
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
typedef struct
{
   union {
      int ivalue;
      char cvalue;
      char* pcvalue;
      ....
    };
    int type;
}VAR;


Далее
Код: plaintext
1.
2.
    vars[0].type = VTYPE_INT;
    vars[0].ivalue = 1;

Код: plaintext
1.
2.
            case VTYPE_INT:   val = var.ivalue; break;
            case VTYPE_STR:   strp = var.pcvalue;     break;
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928745
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T


Достаточно указателя на массив и размера
Код: plaintext
1.
void MyPrintf(VAR var, int var_size, char *str)





Первый аргумент в функции должен быть количество аргументов. И потом если указатель на массив то
void MyPrintf(VAR *var, int var_size, char *str)
Но когда я передаю указатель
MyPrintf(5, str, vars);
то не работает
не умеет var = va_arg(valist, VAR); брать аргументы по указателю.
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928756
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7
Первый аргумент в функции должен быть количество аргументов. И потом если указатель на массив то
void MyPrintf(VAR *var, int var_size, char *str)
Но когда я передаю указатель
MyPrintf(5, str, vars);
то не работает
не умеет var = va_arg(valist, VAR); брать аргументы по указателю.

Зачем va_arg? У тебя фиксированное количество параметров.
Код: plaintext
1.
2.
3.
4.
void MyPrintf(VAR *var, int var_size, char *str) {
 for(int i = 0; i < var_size; i++) {
   switch (var[i].type) {
...
...
Рейтинг: 0 / 0
Переменное число аргументов в функции
    #39928770
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
jenya7
Первый аргумент в функции должен быть количество аргументов. И потом если указатель на массив то
void MyPrintf(VAR *var, int var_size, char *str)
Но когда я передаю указатель
MyPrintf(5, str, vars);
то не работает
не умеет var = va_arg(valist, VAR); брать аргументы по указателю.

Зачем va_arg? У тебя фиксированное количество параметров.
Код: plaintext
1.
2.
3.
4.
void MyPrintf(VAR *var, int var_size, char *str) {
 for(int i = 0; i < var_size; i++) {
   switch (var[i].type) {
...


Ой. Действительно. Спасибо. Как всегда супер. :)
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Переменное число аргументов в функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]