Автор Тема: Проблемы с Си  (Прочитано 1857 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« : 31 Март 2021, 18:00:52 »
Спрашиваю тут, т.к. не могу найти ответ в Гугле, даже не знаю как точно сформулировать вопрос.
На специализированных сайтах по программированию регистрироваться не охота, раз на родном Эмуленде есть оффтоп-тема.

1 Как выделить память под определённый тип элемента по ситуации?

Допустим, в одном случае программа выяснит, что потребуется выделить массив типа int, а в следующий раз char. Потом с этим массивом работать.
if'ы на каждый тип считаю дикостью. Вижу только вариант выделить char и "менять" указатель на нужный тип, прыгать по элементам массива через указатель-переменную. Но проблемой будет доставать что-то крупнее char, например для int придётся вытаскивать 4 байта, каждый раз сдвигая его в переменной и прибавляя:
char массив[4];
int a = (((((массив +3) << 8) +массив +2) << 8) +массив +1 << 8) +массив;

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

2 Как присвоить динамичный массив в статичный?
Нужен статичный массив, каждый элемент которого - указатель на динамичный массив.

Так не работает:
int массив[100];
массив[0] = new int[10];

Так тоже:
int массив[100];
int* test[10];
массив[0] = &test;


До этого нормально работал с двумерными динамичными массивами и проблем не знал. Опыта с указателями пока нет.
« Последнее редактирование: 25 Сентябрь 2021, 18:06:19 от perfect_genius »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5004
    • Просмотр профиля
Массивы в Си / С++
« Ответ #1 : 31 Март 2021, 18:48:11 »
2 Как присвоить динамичный массив в статичный?
    int* arr[10] = {0}; // Массив из 10 указателей на int
    arr[0] = new int[5]; // Выделить память на 5 int и присвоить его указатель
    arr[0][0] = 10;
    cout << arr[0][0] << endl;
    delete [] arr[0];
Надеюсь не ошибся. UPD: В современном подходе используют всякие умные указатели, которые сами удаляют память.
1 Как выделить память под определённый тип элемента по ситуации?
Лучше конкретную задачу озвучить, которую нужно решить. Вы озвучили "как" хотите решать, а не "что".
да и другие сложности ожидаются, наверно.
Например, что int может быть разного размера в разных системах, поэтому я избегаю его использования. И порядок байтов разный в Little-Endian и Big-Endian системах, хотя на современных системах везде Litttle-Endian, просто код становится непереносимый, но для "переносимости" нужно использовать библиотеки, которые в конечном счёте используют определения в зависимости от известных им системах.
--------
UPD2: Напомню, что тип char в C и C++ может быть как знаковым, так и беззнаковым в зависимости от компилятора. Если вы захотите баловаться с указатели, то советую прочитать про Strict Aliasing.
« Последнее редактирование: 31 Март 2021, 19:03:43 от Sharpnull »

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9372
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Массивы в Си / С++
« Ответ #2 : 31 Март 2021, 19:07:49 »
perfect_genius,
1. языки С/C++ со строгой типизацией, т.е. код должен быть явно для определенного типа данных. есть шаблоны/темплейты, но это именно что шаблоны, и в конечном итоге должны использоваться с заданными типами данных.
то есть, по-красивому на С не выйдет

Цитата
. Но проблемой будет доставать что-то крупнее char, например для int придётся вытаскивать 4 байта, каждый раз сдвигая его в переменной и прибавляя:
char массив[4];
int a = (((((массив +3) << 8) +массив +2) << 8) +массив +1 << 8) +массив;
можно проще, типа так:
char массив[4];
int a = *(int*)&массив[0];

2. лучше поразбирайся с указателями, а еще лучше с STL - использовать "обычные" массивы в наше время - моветон, вместо них лучше и удобнее std::vector

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Массивы в Си / С++
« Ответ #3 : 31 Март 2021, 19:56:27 »
Sharpnull, ты и сюда заглядываешь?! Да ты везде, похоже :)

