Jump to content

    
ViKo

Массив указателей на массив char

Recommended Posts

2 минуты назад, Arlleex сказал:

Подробнее? Под вечер я уже совсем не соображаю ничего =)

Фантазирую так. Создать тип - массив, инициализировать его данными. Массивом инициализировать тип - структуру. По размеру массива задавать в типе - структуре размер члена - массива.

Но так, чтобы сам массив не создавался. :wizard: 

Share this post


Link to post
Share on other sites
44 минуты назад, ViKo сказал:

Создать тип - массив, инициализировать его данными. Массивом инициализировать тип - структуру. По размеру массива задавать в типе - структуре размер члена - массива. 

В плюсах можно попробовать:

struct Glyph
{
	// шаблонный конструктор - умеет извлекать размер массива
	template<size_t N>
	Glyph(const uint8_t(&body)[N])
		: size(N)
		, data(&body[0])
	{}
	const size_t size;
	const uint8_t* data;
};

// символы
const uint8_t glyph_0[] = { 0, 1, 2, 3, 4, 5 };
const uint8_t glyph_1[] = { 1, 2, 3, 4, 5 };
const uint8_t glyph_2[] = { 2, 3, 4, 5 };

// сам шрифт
Glyph glyphs[] = {
	Glyph(glyph_0),
	Glyph(glyph_1),
	Glyph(glyph_2),
};

Вот ссылка на код, поиграться.

Share this post


Link to post
Share on other sites

Кабы для себя, я бы попробовал в C++. Но это для соседней темы. А в чем они там творят, нет желания разбираться. С глаз долой... 

За пример - спасибо. Непонятно, правда. Что это - body? 

Share this post


Link to post
Share on other sites

body - это ссылка на массив. Поскольку у оператора "[]" приоритет выше, чем у "&", приходится скобочки добавлять. Без скобок получится "массив ссылок", а это не то, что нам нужно (и вообще нельзя).

Share this post


Link to post
Share on other sites

Можно попробовать поиграться с препроцессором, но могут появиться 'мусорные' массивы (зависит от компилятора)

Основная идея - символы собираются в файле в виде набора макросов, например так (пусть файл называется def.file.inc):

DEF(BigCharSpace, bcrx_32, 0)
DEF(BigChar0, bcrx_11_10_11,
	bcrx_9_14_9,
	bcrx_7_18_7,
	bcrx_6_20_6,
	bcrx_5_22_5,
	bcrx_4_8_8_8_4,
	bcrx_3_7_12_7_3,
	bcrx_3_6_14_6_4,
	bcrx_2_6_16_6_2,
	bcrx_2_5_18_5_2,
	bcrx_1_6_18_6_1,
	bcrx_1_5_20_5_1, 25,
	bcrx_1_6_18_6_1,
	bcrx_2_5_18_5_2,
	bcrx_2_6_16_6_2,
	bcrx_3_6_14_6_4,
	bcrx_3_7_12_7_3,
	bcrx_4_8_8_8_4,
	bcrx_5_22_5,
	bcrx_6_20_6,
	bcrx_7_18_7,
	bcrx_9_14_9,
	bcrx_11_10_11, 0)
  

Потом определяете макрос DEF и делаете #include "def.file.inc"

#define DEF(name, ...) static char DummyArray##name[] = {__VA_ARGS__}; static const int Size##name = sizeof(DummyArray##name);
#include "def.file.inc"
#undef DEF
  
static const struct {
#define DEF(name, ...) uint8_t name[Size##name];
#include "def.file.inc"
} BigCharIndx;

... ну и т.д. 

 

Share this post


Link to post
Share on other sites
В 02.06.2020 в 22:38, ViKo сказал:

Создать тип - массив, инициализировать его данными.

Тип нельзя инициализировать. Инициализировать можно объект какого-то типа. Без создания объекта, выделения под него памяти, инициализация невозможна. Тип - это абстракция, схема, описание. Он не занимает места в памяти, следовательно, инициализировать тип нельзя - некуда записывать значения, память то не выделена.

В 02.06.2020 в 22:38, ViKo сказал:

По размеру массива задавать в типе - структуре размер члена - массива.

Это можно.

В 02.06.2020 в 22:38, ViKo сказал:

Массивом инициализировать тип - структуру.

Снова, инициализировать не тип, а объект этой структуры. Это придется делать явно, через стандартный синтаксис инициализации членов структуры. Т.е. значения для инициализации члена структуры - массива надо будет прописывать явно в месте его инициализации. Не нравится - создайте макрос:

#define ARR {5,2,7,6}

и используйте его в качестве инициализатора для члена структуры - массива.

Share this post


Link to post
Share on other sites
13 минут назад, Darth Vader сказал:

Тип нельзя инициализировать. Инициализировать можно объект какого-то типа.

