Перейти к содержанию
    

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

x893, я использую в данном проекте C99, поскольку передаю другому лицу. 

const меня от создания самих массивов, структуры не спасёт. 

А если typedef задать и для массивов пикселей символов, и для структуры? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, ViKo сказал:

Отдельно имеется массив смещений для каждого массива строк символов из структуры. К адресу структуры прибавляется смещение, так попадаем в массив. А массив смещений упорядочен по коду символов (цифр и др). 

А, понял. То есть смысла собственно в структуре нет, можно слепить все символы просто в массив?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А, понял. То есть смысла собственно в структуре нет, можно слепить все символы просто в массив?

Я не нашел иного способа для определения смещения начала каждого символа в массиве. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Я не нашел иного способа для нахождения смещения начала каждого символа в массиве. 

int Fv(int ix) //ix - индекс символа
{
  #define ZNAK_0 {1,2,3,4,5}
  #define ZNAK_1 {1,2,3,4,5,6}
  #define ZNAK_2 {1,2,3,4,5,6,7}
  #define m1(x) static u8 const concatAB(dummyZnak, x)[] = concatAB(ZNAK_, x)
//#define concatAB_(a, b) a##b
//#define concatAB(a, b) concatAB_(a, b)
  m1(0);
  m1(1);
  m1(2);
  struct Znakogenerator {
    u8 znak_0[sizeof(dummyZnak0)];
    u8 znak_1[sizeof(dummyZnak1)];
    u8 znak_2[sizeof(dummyZnak2)];
  } static const znakogenerator = {
    .znak_0 = ZNAK_0,
    .znak_1 = ZNAK_1,
    .znak_2 = ZNAK_2
  };
  static u16 const offs[] = {
    offsetof(Znakogenerator, znak_0),
    offsetof(Znakogenerator, znak_1),
    offsetof(Znakogenerator, znak_2)
  };
//#define offsetof(typ, member) (size_t)&(((typ *)NULL)->member)
  return offs[ix]; //смещение начала символа ix
}

Это?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 6/7/2020 at 11:11 AM, ViKo said:

Я не нашел иного способа для определения смещения начала каждого символа в массиве. 

Я же выше вам приводил пример описания структуры символа и шрифта целиком.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 6/7/2020 at 8:58 AM, ViKo said:

x893, я использую в данном проекте C99, поскольку передаю другому лицу. 

const меня от создания самих массивов, структуры не спасёт. 

А если typedef задать и для массивов пикселей символов, и для структуры? 

const тут для размещения во flash а не ram. Можете выкинуть const - суть от этого не изменится.

Передавать можно любому лицу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 05.06.2020 в 09:40, Сергей Борщ сказал:

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

Подниму тему)) Наткнулся щас на необходимость соорудить структуру с гибким размером элементов внутри нее. Это в Си, не плюсы.

typedef struct {
  GPIO_TypeDef *gpio;
  
  u16           pinNum,
                pinMsk,
                mode;
} sGPIOItem;

typedef struct {
  u32       size;
  
  sGPIOItem item[];
} sGPIOList;


static sGPIOList const GPIOMainBoard = {
  sizeof(GPIOMainBoard.item)/sizeof(GPIOMainBoard.item[0]),
  
  {
    {GPIOB, 10, B10, OUT_PP_10MHZ},
    
    {GPIOA,  5, B5,  IN_NOPULL},
    {GPIOA,  4, B4,  IN_NOPULL},
    {GPIOB,  1, B1,  OUT_PP_10MHZ}
    ...
  }
};


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

Естественно, компилятор ругается на строчку sizeof(GPIOMainBoard.item)/sizeof(GPIOMainBoard.item[0]), мол, invalid application of ‘sizeof’ to incomplete type ‘const sGPIOItem[]’.

Соответственно, атрибуты типа sGPIOList (его размер, в частности) остаются неизменными вне зависимости от дальнейшего объявления конкретного экземпляра. Его размер будет равен размеру u32 size.

Значит и sizeof(GPIOMainBoard) будет просто равен этому же u32. Жаль, конечно, что есть такое логическое западло. Хотелось автоматически заполнять размеры структуры, как никак. Щас просто пишется число, глазами считаются строчки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, Arlleex said:

Щас просто пишется число, глазами считаются строчки.

Сделайте NULL-terminated список. Конечно, есть шанс этот NULL забыть, зато считать не придется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, Arlleex said:

Это в Си, не плюсы.

добро пожаловать в волшебный мир препроцессора C...

 

#define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), (sGPIOItem[]){__VA_ARGS__}}
 
sGPIOList gpio = STRUCT_INIT(
    {GPIOB, 10, B10, OUT_PP_10MHZ},
    {GPIOA,  5, B5,  IN_NOPULL},
    {GPIOA,  4, B4,  IN_NOPULL},
    {GPIOB,  1, B1,  OUT_PP_10MHZ}
);
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 минуту назад, aaarrr сказал:

Сделайте NULL-terminated список. Конечно, есть шанс этот NULL забыть, зато считать не придется.