Цитата
int* arr[10] = {0}; // Массив из 10 указателей на int
arr[0] = new int[5]; // Выделить память на 5 int и присвоить его указатель
arr[0][0] = 10;
Даже так пробовал и не понял, почему это работает, хотел спросить тоже тут.

Почему int* arr[10] = {0}; не динамичный массив? o_0 Тупо потому, что в квадратных скобках указан размер?
Получается, что первая звёздочка в int** arr[10] = {0}; будет относиться к содержимому массива, и только вторая звёздочка указывает на тип самого этого массива? :ohmy:
И зачем обнулять первый элемент, если далее присваивается указатель?

О переносимости мне рано думать, сейчас Win7 32 бита, VS2010 если что.

MetalliC, спасибо за int a = *(int*)&массив[0];. В своё время перебрал много вариантов в Сети и такой не попадался. Выглядит он жутко, но хоть короткий :)

Насчёт векторов - да, везде их упоминают и я даже почитал про них перед тем, как задать сюда вопрос. Но как встретил, что они по умолчанию обнуляются, так пока и отложил это дело - у меня приоритет на производительности сейчас, нет времени разбираться во всех тонкостях и как с ними сделать именно статичный массив. Но удобства вижу, надоело стрелять себе в ногу.

Задача по первому вопросу такая - загружаю файл в динамичный массив, выделяю второй такого же размера и заполняю его указателями - каждый символ файла указывает на следующий такой же. Получается, что дальность указателя не более 256, и если файл размером больше 256, то дальность char-указателя может не хватить и надо бы выделять тип вместительней. Т.е. программа должна выделить массив с типом в соответствии с размером файла.
« Последнее редактирование: 31 Март 2021, 20:31:20 от perfect_genius »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5004
    • Просмотр профиля
Массивы в Си / С++
« Ответ #4 : 31 Март 2021, 20:18:29 »
Почему int* arr[10] = {0}; не динамичный массив?
Потому что так статичный массив определяется: тип имя[размер]. "int* arr" - это просто указатель на int, когда вы пишите int* arr = new int[10], то сохраняете указатель на динамический массив.
И зачем обнулять первый элемент, если далее присваивается указатель?
Обнуляются все указатели в массиве. Если не писать = {0}, то там будет мусор.
int a = *(int*)&массив[0];
Можно так: int a = *(int*)arr;
у меня приоритет на производительности сейчас
Вы потратите больше времени на отлов ошибок и утечек памяти, а скорости не заметите, преждевременная оптимизация - зло. К тому же, на vector можно использовать разные полезные алгоритмы, что уменьшит количество бесполезного кода.
Задача по первому вопросу такая
Я всё ещё не понимаю зачем... (UPD: хотя не важно) Лучше используйте просто ptrdiff_t или size_t, они созданы для представления индексов массива, и, грубо говоря, для 32-битной системы они 32-битные, а для 64-битной - 64-битные (UPD2: хотел сказать в зависимости от того, на какую платформу скомпилированы, x86 приложение не работает с 64-битными указатели, очевидно). Если вы не собираетесь их сохранять в файл или передавать, то проблем не будет. Нет смысла экономить.
--------
UPD2: Вы добавили:
Получается, что первая звёздочка в int** arr[10] = {0}; будет относиться к содержимому массива, и только вторая звёздочка указывает на тип самого этого массива?
int** arr; - указатель на указатель на int. Таким образом int** arr[10]; - массив из 10 указателей на указатель на int, такое нужно если только вам нужно 10 двумерных динамических массивов.
« Последнее редактирование: 31 Март 2021, 20:37:57 от Sharpnull »

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Массивы в Си / С++
« Ответ #5 : 31 Март 2021, 21:19:22 »
Цитата
Обнуляются все указатели в массиве.
На Хабре как-то разбирались с этим, и выяснилось, что таки обнуляется только первый. Из-за чего я после создания массива заполняю его memset'ом. Вроде бы опять зависит от компилятора или это отличие между Си и С++.
И всё-равно зачем обнулять, если он тут же будет заполняться?

Цитата
Можно так: int a = *(int*)arr;
Но тогда как указать на любое место в массиве?

