Страница 373 из 386

Re: Вопросы по С/С++ (СИ)

Добавлено: Пн янв 02, 2023 16:12:16
OKF
[uquote="VladislavS",url="/forum/viewtopic.php?p=4347196#p4347196"]И вместо обычного шаблона предлагается вот такой хренью страдвть. Мир сошёл с ума.[/uquote]
А нету у меня плюсов, и что прикажешь дальше?
AVR libc посмотри немного. И не такое увидишь.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пн янв 02, 2023 16:20:34
VladislavS
[uquote="OKF",url="/forum/viewtopic.php?p=4347206#p4347206"]А нету у меня плюсов, и что прикажешь дальше?[/uquote]Либо страдать, либо иcпользовать нормальные контроллеры. Впрочем, С23 у вас тоже не будет, так что страдания будут не сильными.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пн янв 02, 2023 23:07:17
DX168B
Кому как, а мне С++ зашел на ура. И в эмбеде, если есть на какой-то платформе возможность писать как на С, так и на С++, я предпочту С++, так как если разобраться в его функционале метапрограммирования, то его код основных алгоритмов проекта становится не чуть не хуже других языков. Я даже кроссплатформенный связный список с автоменеджментом памяти написал и тащу его с проекта в проект.
Даже ассоциативный массив писал, к которому можно обращаться вот так:

Код: Выделить всё

int variable = array["parameter_name"];
который мог хранить данные любого типа вперемешку. Язык очень мощный, но есть минус. Многих вещей нет в базовой "комплектации" и приходится реализовывать их самому. Но при правильном подходе, многие вещи можно собирать в копилку и использовать в других проектах, не изобретая каждый раз различные вариации собственных велосипедов. Какие-то вещи имеются в составе стандартных библиотек, так что не все так печально.

offtop:
Это первое мое сообщение на форуме в этом году и оно 4444-е по счету моих сообщений. :)))

Re: Вопросы по С/С++ (СИ)

Добавлено: Ср мар 22, 2023 21:58:40
uldemir
У меня рекурсивная проблема. Есть фортоподобный интерпретатор. Так как это не настоящий Форт, то список слов сделан просто массивом:

Код: Выделить всё

typedef struct {
    char CmdName[12]; // name of command
    uint32_t (*fnctPt)(instance_t *, int *); // to execute this command
    int *param;
}Cmd_t;
Т.е. 12 байт слово, указатель на код связанный с этим словом и параметр в виде 32 битного числа, которое может быть числом, адресом или ничем. Так как один этот код может исполняться разом несколько копий, в функцию связанную со словом передаётся еще и указатель на то, с которым воплощением мы работаем. Это "воплощение" описано так:

Код: Выделить всё

typedef struct {
        unsigned char input_string[64];
        unsigned int base;
        uint32_t stack[FORTH_STACK_SIZE];
        uint32_t stack_idx;
        unsigned int str_index;
        unsigned int esc_sequence;
        void (*UART_OutString)(char *);
        void (*UART_OutChar)(uint8_t);
        void (*UART_OutUDec)(uint32_t);
} instance_t; 
Ничего особенного - глобальные переменные и функции вывода для каждой копии программы.

Всё было здорово, пока мне не пришло в голову, сделать переключаемые словари, как в настоящем Форте. Поэтому задумал сделать указатель на текущий словарь в instance_t. Но, я не могу в этот instance вставить указатель на Cmd_t, пока он не определён, а Cmd_t не могу определить, пока не определён instance_t. Как быть?

Re: Вопросы по С/С++ (СИ)

Добавлено: Ср мар 22, 2023 22:43:59
Аlex

Код: Выделить всё

struct instance_t;
struct Cmd_t;

struct Cmd_t{

    instance_t  *   p_instance;
};

struct instance_t{

	Cmd_t  *   p_cmd;
};

//------------------------------------------------
{
instance_t      inst;
Cmd_t           cmd;

inst.p_cmd = &cmd;
cmd.p_instance = &inst;

}

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт мар 23, 2023 06:56:31
uldemir
Чевой-то не получается
Спойлер

