Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3667838#p3667838"]делайте именно такой массив, uint8_t *array[3].[/uquote] делали,но на это я получаю ошибку Error initializer element is not constant
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение da-nie »

Вот так надо

Код: Выделить всё

uint8_t *Ptrmymassiv[3]={&mystruct.a,&mystruct.b,mystruct.c)};


Error initializer element is not constant


Это может быть ограничения компилятора.
Тогда сделайте так:

Код: Выделить всё

Ptrmymassiv[0]=&mystruct.a;
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"]Вот так надо[/uquote] Вот это похоже на правду! А ограничение по-моему тоже имеет место, т.к. с точкой я тоже пробовал,но массив инициализировался не корректно...Спасибо!!!! :beer:
1. Почему стрелка не канает?
2.Что это за ограничение?может его надо отключить?

Добавлено after 13 minutes 46 seconds:
[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"]

Код: Выделить всё

uint8_t *Ptrmymassiv[3]={&mystruct.a,&mystruct.b,mystruct.c)};
[/uquote] этот вариант без ошибок,но получаю странные данные

Добавлено after 5 minutes 41 second:
[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"]Тогда сделайте так:

Код: Выделить всё

Ptrmymassiv[0]=&mystruct.a;
[/uquote]
"Этот вариант заплевал всякой всячиной
Вложения
Скриншот 17-07-2019 230324.jpg
(162.62 КБ) 326 скачиваний
Скриншот 17-07-2019 225632.jpg
(43.33 КБ) 319 скачиваний
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Тут могут быть тонкости с выравниванием.

Вообще, код странный и ненужный. Зачем вообще может понадобиться хранить массив адресов элементов структуры, если одного адреса самой структуры вполне достаточно?
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3667874#p3667874"]Зачем вообще[/uquote]в данном случае мне нужно в цикле присваивать значения полями структуры.ну а после так же в цикле считывать, может даже выборочно. Почему структура, а не просто массив? работать с индексами массива не очень, у полей есть имя...

Добавлено after 9 minutes 31 second:
да и вообще хотелось бы просто узнать, как это возможно
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Тогда можно проще, через union:
Спойлер

Код: Выделить всё

typedef union {
    struct {
        uint8_t sec;
        uint8_t min;
        uint8_t hour;
    };
    uint8_t time[3];
} Rtc;

/*
Расположение в памяти::
|             rtc             |
| sec     | min     | hour    |
| time[0] | time[1] | time[3] |
*/

Rtc rtc;

void reset(void)
{
    for (uint8_t i = 0; i < 3; i++) {
        rtc.time[i] = 0;
    }
}

void setHour(uint8_t value)
{
    rtc.hour = value;
   
    // то же самое, что сделать rtc.time[0] = value;
}

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

Код: Выделить всё

typedef struct
{
   uint8_t a;
   uint8_t b;
   uint8_t c;
} mytyp;

mytype mystruct;

void reset(void)
{
    uint8_t *p = (uint8_t*)&mystruct;
   
    for (int i = 0; i < 3; i++) {
        p[i] = 0;
    }
}
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

Спасибо, варианты интересные, буду прорабатывать :write:
Аватара пользователя
ПростоНуб
Собутыльник Кота
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Re: Вопросы по С/С++ (СИ)

Сообщение ПростоНуб »

[uquote="ROMan2947",url="/forum/viewtopic.php?p=3667969#p3667969"]в данном случае мне нужно в цикле присваивать значения полями структуры.ну а после так же в цикле считывать, может даже выборочно[/uquote]
Для таких целей эффективней использовать union структуры с массивом.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Вопросы по С/С++ (СИ)

Сообщение jcxz »

[uquote="ROMan2947",url="/forum/viewtopic.php?p=3667834#p3667834"]Здравствуйте Уважаемые!
Столкнулся с такой ситуацией, что стало мне нужно в массив закинуть адреса полей структуры.Но что-то ничего не выходит, да и в сети не нашел ответа...Есть ли такая возможность в си?[/uquote]

В таких случаях лучше использовать указатели на члены структуры, а не просто указатели на uint8_t. Так:

Код: Выделить всё

struct Mytyp {
 u8 a, b, c;
};
static u8 Mytyp:: * const ttz[] = {&Mytyp::a, &Mytyp::b, &Mytyp::c};

Использование:

Код: Выделить всё

uint Func(Mytyp const *p)
{
  static u8 cnt = sizeof(ttz) / sizeof(ttz[0]);
  int i;
  if ((i = cnt - 1) < 0) i = sizeof(ttz) / sizeof(ttz[0]) - 1;
  cnt = i;
  return p->*ttz[i];
}


Разница думаю понятна. Хотя конкретно в Вашем случае (когда адресуемые члены расположены подряд), я бы использовал наложенный через union массив (как тут уже посоветовали).
Правда указатели на члены имеют размерность равную указателям и в случаях маленьких структур экономнее (по флеши) может быть просто хранить смещения к членам структуры и когда нужно - приводить тип.

PS: И ещё - в таких случаях как у вас (массив констант), нужно всё-таки использовать квалификатор const для массива указателей. Чтоб не тратить понапрасну ОЗУ.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="jcxz",url="/forum/viewtopic.php?p=3668040#p3668040"]