Цитата
Вы потратите больше времени на отлов ошибок и утечек памяти
Время на изучение векторов тоже могу потратить много? Как с ними сделать статический массив указателей?

Цитата
Я всё ещё не понимаю зачем
Чтобы не проходить весь файл в поисках символа. Получается, я создаю однонаправленные списки на каждый символ.

Цитата
Нет смысла экономить.
Получается ведь, что с int памяти на указатели понадобится в 4 раза больше, чем сам файл. А если он гигабайт? Вот и ищу как можно оптимизировать потребление памяти.

Добавлено позже:
Цитата
Но тогда как указать на любое место в массиве?
Вот так красивее всего, похоже:
int a = *(int*)(массив +0);
« Последнее редактирование: 31 Март 2021, 21:33:53 от perfect_genius »

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5004
    • Просмотр профиля
Массивы в Си / С++
« Ответ #6 : 31 Март 2021, 21:56:31 »
На Хабре как-то разбирались с этим, и выяснилось, что таки обнуляется только первый.
Нет, в C и C++ будет обнуление. Может вы путаете с чем-то другим, я бы посмотрел на эту статью. Обнуляю просто так, неважно.
Но тогда как указать на любое место в массиве?
Я привёл вариант для 0-го элемента, очевидно. Можно и так: int a = *(int*)(arr + 10);, где 10 - смещение размером char, или так: int a = *((int*)arr + 11);, где 11 - смещение размером int, или так: int a = ((int*)arr)[12];, где 12 - тоже смещение как int.
Время на изучение векторов тоже могу потратить много? Как с ними сделать статический массив указателей?
Его нужно изучать, если вам нужен C++ без отстреленных ног. Я не понимаю, что вы имеете в виду под "статический массив указателей", сам vector - это тип, который выделяет память динамически в зависимости от потребностей, чтобы не писать new/delete и не производить всякие копирования, если нужно больше памяти. Я вам приводил пример: int* arr[10];, предполагая, что вам нужен не динамический массив, т. е. память выделяется на стеке, если внутри функций, или глобально, когда со словом static или определено глобально (вне функций).
А если он гигабайт? Вот и ищу как можно оптимизировать потребление памяти.
Тогда если не хотите if, можно шаблоны или шаблонные функции использовать (как уже упоминали), тогда один и тот же алгоритм будет работать с разными типами (целые числа размером 1, 2, 4 байта). Конечно там нужно быть аккуратным.

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9372
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Массивы в Си / С++
« Ответ #7 : 01 Апрель 2021, 00:51:20 »
Можно так: int a = *(int*)arr;
можно но не нужно, вариант с &arr[0] считается более здоровым, например на случай если вдруг массив сменим на вектор

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #8 : 25 Сентябрь 2021, 18:15:03 »
Снова нашёл странное.

Мне нужен массив структур в массиве структур, не динамичные.

struct Структура_1 {
   int тест_1;

   struct Структура_2 {
      int тест_2;
   };

} массив_структур[10];


Мне надо, чтобы в каждой из 10 структур Структура_2 или массив (тест_2) в ней были разного количества, заполняю каждую прям там-же после объявления (часть[n] = { 5 };).
Если бы они были динамичные, то было бы легко, просто каждый раз выделяя разное количество и присваивая. А как быть со статичным массивом?
Никак не могу найти в Гугле ничего.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5004
    • Просмотр профиля
Проблемы с Си
« Ответ #9 : 25 Сентябрь 2021, 18:58:58 »
Мне нужен массив структур в массиве структур, не динамичные.
Я не понял что вы хотите. Если решили каким-то образом иметь массив структур с фиксированным массивом, который имеет разные размеры в зависимости от порядка в главном массиве, то не получится. Любая структуры всегда имеет одинаковый размер в памяти, иначе нельзя было бы создать массивы.
Если нужен "массив структур в массиве структур" с фиксированными массивами, то например (в языке C добавлять struct или typedef):
struct A {
  int a;
};
struct B {
  int b;
  A arr[10];
};
// Или
struct C {
  int c;
  struct {
    int d;
  } arr[10];
};
...
B arr[3];
arr[2].arr[9].a = 10;
C arr2[3];
arr2[2].arr[9].d = 10;