Код: Выделить всё

#ifndef COMMANDLINE_H
#define COMMANDLINE_H

#define FORTH_STACK_SIZE 16

struct instance_t;
struct Cmd_t;

typedef struct {
    char CmdName[12]; // name of command
    uint32_t (*fnctPt)(instance_t *, int *); // to execute this command
    int *param;
}Cmd_t;

typedef struct {
        unsigned char input_string[64];
        unsigned int base;
        uint32_t stack[FORTH_STACK_SIZE];
        uint32_t stack_idx;
        unsigned int str_index;
        unsigned int esc_sequence;
        Cmd_t  * current_vocabulary;
        void (*UART_OutString)(char *);
        void (*UART_OutChar)(uint8_t);
        void (*UART_OutUDec)(uint32_t);
} instance_t;

Код: Выделить всё

arm-none-eabi-gcc -g3 -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 '-DDEBUG_EFM=1' '-DEFM32GG12B810F1024GM64=1' '-DSL_BOARD_NAME="BRD2207A"' '-DSL_BOARD_REV="A03"' '-DSL_COMPONENT_CATALOG_PRESENT=1' -I"C:\Users\prg51\SimplicityStudio\Maze\EFM32_ROMI_Robot_2\config" 
<Skipped>
In file included from ../Maze.c:21:
../commandline.h:22:24: error: unknown type name 'instance_t'
   22 |     uint32_t (*fnctPt)(instance_t *, int *); // to execute this command
      |                        ^~~~~~~~~~
Если поменяю местами typedef, то ошибка в строчке

Код: Выделить всё

    uint32_t (*fnctPt)(instance_t *, int *); // to execute this command

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт мар 23, 2023 09:12:00
VladislavS
Не мудрите. Делайте по классике. Связный список это

Код: Выделить всё

typedef struct Node {
    DATA_TYPE data;
    struct Node *next;
} Node;
В DATA_TYPE можете что угодно пихать, но о связном списке он ничего знать не должен.

Впрочем, С++ компилятор ваш пример проглотит, но это не делает его (пример) рабочим. Он идеологически плохо построен.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 02:14:57
Аlex
uldemir писал(а):Чевой-то не получается
Вы не внимательно посмотрели в мой код. У него с Вашим есть различия.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 07:50:24
uldemir
может, вас не затруднит разъяснить, так как ваш код у меня не компилируется точно так же

Код: Выделить всё

#ifndef COMMANDLINE_H
#define COMMANDLINE_H

#define FORTH_STACK_SIZE (16)

struct instance_t;
struct Cmd_t;

struct Cmd_t{

    instance_t  *   p_instance;
};

struct instance_t{

   Cmd_t  *   p_cmd;
};