Если я правильно Вас понял, Вы имели в виду добавить в структуру Item-а еще одно поле, некий флажок. У обычных полей пусть он будет 0, а у самого крайнего 1, а дальше в цикле не пропустить этот самый 1? Или вон у меня указатель на GPIO есть, туда NULL вписать, а-ля список закончен.

 

5 минут назад, _pv сказал:

добро пожаловать в волшебный мир препроцессора C...

Как вариант, конечно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, Arlleex said:

Или вон у меня указатель на GPIO есть, туда NULL вписать, а-ля список закончен.

Именно так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

добро пожаловать в волшебный мир препроцессора C...

#define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), (sGPIOItem[]){__VA_ARGS__}}
sGPIOList gpio = STRUCT_INIT(
    {GPIOB, 10, B10, OUT_PP_10MHZ},
    {GPIOA,  5, B5,  IN_NOPULL},
    {GPIOA,  4, B4,  IN_NOPULL},
    {GPIOB,  1, B1,  OUT_PP_10MHZ}
);
 

И какой компилятор позволяет такое? IAR ожидаемо выдаёт ошибку: "cast to incomplete array type "sGPIOItem []" is not allowed".

 

Имхо - без создания экземпляра массива так работать не будет. Я много раз пользовался подобным способом, но с созданием фейкового экземпляра массива.

Вот как реализую аналогичную задачу в одном из проектов:

Спойлер
//USB Configuration Descriptor
//All Descriptors (Configuration, Interface, Endpoint, Class, Vendor)
#define USB_CONFIG_DESCRIPTOR(typ, obj, dtyp) \
struct typ {                                                                                              \
  UsbCfgDesc cfg;                                                                                         \
  UsbIfaceDesc if0;                                                                                       \
  UsbIfaceDesc if1;                                                                                       \
  UsbEpDesc if1ep0;                                                                                       \
  UsbIfaceDesc if2;                                                                                       \
  UsbEpDesc if2ep0;                                                                                       \
  u8 terminator;                                                                                          \
} const obj __align4 = {                                                                                  \
  .cfg.bLength             = sizeof(UsbCfgDesc),                                                          \
  .cfg.bDescriptorType     = dtyp,                                                                        \
  .cfg.wTotalLength        = sizeof(typ) - sizeof(typ::terminator),                                       \
  .cfg.bNumInterfaces      = 1,                                                                           \
  .cfg.bConfigurationValue = 1,                                                                           \
  .cfg.iConfiguration      = 0,                                                                           \
  .cfg.bmAttr              = USB_CONFIG_BUS_POWERED,                                                      \
  .cfg.bMaxPower           = USB_CONFIG_POWER_MA(100),                                                    \
                                                                                                          \
  .if0.bLength             = sizeof(UsbIfaceDesc),                                                        \
  .if0.bDescriptorType     = USB_DESC_TYP_INTERFACE,                                                      \
  .if0.bInterfaceNumber    = 0,                                                                           \
  .if0.bAlternateSetting   = 0,                                                                           \
  .if0.bNumEndpoints       = 0,                                                                           \
  .if0.bInterfaceClass     = USB_DEVICE_CLASS_VENDOR_SPECIFIC,                                            \
  .if0.bInterfaceSubClass  = 255,                                                                         \
  .if0.bInterfaceProtocol  = 255,                                                                         \
  .if0.iInterface          = iInterface0,                                                                 \
                                                                                                          \
  .if1.bLength             = sizeof(UsbIfaceDesc),                                                        \
  .if1.bDescriptorType     = USB_DESC_TYP_INTERFACE,                                                      \
  .if1.bInterfaceNumber    = 0,                                                                           \
  .if1.bAlternateSetting   = 1,                                                                           \
  .if1.bNumEndpoints       = 1,                                                                           \
  .if1.bInterfaceClass     = USB_DEVICE_CLASS_VENDOR_SPECIFIC,                                            \
  .if1.bInterfaceSubClass  = 255,                                                                         \
  .if1.bInterfaceProtocol  = 255,                                                                         \
  .if1.iInterface          = iInterface1,                                                                 \
                                                                                                          \
  .if1ep0.bLength          = sizeof(UsbEpDesc),                                                           \
  .if1ep0.bDescriptorType  = USB_DESC_TYP_ENDPOINT,                                                       \
  .if1ep0.bEndpointAddress = USB_EP_PHY2LOG(EPstream),                                                    \
  .if1ep0.bmAttr.traTyp    = USB_EP_TYP_ISOCHRONOUS,                                                      \
  .if1ep0.bmAttr.syncTyp   = USB_EP_SYNC_NO_SYNCHRONIZATION,                                              \
  .if1ep0.bmAttr.usageTyp  = USB_EP_USAGE_DATA,                                                           \
  .if1ep0.wMaxPacketSize   = epSize_ASET1,                                                                \
  .if1ep0.bInterval        = 1,                                                                           \
                                                                                                          \
  .if2.bLength             = sizeof(UsbIfaceDesc),                                                        \
  .if2.bDescriptorType     = USB_DESC_TYP_INTERFACE,                                                      \
  .if2.bInterfaceNumber    = 0,                                                                           \
  .if2.bAlternateSetting   = 2,                                                                           \
  .if2.bNumEndpoints       = 1,                                                                           \
  .if2.bInterfaceClass     = USB_DEVICE_CLASS_VENDOR_SPECIFIC,                                            \
  .if2.bInterfaceSubClass  = 255,                                                                         \
  .if2.bInterfaceProtocol  = 255,                                                                         \
  .if2.iInterface          = iInterface2,                                                                 \
                                                                                                          \
  .if2ep0.bLength          = sizeof(UsbEpDesc),                                                           \
  .if2ep0.bDescriptorType  = USB_DESC_TYP_ENDPOINT,                                                       \
  .if2ep0.bEndpointAddress = USB_EP_PHY2LOG(EPstream),                                                    \
  .if2ep0.bmAttr.traTyp    = USB_EP_TYP_ISOCHRONOUS,                                                      \
  .if2ep0.bmAttr.syncTyp   = USB_EP_SYNC_NO_SYNCHRONIZATION,                                              \
  .if2ep0.bmAttr.usageTyp  = USB_EP_USAGE_DATA,                                                           \
  .if2ep0.wMaxPacketSize   = epSize_ASET2,                                                                \
  .if2ep0.bInterval        = 1,                                                                           \
                                                                                                          \
  .terminator              = 0                                                                            \
}