Оффлайн Yoti

  • Пользователь
  • Сообщений: 4420
  • Пол: Мужской
  • Не тро-гай ме-ня
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #10 : 26 Сентябрь 2021, 22:56:13 »
не динамичные
Чтобы на месте сидели и никуда не дёргались?

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #11 : 27 Сентябрь 2021, 22:50:42 »
Да, только для чтения. "Фиксированный", подсказывает мне Sharpnull. Ещё он нашёл Flexible array member:

struct Машина {
      int количество_дверей;
      struct дверь {
         int спереди, сзади, слева, справа;
      } дверь[];
   } машина = {
   4, { 0, 0, 1, 1,   0, 0, 1, 1,   0, 0, 1, 1,   0, 0, 1, 2,} };

int test = машина.дверь[3].справа;
//test == 2;

Но им, почему-то, нельзя создать массив структур Машина, даже динамический, чтобы можно было "машина[5].дверь[3].справа;"
В итоге я сдался.
Мягко говоря, удивлён, что это не типичная задача.

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #12 : 12 Октябрь 2021, 16:08:40 »
Снова мне "везёт" как новичку.
Мне нужен был случайный доступ к элементу структуры, а такого в Си нет :neznayu:
struct A {
  int a; char b; short c;
};
Можно накостылить с указателями, но это сложно и ненадёжно.
Sharpnull пишет:
Цитата
В C++ можно использовать рефлексию, ... она похоже сложная, чем в C#, например. Она должна позволять делать разные хитрые вещи с полями структур/классов.

"Всемогущий Си" снова разочаровал. Его, вроде бы, продолжают развивать и сейчас, но такие базовые вещи всё ещё отсутствуют, будто я прошу чего-то извращённого. Да чего там, даже что-то типа:
char test[] = {C:\test\test_img.jpg};
всё ещё обсуждалось, оказывается, и думают вот принять :ohmy:

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9372
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Проблемы с Си
« Ответ #13 : 12 Октябрь 2021, 16:55:31 »
Снова мне "везёт" как новичку.
Мне нужен был случайный доступ к элементу структуры, а такого в Си нет :neznayu:
struct A {
  int a; char b; short c;
};
Можно накостылить с указателями, но это сложно и ненадёжно.

книжки по С/С++ хоть пробовал читать ?
то что (как я предполагаю) ты хочешь можно сделать через union или более современный STL-ный std::variant

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #14 : 12 Октябрь 2021, 21:09:59 »
Я хотел изучить Си перед С++, поэтому пока только с ним вожусь. Вопросы в Интернете изучать быстрее и эффективнее оказалось, чем читать книги. Но всякие сетевые самоучители читал уже много, ответов не нахожу.

В итоге Sharpnull нашёл решение просто создать массив из структур в структуре, тогда и можно свободно обращаться к любой хоть случайно:

struct arr{
  int a; char b; short c;
} arr[4];

int test = arr[random].a;

Из-за предыдущей проблемы с массивами структур разного размера про этот простой вариант я что-то даже не подумал :wall:
Ну и он снова не удержался рассказать, что в более новых языках все эти удобства есть :)

Оффлайн Skay

  • Пользователь
  • Сообщений: 4115
  • Пол: Мужской
    • Просмотр профиля
Проблемы с Си
« Ответ #15 : 13 Октябрь 2021, 10:52:24 »
perfect_genius, уф. лучшеб не за какой то язык цеплялся, а пошел бы книжки по алгоритмам, структурам данных почитал. язык с его синтаксическим сахаром дело десятое, выбирается уже под конркетные задачи.
Я хотел изучить Си перед С++, поэтому пока только с ним вожусь.
не имеет смысла, никакой приемственности нет, только синтаксис, да и то..
Плюсы очень широкие, сейчас это скорее набор разных парадигм, так как в контексте одного языка можно писать очень по разному и разными средствами. То же подмножество уровня Си можно сразу в рамках плюсов изучать.

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #16 : 13 Октябрь 2021, 20:07:55 »
Насчёт массива структур с массивами/структурами разного размера.