Код: Выделить всё

static u8 Mytyp:: * const ttz[] = {&Mytyp::a, &Mytyp::b, &Mytyp::c};
[/uquote] чет не знаком мне этот :: синтаксис это не С++?

Добавлено after 28 minutes 49 seconds:
[uquote="WiseLord",url="/forum/viewtopic.php?p=3667981#p3667981"]Тогда можно проще, через union:
Спойлер

Код: Выделить всё

typedef union {
    struct {
        uint8_t sec;
        uint8_t min;
        uint8_t hour;
    };
    uint8_t time[3];
} Rtc;

/*
Расположение в памяти::
|             rtc             |
| sec     | min     | hour    |
| time[0] | time[1] | time[3] |
*/

[/uquote]

как это работает? :dont_know: почему в массив сразу залетают элементы структуры?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Потому что это union. Один из базовых типов в C, кстати.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3668478#p3668478"]Потому что это union. Один из базовых типов в C, кстати.[/uquote] в книге было дело про этот тип,но там как-то поверхностно описано было,и больше всего меня смутило как элементы,причем разных типов, занимают одну область памяти...а сейчас увидел то, что данные в структуре,что в массиве одинаковые......пока не понимаю для чего эти объединения нужны. пример бы конкретный увидеть.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

А чем этот пример не устраивает?

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

Ещё один полезный пример:
Спойлер

Код: Выделить всё

typedef union {
    uint16_t word;
    struct {
        uint8_t byteL;
        uint8_t byteH;
    }
} WordType;

void function()
{
    WordType wt = 0x4567;

    // Теперь wt.byteL автоматически равно 0x67, а wt.byteH = 0x45
}
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3668534#p3668534"]Ещё один полезный пример:[/uquote]
класс, теперь понял как это, и для чего можно применять! спасибо! только ещё момент, а что если в объединение определить тип int и float, что за каша получится?
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Вопросы по С/С++ (СИ)

Сообщение jcxz »

[uquote="ROMan2947",url="/forum/viewtopic.php?p=3668387#p3668387"][uquote="jcxz",url="/forum/viewtopic.php?p=3668040#p3668040"]

Код: Выделить всё

static u8 Mytyp:: * const ttz[] = {&Mytyp::a, &Mytyp::b, &Mytyp::c};
[/uquote] чет не знаком мне этот :: синтаксис это не С++?[/uquote]
С++. Прочитайте про "Указатели на член структуры/класса".
Это указатели на член типа структуры, а не на член конкретного экземпляра структуры (как у Вас). Т.е. - не указатель на ячейку памяти, а смещение члена структуры внутри структуры от её начала - если так понятнее. Их можно использовать с любым экземпляром структуры/класса.

