Создание массива

Тема в разделе "Arduino & Shields", создана пользователем sqafaroff, 6 янв 2021.

  1. Asper Daffy

    Asper Daffy Иксперд

    Это не массив.

    А если написать
    Код (C++):
    unsigned char massiv[] = SSD1306_INITIALIZATION_DATA_ARRAY;
    То и sizeof отлично работает.
     
    parovoZZ и SergeiL нравится это.
  2. AlexU

    AlexU Гуру

    sizeof -- очень простой оператор, он вычисляет размер данных в байтах. Он не вычисляет количество элементов в массиве, он вычисляет размер этого массива в байтах, не зависимо от размера элементов массива. Размер массива в байтах не будет соответствовать количеству элементов массива, если размер элементов массива больше одного байта.
    И нет тут ни какой "мути" -- всё просто и прозрачно до безобразия.
     
    SergeiL нравится это.
  3. Asper Daffy

    Asper Daffy Иксперд

    Муть есть, только не массиве, а голове.
     
    AlexU, SergeiL и parovoZZ нравится это.
  4. parovoZZ

    parovoZZ Гуру

    А как грамотно это назвать?
     
  5. kino

    kino Нерд

    ну грамотно это уже обозвали define, куда еще грамотней. )
     
  6. Asper Daffy

    Asper Daffy Иксперд

    Макрос
     
    AlexU, SergeiL и parovoZZ нравится это.
  7. SergeiL

    SergeiL Оракул Модератор

    Ну можно же поделить на sizeof() элемента массива или структуры.
     
  8. SergeiL

    SergeiL Оракул Модератор

    upload_2021-1-9_22-38-32.png
    Это костыль... :-(
     
    AlexU нравится это.
  9. AlexU

    AlexU Гуру

    Конечно можно.
    Но эта "мутная" магия доступна только просвящённым, достигшим 26-го уровня....
     
  10. AlexU

    AlexU Гуру

    Учитывая обстоятельства, что в макросе, который определяет содержимое массива, используются другие макросы, которые могут быть определены как '0', этот "костыль" превращается в головную боль.
     
  11. sqafaroff

    sqafaroff Нерд

    Проблема решена. Прошу модераторов закрытьь тему.
     
  12. parovoZZ

    parovoZZ Гуру

    Это не костыль, а решение, которое позволяет передавать в интерфейс определённое количество байт. Сколько байт передавать, определяется первым байтом в строчке. Далее двигаем "каретку" на один элемент вперёд и рисуем байты в интерфейс. Затем переходим на следующую строчку, считываем количество байт и так далее. Такая замута потребовалась для трансиверов от SiLabs. За раз в него можно напихать не более 15 мать их чтоле байт. А всего вместе с патчем необходимо передать что-то около 800 байт для его конфигурации.
    В SSD1306 такое не требуется, поэтому переделал на обычное написание:
    Код (C++):
    #define SSD1306_INITIALIZATION_DATA_ARRAY { \
            SSD1306_CMD_SET_DISPLAY_OFF, \
            SSD1306_SET_MULTIPLEX_RATIO, \
            SSD1306_SET_DISPLAY_OFFSET, \
            SSD1306_SET_DISPLAY_START_LINE, \
            SSD1306_SET_SEGMENT_REMAP_SEG0, \
            SSD1306_SET_OUTPUT_SCAN_DIRECTION, \
            SSD1306_SET_ADDRESSING_MODE, \
            SSD1306_SET_PINS_HARDWARE_CONF, \
            SSD1306_SET_CONTRAST_CONTROL, \
            SSD1306_ENTIRE_DISPLAY_ON, \
            SSD1306_SET_NORMAL_INVERSE_DISPLAY, \
            SSD1306_SET_DISPLAY_CLOCK, \
            SSD1306_SET_PRECHARGE_PERIOD, \
            SSD1306_SET_VCOMH_DESELECT_LEVEL, \
            SSD1306_CMD_DEACTIVATE_SCROLL, \
            SSD1306_CHARGE_PUMP_SETTING, \
            SSD1306_CMD_SET_DISPLAY_ON, \
            }
    Ну и как тут подсказали, sizeof() на это...
     
  13. parovoZZ

    parovoZZ Гуру

    Застрял на такой задачке. Есть такая структура:
    Код (C++):
    typedef struct {
        const unsigned char *data;
        uint8_t     width;
        uint8_t     height;
        uint8_t     dataSize;
    } tImage;

     
    Данные примерно в таком виде:
    Код (C++):
    static const uint8_t image_data_Font_0xfe[18] = {
        0x00, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x80, 0x00, 0x07, 0x02, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01
    };
    static const tImage Font_0xfe = { image_data_Font_0xfe,
        9, 16, 8};

    static const uint8_t image_data_Font_0xff[14] = {
        0x00, 0x80, 0x40, 0x40, 0x80, 0x00, 0xc0, 0x04, 0x05, 0x02, 0x02, 0x01, 0x01, 0x07
    };
    static const tImage Font_0xff = { image_data_Font_0xff,
        7, 16, 8};
    Через указатели получаю адрес требуемой структуры во флеше:
    Код (C++):
        uint8_t char_width;
        const tImage* image_font;
        uint8_t* data;

        image_font = Get_Char_Data(c);

        if (image_font)
        {
            char_width = image_font->width;

            data = (uint8_t*)image_font->data;
          /* ...... */
          }
    Все данные получаю валидные по адресам из флеша (смотрю дебагом), а вот
    Код (C++):
    sizeof(image_font->data)
    возвращет чепуху (2 байта, но должно вернуться 14, 18 ...). Как натравить этот мутный оператор (с) на массив через поле структуры?
     
    Последнее редактирование: 11 янв 2021
  14. AlexU

    AlexU Гуру

    Ну и где тут чепуха?
    Сел за руль машины, включил заднюю, нажал не газ, и начинаешь возмущаться -- "а чой-то она назад поехала, а не вперёд как я хочу!?!?!"
    sizeof вычисляет размер данных, хранимых в переменной на основе типа этой переменной.
    Какой тип у переменной 'image_font->data'?
    Правильно -- const unsigned char *data -- это указатель.
    Какой размер данных у переменной типа "указатель"?
    Зависит от архитектуры, в твоём случае 2 байта.

    В том-то и беда, что натравливаешь это простейший оператор не на массив, а на указатель, который указывает на ячейку памяти типа 'unsigned char' размером 1 (один) байт.
    Если хочешь узнать размер данных, на которые указывает указатель, то сначала твоя программа должна узнать "а на данные какого типа указывает указатель?". Узнав этот тип, передаёшь его оператору 'sizeof' и получаешь нужный тебе ответ.

    PS: тебе надо разобраться -- что такое указатели и с чем их едят....
     
  15. parovoZZ

    parovoZZ Гуру

    Я не знаю никакого способа приведения указателя к массиву. Получается, размер массива надо передавать отдельно.
     
  16. AlexU

    AlexU Гуру

    Это потому, что в языке 'C' нет способа сделать указатель на массив -- такой тип как массив есть, а указателя на него нет (наверное единственный тип, для которого в этом языке нельзя сделать указатель).
     
  17. b707

    b707 Гуру

    в языке Си нет такого типа как "массив" - поэтому и указателя нет.
    Вместо массива в Си есть область памяти. заполненная переменными данного типа. И есть указатель на начало этой области. Вполне логично. что этот указатель имеет тип элемента. а не массива.
     
  18. b707

    b707 Гуру

    не обязательно отдельно. Можешь хранить размер структуры в первом элементе. Или ставить в конце массива терминатор, как в классических С-type строках
    Но в любом случае в твоей структуре за размером массива должен следить ты сам, компилятор тут не справится
     
  19. AlexU

    AlexU Гуру

    Разработчики языка 'C' с Вами не согласны. Вот выдержка из стандарта 'ANSI C' (ISO/IEC 9899):
    В разделе описываются производные типы, такие как -- массив, структура, объединение и т.д.

    UPD: Исходя из текста стандарта и Вашего заявления, можно продолжить мысль, что и структура тоже на является типом, и на неё не может быть указателя.
     
  20. SergeiL

    SergeiL Оракул Модератор

    В классических строках не встречается "\0", за исключением как только конец строки.
    В массиве данных 0 может встречаться как элемент массива.
    Почему не передать размер массива как отдельный параметр?
    Вот зачем эти костыли?
    Как по мне в Си все очень однозначно и понятно.
    Можно же так:
    Код (C++):
    typedef struct {
        const unsigned char *data;
        uint8_t     data_size;
        uint8_t     width;
        uint8_t     height;
        uint8_t     dataSize;
    } tImage;

    static const uint8_t image_data_Font_0xfe[] = {
        0x00, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x80, 0x00, 0x07, 0x02, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01
    };
    static const tImage Font_0xfe = { image_data_Font_0xfe, sizeof(image_data_Font_0xfe),     \\
        9, 16, 8};

    static const uint8_t image_data_Font_0xff[] = {
        0x00, 0x80, 0x40, 0x40, 0x80, 0x00, 0xc0, 0x04, 0x05, 0x02, 0x02, 0x01, 0x01, 0x07
    };
    static const tImage Font_0xff = { image_data_Font_0xff,sizeof(image_data_Font_0xff),     \\
        7, 16, 8};