USB_CONFIG_DESCRIPTOR(UsbFSConfigDescriptor, usbFSConfigDescriptor, USB_DESC_TYP_CONFIGURATION);
USB_CONFIG_DESCRIPTOR(UsbHSConfigDescriptor, usbHSConfigDescriptor, USB_DESC_TYP_CONFIGURATION);
USB_CONFIG_DESCRIPTOR(UsbFSOtherSpeed, usbFSOtherSpeed, USB_DESC_TYP_OTHER_SPEED_CONFIG);
USB_CONFIG_DESCRIPTOR(UsbHSOtherSpeed, usbHSOtherSpeed, USB_DESC_TYP_OTHER_SPEED_CONFIG);

См. как инициализируется .cfg.wTotalLength.

Т.е. - один из членов структуры получает значение, вычисленное на основании размера экземпляра структуры. Вроде этого и хотел ТС.

Компилится нормально в IAR for ARM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

46 minutes ago, jcxz said:

И какой компилятор позволяет такое? IAR ожидаемо выдаёт ошибку: "cast to incomplete array type "sGPIOItem []" is not allowed".

С компилятор любой должен, это вроде как стандартный способ инициализации массивов/структур через (type){x, y, z}

но плюсовый может и не уметь, там что-то про сишные инициализации вроде бы только в с++23 наконец добавили. попробуйте переключить его в -std=c99

https://godbolt.org/z/TYnqzvqKj

 

1 hour ago, jcxz said:

Вроде этого и хотел ТС.

у ТСа там массив, неопределённой на момент определения (каламбур-с) длины [] есть, размер которого он хочет получить внутри этой же инициализации, которую компилятор ему не может дать, так как С теоретически позволяет ТСу после определения длины коварно продолжить инициализовать массив через именованную инициализацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

49 минут назад, _pv сказал:

С компилятор любой должен, это вроде как стандартный способ инициализации массивов/структур через (type){x, y, z}

но плюсовый может и не уметь, там что-то про сишные инициализации вроде бы только в с++23 наконец добавили. попробуйте переключить его в -std=c99

Переключил:

scr006.thumb.png.acb77bf1a3e4b24f9caaff2acabf1625.png

Код находится в .c-файле:

typedef struct {
  unsigned gpio;
  short pinNum;
} sGPIOItem;
typedef struct {
  unsigned size;
  sGPIOItem item[];
} sGPIOList;

#define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), (sGPIOItem[]){__VA_ARGS__}}

#if 1
sGPIOList const gpio = STRUCT_INIT(
  {0x101,  1},
  {0x102,  2},
  {0x103,  3}
);
#endif

Теперь выдаёт другую ошибку: Error[Pe144]: a value of type "sGPIOItem *" cannot be used to initialize an entity of type "unsigned int"

 

PS: Вот так компилится без ошибок:

#define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), {__VA_ARGS__}}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

57 minutes ago, jcxz said:

Теперь выдаёт другую ошибку: Error[Pe144]: a value of type "sGPIOItem *" cannot be used to initialize an entity of type "unsigned int"

каким образом у него там вообще int в этом месте образовался (парсер пролюбил "массивность" или вложенность стуктуры и сразу полез уровнем ниже unsigned gpio инициализировать?), и то что * и [] не абсолютно прям одно и то же, выглядит как-то не очень красиво. имхо что-то они там перемудрили с приведениями типов.

53 minutes ago, jcxz said:

PS: Вот так компилится без ошибок:

#define STRUCT_INIT(...) {sizeof((sGPIOItem[]){__VA_ARGS__})/sizeof(sGPIOItem), {__VA_ARGS__}}

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

но да, второе приведение {__VA_ARGS__} при инициализации поля структуры тут совсем не обязательно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...