Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

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

Пт мар 31, 2023 17:25:49

А. дошло. никак не мог додуматься зачем нужно имя при определении типа. Теперь понял.

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

Сб апр 01, 2023 07:44:20

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

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

Пример вы привели, мягко сказать, неудачный. Для начала нужно понять что собой представляют массивы и списки, и для чего они могут быть использованы.
Прежде всего, с точки зрения использования памяти, массивы являются статическими объектами. Т.е требуемый объём памяти определяется на этапе компиляции. Допустим, вы хотите сделать словарь на определённо количество слов и оформили его в виде массива. В этом случае вы не сможете в процессе работы программы увеличить количество слов в словаре, если это потребуется. Можно конечно на этапе компиляции сделать размер массива больше, чем требуется изначально. Скажем на момент компиляции в словаре имеется 10 слов, но вы сделаете массив на 100 слов, в расчёте на то, что в процессе работы программы словарь может быть увеличен. Но при этом могут возникнуть две проблемы. Во-первых нет гарантии, что этого массива может хватить (скажем, вы предполагали увеличение словаря до 100, а понадобилось 101 слово). Во-вторых, память будет использоваться не рационально, если количество слов в словаре будет меньше, чем вы расчитывали.
Теперь о списках. В противоположность массивам, списки являются динамическими объектами. Изначально список может вообще быть пустым и никакой памяти выделять не потребуется. Элементы списка создаются и добавляются к списку во время работы программы. Но ту возникает вопрос: а где взять необходимую память? Ответ - память берется из так называемой "кучи", которая обычно имеется в системе. Для этой цели в библиотеки Си имеются соответствующие функции, например malloc (выделить память) и free (освободить память). Но при этом для работы со списками потребуются дополнительные программы.
Наиболее часто связные списки используются в различных трансляторах, когда количество символов в транслируемой программе заранее неизвестно.
Теперь об инициализации списков. В приведённом вам примере список вообще не нужен, ибо все элементы статические. Здесь лучше использовать обыкновенный массив. И памяти меньше потребуется, и работать с массивом будет проще. Что же касается инициализации самих списков на этапе компиляции не необходимости указывать адрес следующего элемента в списке, поскольку этот адрес будет определяться в процессе создания списка при работе программы. Ниже приводится фрагмент программы инициализации списка. На этапе компиляции определяются только те элементы списка, которые должны быть в списке изначально.
Код:
    add_sym("ADC", I_ADC, OC_LD, &instruction_section, &system_st);
    add_sym("ADD", I_ADD, OC_LD, &instruction_section, &system_st);
    add_sym("ASL", I_ASL, OC_1GEN, &instruction_section, &system_st);
    add_sym("ASR", I_ASR, OC_1GEN, &instruction_section, &system_st);
    add_sym("LSL", I_LSL, OC_1GEN, &instruction_section, &system_st);
    add_sym("LSR", I_LSR, OC_1GEN, &instruction_section, &system_st);
    add_sym("BCC", I_BCC, OC_BR, &instruction_section, &system_st);
    add_sym("BCS", I_BCS, OC_BR, &instruction_section, &system_st);

Функция add_sym как раз используется для добавления к списку. При этом последовательность добавления элементов в список может быть произвольной.
Последний раз редактировалось Bill_ Сб апр 01, 2023 08:23:02, всего редактировалось 1 раз.

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

Сб апр 01, 2023 08:01:59

Связанный свитер, а список связный. А так, в целом верно. Разве что, память не только в куче можно взять.

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

Сб апр 01, 2023 08:24:16

Связанный свитер, а список связный. А так, в целом верно. Разве что, память не только в куче можно взять.

Исправил. :)

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

Сб апр 01, 2023 08:32:30

Ну, это всё понятно. пополнение списка у меня не предполагается. потому как это не настоящий форт, а всего-лишь способ интерпретации команд. Очень простой, причем. Почему я кошусь в сторону списков? Хочется избавиться от ограничения на длину строки. Для интерпретатора нуль-терминированная строка вполне подходит (тем более что у меня сейчас это сделано также - сравнение либо до '\0', либо до 12-го символа). Но массив, как вы сказали, имеет жёстко заданные размеры. И для того чтобы иметь возможность с этим справиться и может помочь список. Почему меня не устраивает применение "add_sym()" - из-за того, что тогда этот "список" будет в двух местах и в ПЗУ, и в ОЗУ. И еще нужно будет ждать пока он проиницализируется при старте.

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

Сб апр 01, 2023 08:59:51

Ну, это всё понятно. пополнение списка у меня не предполагается. потому как это не настоящий форт, а всего-лишь способ интерпретации команд. Очень простой, причем. Почему я кошусь в сторону списков? Хочется избавиться от ограничения на длину строки. Для интерпретатора нуль-терминированная строка вполне подходит (тем более что у меня сейчас это сделано также - сравнение либо до '\0', либо до 12-го символа). Но массив, как вы сказали, имеет жёстко заданные размеры. И для того чтобы иметь возможность с этим справиться и может помочь список. Почему меня не устраивает применение "add_sym()" - из-за того, что тогда этот "список" будет в двух местах и в ПЗУ, и в ОЗУ. И еще нужно будет ждать пока он проиницализируется при старте.

Используйте в элемента не массив символов, а указатель на него. Например, вместо
Код:
char word[12];

Код:
char *word;

Хотя инициализация массива будет выглядеть одинаково.

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

Сб апр 01, 2023 09:14:43