Добавлено after 7 minutes 30 seconds:
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3668599#p3668599"]класс, теперь понял как это, и для чего можно применять! спасибо! только ещё момент, а что если в объединение определить тип int и float, что за каша получится?[/uquote]
...то прочитав int получите бинарное содержимое float естественно.
union позволяет обращаться к одним и тем же данным разным способом. Например:
union {
u8 a[4];
u16 b[2];
u32 c;
};
позволяет обратиться к содержимому 32-битного значения c через a - побайтно, или через b - пословно (по 16-битно).
Ещё union можно использовать для принудительного выравнивания без прагм - если нужно чтобы структура struct A { u8 a, b, c;} содержащая только байтовые члены была выровнена на границу 4-х байт (на 32-битных системах), то можно сделать:
union {
struct A;
u32 align;
};
и прагмы не нужны, а значит будет корректно компилироваться разными компиляторами.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

Доброго вечера!Не могу сообразить как проще и правильнее решить следующую задачу:
есть переменная типа UL. в ней хранится число,которое является показанием счетчика воды. максимальное число которое мне нужно это от 0 до 99999999 л. мне необходимо редактировать это число поразрядно,для задания данных ручками. мысль пока одна, считать область побайтно,после отработать с полубайтами и собрать снова все в кучу.Как-то мудрено получается.Хотелось бы услышать Ваши варианты. :roll:
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Преобразовать в массив символов перед редактированием, после редактирования - обратно в число.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Вопросы по С/С++ (СИ)

Сообщение jcxz »

[uquote="ROMan2947",url="/forum/viewtopic.php?p=3669095#p3669095"]есть переменная типа UL. в ней хранится число,которое является показанием счетчика воды. максимальное число которое мне нужно это от 0 до 99999999 л. мне необходимо редактировать это число поразрядно,для задания данных ручками. мысль пока одна, считать область побайтно,после отработать с полубайтами и собрать снова все в кучу.[/uquote]
Почему "полубайтами"? Число в BCD-формате что-ль?
Если не BCD, а обычное бинарное, то:
Чтобы удалить цифру в дес.разряде ix из числа u32 x (со сдвигом в пустое место из более старших разрядов):

Код: Выделить всё

static u32 const tPow10[] = {
  1ul,
  10ul,
  100ul,
  1000ul,
  10000ul,
  100000ul,
  1000000ul,
  10000000ul,
  100000000ul,
  1000000000ul};
#define ncell(m) (sizeof(m) / sizeof((m)[0]))
u32 Del(u32 x, uint ix)
{
  assert(ix < ncell(tPow10));
  u32 i = x % tPow10[ix];
  if (ix < ncell(tPow10) - 1) i += x / tPow10[ix + 1] * tPow10[ix];
  return i;
}

Примерно так.
Вставка цифры со сдвигом других разрядов - аналогично, в обратном порядке.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

Re: Вопросы по С/С++ (СИ)

Сообщение ROMan2947 »

[uquote="jcxz",url="/forum/viewtopic.php?p=3669133#p3669133"]Почему "полубайтами"? Число в BCD-формате что-ль?[/uquote]

допустим в моей переменной хранится десятичное число 12345678 или 0x‭BC614E‬;
дело в том,что эта переменная находиться в eeprom. стандартными функциями могу читать и писать побайтно->по 8 бит. считав один байт я получу
78 или 0x4E. т.е. два разряда 7 и 8, которые я должен редактировать отдельно. а после все это надо еще собрать в единое число
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Вопросы по С/С++ (СИ)

Сообщение Reflector »

[uquote="ROMan2947",url="/forum/viewtopic.php?p=3669249#p3669249"]допустим в моей переменной хранится десятичное число 12345678 или 0x‭BC614E‬;
дело в том,что эта переменная находиться в eeprom. стандартными функциями могу читать и писать побайтно->по 8 бит. считав один байт я получу 78 или 0x4E. т.е. два разряда 7 и 8, которые я должен редактировать отдельно.[/uquote]
А если число будет 87654321, то прочитав младший байт получишь 177, и что с ним потом делать? :)
Ответить

Вернуться в «Разные вопросы по МК»