/*

------------------------------------------------
In file included from ../Maze.c:21:
../commandline.h:22:5: error: unknown type name 'instance_t'
   22 |     instance_t  *   p_instance;
      |     ^~~~~~~~~~
../commandline.h:27:4: error: unknown type name 'Cmd_t'
   27 |    Cmd_t  *   p_cmd;
      |    ^~~~~

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 08:44:01
VladislavS
Аlex, наверное, в ардуине компилирует? Там компилятор в режиме С++ - он такое умеет.

uldemir, послушайте мой совет - сделайте связный список с полем DATA_TYPE ничего не знающем о том что оно находится в связном списке. Как обычную структура данных. Чтобы было всё равно где её создавать - глобально, в куче, на стеке... И вяжи те себе потом из них списки сколько влезет.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 12:30:14
Аlex
VladislavS писал(а):Аlex, наверное, в ардуине компилирует? Там компилятор в режиме С++ - он такое умеет.
Не совсем в Ардуине :))
Да, компилятор g++ под ARM.
СпойлерИзображение
2023-03-24_12-26-14.png
(18.29 КБ) 102 скачивания
Добавлено after 1 minute 52 seconds:
[uquote="uldemir",url="/forum/viewtopic.php?p=4390345#p4390345"]может, вас не затруднит разъяснить, так как ваш код у меня не компилируется точно так же[/uquote] Выше у Вас код был немного другой, с typedef. Похоже, такое умеет только С++, действительно :roll:

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 19:07:23
uldemir
Хорошо. Эта затея не удалась. Есть обходной вариант - так как массив ссылается по адресу, я его могу определить просто как void*, а потом делать приведение типа.


Попробуем связный список.. Но все описания, что я находил гуглом предполагают создание списка в озу и в процессе. У меня же список константный и уже состоит под сотню элементов:
Спойлер

Код: Выделить всё

Thunderboard>words
drop        dup         swap        @           +
*           /           -           <<          !
b!          w!          &           |           ^
.           sp          cr          show        hex
bin         decimal     crc         vbat        threshold
Threshold   X_offset    Y_slope     MAXspeed    MINspeed
MAXmotor    TurnSpeed   Accelerat   K*error     K*de/dt
Kintegral   MotorKprop  MotorKint   OnWay       RunNumber
PathLength  MapSize     StartPoint  EndPoint    IRlevel
map         LeftHand    ColorRed    ColorGreen  ColorBlue
ColorThr    ColorSat    DstToleran  GuardDist   SensorOffs
IgnoreError BrakePath   TimeToRun   TurnCost    CrossCost
StepCost    CellStep    Volt_calibr Bat_low_lvl Length_tab
RedWall     GreenWall   Watermark   motor_en    motor_speed
searchWay   validate    save_conf   dump        dump_eeprom
dump_log    dump_addlog dump_log_ft dump_map    show_path
time_to_run init_brkpth list        words

Thunderboard>
Подскажите, как из этого массива написать связный список на си?

Код: Выделить всё

const Cmd_t Table[]={
    {"drop",            &drop_stack, NULL},
    {"dup",             &dup_stack, NULL},
    {"swap",            &swap_stack, NULL},
    {"@",               &read_mem, NULL},
    {"+",               &sum_stack, NULL},
Чтобы линки создались уже на этапе компиляции. И чтобы не выдумывать каждой записи уникальное имя.

Видел "связный список" в одном видео от TexasInstruments, но оно куда-то подевалось - ссылка никуда не ведёт. И мне кажется, что там всё-равно был массив, потому что длина слова была ограничена (как и у меня, хотя от этого хотелось бы избавиться).

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 19:51:37
VladislavS
Зачем тут для константных данных связный список, когда это обычный массив и возможен простой доступ по индексу?
Спойлер

Код: Выделить всё

#include <stdint.h>
#include <string.h>

uint32_t foo1() { return 1; }
uint32_t foo2() { return 2; }
uint32_t foo3() { return 3; }
uint32_t foo4() { return 4; }
uint32_t foo5() { return 5; }

typedef struct {
    char CmdName[12];
    uint32_t (*fnctPt)();
    int *Cmd_t;
} Cmd_t;

const Cmd_t Table[]={
    {"drop", &foo1},
    {"dup",  &foo2},
    {"swap", &foo3},
    {"@",    &foo4},
    {"+",    &foo5}, };

int main(int argc, char *argv[])
{
  for(uint32_t i=0; i<argc; i++)
  {
    if(strcmp(Table[i].CmdName, argv[i])==0) 
      return  Table[i].fnctPt();
  }
}

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 20:15:05
uldemir
Ну вы же предлагали:
VladislavS писал(а):uldemir, послушайте мой совет - сделайте связный список
Я не против. Более того, хотелось бы. Но я не знаю, как это организовать на языке си, поэтому пока что выкрутился используя массивы. На ассемблере и не такие завороты когда-то устраивал. Ну и конечная цель - переключение словарей. Т.е. чтобы в определённом контексте стали бы доступны другие слова. Почти как в настоящем форте.
Ну если нет - так нет.

p.s. Нашел видео: https://www.ti.com/video/6063280003001? ... NTERPRETER
А вот кадр из видео, где у Валвано сделан "линейный связный список"
Изображение
Но так как у него массив, я не вижу логики в этом списке. Тем более, еще надо помнить индекс каждой записи и если что-то вздумается добавить в начало или середину списка, то нужно будет весь список править.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 24, 2023 21:05:36
VladislavS
[uquote="uldemir",url="/forum/viewtopic.php?p=4390612#p4390612"]Ну вы же предлагали:[/uquote]Вы спросили как сделать сложновыперднутый список. Я предложил сделать простой классический. А когда вы более подробно показали задачу, то видно, что никакой связный список там вообще не нужен.

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт мар 30, 2023 14:44:19
Bill_
[uquote="uldemir",url="/forum/viewtopic.php?p=4390612#p4390612"]Ну вы же предлагали:
VladislavS писал(а):uldemir, послушайте мой совет - сделайте связный список
Я не против. Более того, хотелось бы. Но я не знаю, как это организовать на языке си, поэтому пока что выкрутился используя массивы. На ассемблере и не такие завороты когда-то устраивал. Ну и конечная цель - переключение словарей. Т.е. чтобы в определённом контексте стали бы доступны другие слова. Почти как в настоящем форте.
Ну если нет - так нет.

p.s. Нашел видео: https://www.ti.com/video/6063280003001? ... NTERPRETER
А вот кадр из видео, где у Валвано сделан "линейный связный список"
Изображение
Но так как у него массив, я не вижу логики в этом списке. Тем более, еще надо помнить индекс каждой записи и если что-то вздумается добавить в начало или середину списка, то нужно будет весь список править.[/uquote]
https://www.tutorialspoint.com/data_str ... m_in_c.htm

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт мар 30, 2023 18:44:17
uldemir
Эти примеры кочуют из ссылки в ссылку, что подсовывают поисковики. Но они не отвечают на мой вопрос, который вы старательно бессмыссленно отквотили и, видимо, даже не прочитали. По делу есть что написать?

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 31, 2023 08:40:51
ARV
Я не могу понять, как "переключение контекста" пересекается со связными списками "слов" или массивами?
Переключение контекста, имхо, это присваивание указателю на контекст нового значения...
Context_t *current_context = list1;
...
current_context = list2;
И если вы заранее сделали list1 и list2, то вот и переключение, и совершенно не важно, это будет адрес первого элемента массива или первого элемента списка...

В чем вопрос-то?

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 31, 2023 15:53:32
uldemir
Как переключать контекст я и так знаю - там проблема в цикличной зависимости определений друг от друга. Которая не проблема для, говорят, C++, но чистый C такого не позволяет. А про связный список я не настаивал, но мне его предложили и хочу знать.
...как написать связный список на си? Чтобы линки создались уже на этапе компиляции. И чтобы не выдумывать каждой записи уникальное имя. Или как в этом кадре из видео,
Изображение
не нужно было в случае, если захочу вставить команду между "s" и "g" переправлять в каждой строчке &LL[3] на &LL[4], затем &LL[4] на &LL[5] и так далее до 85-го элемента массива.

И еще, чтобы длина строки содержащей команду не была константной. но typedef, кажется, такое не приемлет.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт мар 31, 2023 16:22:33
Bill_
[uquote="uldemir",url="/forum/viewtopic.php?p=4390345#p4390345"]может, вас не затруднит разъяснить, так как ваш код у меня не компилируется точно так же

Код: Выделить всё

#ifndef COMMANDLINE_H
#define COMMANDLINE_H

#define FORTH_STACK_SIZE (16)

struct instance_t;
struct Cmd_t;

struct Cmd_t{

    instance_t  *   p_instance;
};

struct instance_t{

   Cmd_t  *   p_cmd;
};

/*

----------
In file included from ../Maze.c:21:
../commandline.h:22:5: error: unknown type name 'instance_t'
   22 |     instance_t  *   p_instance;
      |     ^~~~~~~~~~
../commandline.h:27:4: error: unknown type name 'Cmd_t'
   27 |    Cmd_t  *   p_cmd;
      |    ^~~~~
[/uquote]
Всё так и должно быть. Нужно правильно типы указать

Код: Выделить всё

struct instance_t;
struct Cmd_t;

struct Cmd_t{

   struct instance_t  *   p_instance;
};