Почему я кошусь в сторону списков? Хочется избавиться от ограничения на длину строки.
У вас не хватает памяти? Пусть у вас три десятка элементов в среднем занятых на половину. 30х6=180 байт лишних. Вы уверены, что функции работы со связным списком займут меньше? Пока что это выглядит как преждевременная оптимизация.

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

Сб апр 01, 2023 10:58:37

В своё время (лет эдак 30 назад) Харий Буш говорил про винчестеры, что скорость их заполнения является константой и от объёма диска независящая. Так же и с памятью. Когда-то хватало 4 килобайт, сейчас и в 128 становится тесно. Хотя новый проект идёт на кристалле с 1.5М флеша и 0.5М озу. Но если серьёзно, хочется научиться разным техникам просто из интереса. И честно, мне плевать, сколько это памяти съест, а как это внятно написать в программе, чтобы было легче её "сопровождать". Я мог бы оставить строку с ограниченной длинной, и когда мне захотелось бы добавить слово "init_brakepath" тогда пришлось бы думать, сократить эту команду на 2 символа или в определении поменять 12 на 14. А так, я даже еще потерял 4 байта памяти на указатель к строке, но зато можно не ломать голову что делать.

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

Сб апр 01, 2023 11:01:11

Посмотрите, как делал я в своём проекте FlexMenu, там на этапе компиляции собираются массивы со строковыми константами произвольной длины. Там, кстати, есть и еще некоторые моменты, которые, как мне кажется, могут вам пригодиться. Если с макросами разберетесь, конечно...
А из проекта DigiScript можете использовать идею "массивов без явного описания и с инициализацией элементов в любом месте проекта". В этом проекте, кстати, я как раз интерпретатор и делал.

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

Сб апр 01, 2023 13:12:38

Красивого решения для работы со строковыми литералами на этапе компиляции нет даже в С++. Каждый раз решение под задачу приходится придумывать. Где-то память важна, где-то скорость доступа. Для USB-дескрипторов, например, вот так делаю.

1. Под каждый литерал глобальная структура. Макросы зло, но шаблоны и строковые литералы плохо дружат. Так что, пока макрос.
Изображение

2. Набиваем глобальных объектов
Изображение

3. Создаём массив указателей на глобальные объекты. Причём, тут даже жертвуем типизацией.
Изображение

4. Например, поиск в такой "структуре" по индексу
Изображение

И никакие связные списки для константных данных этапа компиляции, само собой, тут не нужны. Каждый инструмент предназначен для своих задач.

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

Пн май 01, 2023 10:01:56

Вопрос по ардуине. Есть функция в файле motors.cpp
Код:
void set_motor_pwm_frequency(int frequency) {
  switch (frequency) {
    case PWM_31250_HZ:
      // Divide by 1. frequency = 31.25 kHz;
...
      break;
    case PWM_3906_HZ:
      // Divide by 8. frequency = 3.91 kHz;
...
      break;
    case PWM_488_HZ:
    default:
      // Divide by 64. frequency = 488Hz;
...
      break;
  }
}


вызывается просто:
Код:
set_motor_pwm_frequency();


Я бы подумал, что установится частота 488Гц. Но в хидере она объявлена так:
Код:
/***
 * @brief set the motor pwn drive to one of three possible values
 */
void set_motor_pwm_frequency(int frequency = PWM_31250_HZ);
Это что значит? в плюсах я ничего не понимаю.

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

Пн май 01, 2023 10:38:05

"аргумент по умолчанию" - если ничего в аргументах не указывается пользователем будет использовано значение по умолчанию.
8)

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

Пн май 01, 2023 12:27:46

Но в хидере...

Не в хидере, а в хедере! "Карту купи..."

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

Пн май 01, 2023 12:57:11

ну, тогда уж правильно в хеде, без р

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

Пн май 01, 2023 13:10:45

Лучше бы по делу что написали, что произойдёт, если этот хи... пусть будет так: motors.h не будет включен в motors.cpp.

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

Пн май 01, 2023 14:37:21

ну как что? если заголовочный файл не будет подключен, область видимости объявленных в нем переменных и функций и значения дефайнов изменятся. В случае переменных и функций будет фатальная ошибка (впрочем, с функциями не всегда), в случае дефайнов - или фатальная, или логическая (если они где-то ещё такие же есть, но с другими значениями).
Здесь, если компилятор увидит функцию раньше вызова, ошибки не будет, но значение по умолчанию потеряется.

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

Сб май 06, 2023 22:24:25

Я вижу тут народ списки обсуждал. TL;DR.
Чем не устраивает плюсовый std::list? Список, конечная самая простая из сложных структур данных, но реализовывать функции для работы с ней с нуля муторно.
Кстати, совет, можно написать список полностью в максросах (как шаблоны на Си++) и тогда можно будет не копипастить их для разных типов данных.

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

Вс май 07, 2023 09:57:34

Чем не устраивает плюсовый std::list?

Думаю, что не ошибусь, если скажу, что среднему программисту гораздо проще написать свою реализацию списка (хоть на си, хоть на плюсах с шаблонами), чем свой кастомный аллокатор для STL-контейнеров.

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

Вт авг 01, 2023 21:38:04

Снова глупый вопрос. Для расчета тормозного пути мне надо вычислить разность квадратов a²-b². В целочисленных вычислениях я использовал формулу (a-b)*(a+b) - два сложения и одно умножение. А как лучше считать для плавующей точки, если у процессора есть FPU? имеется в виду - два умножения и сложение или два сложения и умножение - что будет быстрее.

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

Ср авг 02, 2023 07:20:34

Имхо, умножение однотактное маловероятно даже на FPU, а сложение однозначно однотактное.
Ответить