Как переключать контекст я и так знаю - там проблема
в цикличной зависимости определений друг от друга. Которая не проблема для, говорят, 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 раз.