Случайно наткнулся на карты Метроида с Кастлванией



и подумал о том, как они хранятся в роме? Ведь пустоты - слишком расточительно для тех лет. Может, там что-то хранится?
И вот вдруг вспомнил про массива структур с массивами/структурами разного размера. Ведь можно сделать все структуры по размеру самого большого из них, а все пустоты использовать для других констант/данных. Такую структуру даже можно "проткнуть" разреженным массивом - каждый элемент необязательно будет со смещением в 4 для int, например (arr + 4, arr + 8, arr + 12...), а больше. Ну и обычные массивы в больших пустотах.
Как вам идея? Или уже встречали такое? Наверно, можно такое как-то организовать указаниями выравнивания для компилятора?

Оффлайн Skay

  • Пользователь
  • Сообщений: 4115
  • Пол: Мужской
    • Просмотр профиля
Проблемы с Си
« Ответ #17 : 14 Октябрь 2021, 12:06:21 »
perfect_genius, а зачем всю карту грузить в память? вспомни переходы между локациями.
Можно сходить хотя бы, к примеру, на канал к Санчезу, где он реверсил старые консольные игры, и посмотрел бы как они делали хранение уровней и тд. Прежде чем выдумывать своё сначала стоит посмотреть кто и как раньше реализовывал.

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #18 : 14 Октябрь 2021, 21:42:02 »
Skay, не, я не про игру, а про Си и компилятор, про упаковку и выравнивание данных. Карта игры лишь надоумила, это я потом посмотрю.

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9372
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Проблемы с Си
« Ответ #19 : 16 Октябрь 2021, 01:47:16 »
perfect_genius, тебе не зря посоветовали почитать книжки по алгоритмам, там ты можешь узнать много нового (и не будешь изобретать велосипеды ;) ), в том числе про различные способы хранения данных. кроме банальных массивов бывают еще например связные списки, которые вполне подходят для кишко-подобных цепочек игровых локаций.

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #20 : 16 Октябрь 2021, 18:58:41 »
Отстаньте уже от карты Метроида, зря его привёл :lol: Я просто забыл, что в Метроиде не видна вся карта, что там подходишь к двери и начинает загрузка других частей карты. Это оффтоп уже.

Попробую снова объяснить идею массива структур нефиксированного размера в Си (или ассемблере), что даёт и удобство человеку и оптимизацию по скорости.

В Си есть Flexible array member:

struct массив_структур {
    int a;           // должно быть что-то до массива. Обычно, длина массива ниже.
    double b[];  //должен быть последним
};


Но из него нельзя сделать массив:

struct массив_структур {
    int a;           // должно быть что-то до массива. Обычно, длина массива ниже.
    double b[];  //должен быть последним
} [] массив_структур;


Мне уже интересно как это сделано внутри, в будущем гляну. Так вот моя идея массива структур из Flexible array member - пусть в ней длина структуры берётся от самой длинной (например, b равен 10), тогда в других элементах этого массива, которые меньше 10, будут пустоты. Вот в них компилятор пусть и вставляет другие данные программы, чтобы зря не терять места. В итоге и человек может удобнее оформлять свой код, и программе не надо на старте выделять память в куче и записывать туда данные, и обращаться к ним будет не через указатель + база + смещение, а только база + смещение. Выглядит как win-win, так что буду проверять идею, проблемы могут возникнуть при упаковке данных в эти дыры.

Онлайн Mr2

  • Пользователь
  • Сообщений: 1592
  • Пол: Мужской
  • Free roaming sorcerer
    • Facebook
    • Просмотр профиля
Проблемы с Си
« Ответ #21 : 16 Октябрь 2021, 19:21:32 »
perfect_genius, в Си нет динамических структур(struct), успокойся уже. Размер структуры должен быть фиксированным, можешь хоть из штанов выпрыгнуть, а по твоему не будет!  :P

