Страница 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
Кому как, а мне С++ зашел на ура. И в эмбеде, если есть на какой-то платформе возможность писать как на С, так и на С++, я предпочту С++, так как если разобраться в его функционале метапрограммирования, то его код основных алгоритмов проекта становится не чуть не хуже других языков. Я даже кроссплатформенный связный список с автоменеджментом памяти написал и тащу его с проекта в проект.
Даже ассоциативный массив писал, к которому можно обращаться вот так:
который мог хранить данные любого типа вперемешку. Язык очень мощный, но есть минус. Многих вещей нет в базовой "комплектации" и приходится реализовывать их самому. Но при правильном подходе, многие вещи можно собирать в копилку и использовать в других проектах, не изобретая каждый раз различные вариации собственных велосипедов. Какие-то вещи имеются в составе стандартных библиотек, так что не все так печально.
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.
Спойлер
Добавлено after 1 minute 52 seconds:
[uquote="uldemir",url="/forum/viewtopic.php?p=4390345#p4390345"]может, вас не затруднит разъяснить, так как ваш код у меня не компилируется точно так же[/uquote] Выше у Вас код был немного другой, с
typedef. Похоже, такое умеет только С++, действительно

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;
};