Это понятно. Это в краткой форме - создать тип (отдельно), инициализировать его (отдельно).

Проблема в том, останутся ли ненужные массивы после компиляции, или уберутся.
Вообще, с этим я почти закончил. Есть мысли, как ускорить сами функции рисования шрифта. А сама структура уже написана, всё скомпилировалось и в симуляторе прогналось.

Share this post


Link to post
Share on other sites
В 02.06.2020 в 20:46, Arlleex сказал:

Пустые скобки будут равносильны трактовке элемента как указателя.

Неправда. Пустые скобки будут равносильны массиву неизвестного размера (incomplete array), который может располагаться только в конце структуры (flexible array member). Его размер определяется в момент определения структуры. Почему именно только в конце - становится понтяно, если поставить себя на место компилятора, который при компиляции другого файла увидит только объявление структуры из заголовочного файла, но не определение.

Share this post


Link to post
Share on other sites
1 час назад, ViKo сказал:

Это в краткой форме - создать тип (отдельно), инициализировать его (отдельно).

Снова инициализировать тип :acute:

Правильно:

Описать тип. Создать и инициализировать объект этого типа.

1 час назад, ViKo сказал:

Проблема в том, останутся ли ненужные массивы после компиляции, или уберутся.

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

1 час назад, Сергей Борщ сказал:

Его размер определяется в момент определения структуры. Почему именно только в конце - становится понтяно, если поставить себя на место компилятора, который при компиляции другого файла увидит только объявление структуры из заголовочного файла, но не определение

А как компилятор вычислит значение выражения: sizeof(имя_типа_структуры)? Получается, размер для типа будет неизвестен. А размер объектов этого типа может быть разным.

Share this post


Link to post
Share on other sites
Только что, Darth Vader сказал:

Снова инициализировать тип

:girl_cray2: Создать тип - массив (отдельно), инициализировать его (массив)(отдельно).

Только что, Darth Vader сказал:

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

Я не хочу зависеть от совести компилятора или тех, кто его создал.

Share this post


Link to post
Share on other sites
32 минуты назад, Darth Vader сказал:

А как компилятор вычислит значение выражения: sizeof(имя_типа_структуры)?

Он будет считать размер массива равным нулю. 

Share this post


Link to post
Share on other sites
9 часов назад, Сергей Борщ сказал:

Неправда. Пустые скобки будут равносильны массиву неизвестного размера (incomplete array), который может располагаться только в конце структуры (flexible array member). Его размер определяется в момент определения структуры. Почему именно только в конце - становится понтяно, если поставить себя на место компилятора, который при компиляции другого файла увидит только объявление структуры из заголовочного файла, но не определение.

Спасибо, Ваш комментарий подвиг меня гуглить, т.к. на практике я такими конструкциями не пользуюсь, а в голове почему-то осталась именно та инфа, которую я изложил.

К сожалению, мне и сейчас не понятно, зачем вообще иметь структуру с последним массивом гибкого размера.

Ибо размер возвращаемый sizeof(str) такой структуры будет равен размеру структуры без этого массива (а-ля пустое место, 0 байт).

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

Везде приводят пример с размещаемой областью из alloc() в этот массив но это из области какого-то бреда, ИМХО.

Проще, определеннее и всегда предсказуемо тупо дать указатель на начальный элемент нужного массива.

Share this post


Link to post
Share on other sites
49 минут назад, Arlleex сказал:

К сожалению, мне и сейчас не понятно, зачем вообще иметь структуру с последним массивом гибкого размера.

Я такие структуры использую для описания некоторых пакетов данных. В структуре хранится заголовок пакета, в массиве байтов - данные. Поскольку размер данных заранее неизвестен - располагаю их в куче, выделяя под них sizeof(packet) + data_size байтов. Память под такой пакет выделяется одним куском, нет лишней неявной операции разыменования указателя на данные. Или для разбора принятых пакетов.

что-то типа такого:

struct header
{
   ... 
};

struct packet_int
{
   header Header;
   int    Data;
};

struct generic_packet
{
    header Header;
    uint8_t Raw_data[];
};

generic_packet * pGeneric_packet = (generic_packet *)Rx_buffer;

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

 

Share this post


Link to post
Share on other sites
6 минут назад, Сергей Борщ сказал:

Я такие структуры использую для описания некоторых пакетов данных...

А, я, кажется, допер. Это действительно удобно.

Share this post


Link to post
Share on other sites
4 hours ago, Сергей Борщ said:

 


struct header
{
   ... 
};

struct packet_int
{
   header Header;
   int    Data;
};

struct generic_packet
{
    header Header;
    uint8_t Raw_data[];
};

generic_packet * pGeneric_packet = (generic_packet *)Rx_buffer;

 

Мне тоже такие описания нравятся, только компиляторы на них предупреждения выдают (((

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.