Оффлайн Skay

  • Пользователь
  • Сообщений: 4115
  • Пол: Мужской
    • Просмотр профиля
Проблемы с Си
« Ответ #22 : 17 Октябрь 2021, 09:20:54 »
зря его привёл
да не важно, пройди какой нибудь курс по структурам и алгоритмам данных (хоть на степике), чтоб еще и верно оценивать что будет "быстее", а не просто так на глаз потмоу что ты так надумал.

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #23 : 17 Октябрь 2021, 12:44:11 »
Skay, "быстрее" что - разработка или код?
Заметил, что я переименовал тему исключительно в Си? Я понимаю, что на С++ и других языках есть много удобств, а тут я касаюсь только Си, поэтому не стоит упоминать другое и зачем-то посылать читать структуры и алгоритмы. Я упомянул мои проблемы с Си, а не с выбором языка. Тут много кто дружит с Си и с ещё более низким уровнем, поэтому и уместнее было спрашивать здесь.
 Си продолжает развиваться, вон скоро бинарники можно будет вставлять в исполнительный файл. Поэтому и у меня вот рассуждения как что-то в нм можно улучшить. На Хабре встречал несколько людей, которые предпочитают Си вместо С++, и я тоже пока буду.

Цитата
на глаз потмоу что ты так надумал.
Т.е. работа со статичным массивом не быстрее, чем с динамичным? o_0

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9372
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Проблемы с Си
« Ответ #24 : 17 Октябрь 2021, 19:49:15 »
Я понимаю, что на С++ и других языках есть много удобств, а тут я касаюсь только Си, поэтому не стоит упоминать другое и зачем-то посылать читать структуры и алгоритмы.
потому что в С++ не много удобств, а обширная стандартная библиотека (STL), с кучей всякого разного полезного, чтоб не приходилось махать каменным топором или изобретать велосипеды 50-летней давности.

к слову, в C тоже есть стандартная библиотека.

Т.е. работа со статичным массивом не быстрее, чем с динамичным
а что это в твоём понимании и в чём разница ?

может ты все же почитаешь книжки по алгоритмам и самому языку, чтоб ты говорил на одном языке с нами и использовал общепринятую терминологию, и можно было понять о чем вообще говоришь ?
« Последнее редактирование: 17 Октябрь 2021, 19:58:53 от MetalliC »

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9372
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Проблемы с Си
« Ответ #25 : 17 Октябрь 2021, 19:52:43 »
В Си есть Flexible array member:

struct массив_структур {
    int a;           // должно быть что-то до массива. Обычно, длина массива ниже.
    double b[];  //должен быть последним
};

нет нету.
double b[] - будет указателем, т.е. эквивалентно записи double *b
а собсно память для него ты должен будешь выделить сам, на куче или на стеке.

Онлайн Mr2

  • Пользователь
  • Сообщений: 1592
  • Пол: Мужской
  • Free roaming sorcerer
    • Facebook
    • Просмотр профиля
Проблемы с Си
« Ответ #26 : 17 Октябрь 2021, 21:20:50 »
может ты все же почитаешь книжки по алгоритмам и самому языку
Чукча не читатель, Чукча - писатель. :lol:

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1144
    • ВКонтакте
    • Steam
    • Просмотр профиля
Проблемы с Си
« Ответ #27 : 19 Октябрь 2021, 16:02:59 »
double b[] - будет указателем, т.е. эквивалентно записи double *b
а собсно память для него ты должен будешь выделить сам, на куче или на стеке.
Будет константным указателем, т.е. быстрее, чем double* b. Этот массив я заполняю там-же в коде программы.

Цитата
Advantages of the flexible array:

save space
save one indirection
allocate in one step
arr is never NULL
Conversely, making arr a pointer requires separate allocation of the array it points to. This disadvantage in size, code and speed comes with compensations.

Advantages of the pointer version:

arr can be NULL to specify no data.
arr can be allocated on demand, when the actual size is known.
arr can be reallocated easily.