Вопросы по С/С++ (СИ)
- ROMan2947
- Грызет канифоль
- Сообщения: 287
- Зарегистрирован: Сб янв 23, 2016 00:59:59
- Откуда: Чебоксары
Re: Вопросы по С/С++ (СИ)
[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: Вопросы по С/С++ (СИ)
Вот так надо
Это может быть ограничения компилятора.
Тогда сделайте так:
Код: Выделить всё
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
Мои программки: 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: Вопросы по С/С++ (СИ)
[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"]Вот так надо[/uquote] Вот это похоже на правду! А ограничение по-моему тоже имеет место, т.к. с точкой я тоже пробовал,но массив инициализировался не корректно...Спасибо!!!!
1. Почему стрелка не канает?
2.Что это за ограничение?может его надо отключить?
Добавлено after 13 minutes 46 seconds:
[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"][/uquote] этот вариант без ошибок,но получаю странные данные
Добавлено after 5 minutes 41 second:
[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"]Тогда сделайте так:
[/uquote]
"Этот вариант заплевал всякой всячиной
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)};
Добавлено after 5 minutes 41 second:
[uquote="da-nie",url="/forum/viewtopic.php?p=3667847#p3667847"]Тогда сделайте так:
Код: Выделить всё
Ptrmymassiv[0]=&mystruct.a;"Этот вариант заплевал всякой всячиной
- Вложения
-
- Скриншот 17-07-2019 230324.jpg
- (162.62 КБ) 326 скачиваний
-
- Скриншот 17-07-2019 225632.jpg
- (43.33 КБ) 319 скачиваний
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Тут могут быть тонкости с выравниванием.
Вообще, код странный и ненужный. Зачем вообще может понадобиться хранить массив адресов элементов структуры, если одного адреса самой структуры вполне достаточно?
Вообще, код странный и ненужный. Зачем вообще может понадобиться хранить массив адресов элементов структуры, если одного адреса самой структуры вполне достаточно?
- ROMan2947
- Грызет канифоль
- Сообщения: 287
- Зарегистрирован: Сб янв 23, 2016 00:59:59
- Откуда: Чебоксары
Re: Вопросы по С/С++ (СИ)
[uquote="WiseLord",url="/forum/viewtopic.php?p=3667874#p3667874"]Зачем вообще[/uquote]в данном случае мне нужно в цикле присваивать значения полями структуры.ну а после так же в цикле считывать, может даже выборочно. Почему структура, а не просто массив? работать с индексами массива не очень, у полей есть имя...
Добавлено after 9 minutes 31 second:
да и вообще хотелось бы просто узнать, как это возможно
Добавлено after 9 minutes 31 second:
да и вообще хотелось бы просто узнать, как это возможно
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Тогда можно проще, через 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: Вопросы по С/С++ (СИ)
Спасибо, варианты интересные, буду прорабатывать 

- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3667969#p3667969"]в данном случае мне нужно в цикле присваивать значения полями структуры.ну а после так же в цикле считывать, может даже выборочно[/uquote]
Для таких целей эффективней использовать union структуры с массивом.
Для таких целей эффективней использовать union структуры с массивом.
Re: Вопросы по С/С++ (СИ)
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3667834#p3667834"]Здравствуйте Уважаемые!
Столкнулся с такой ситуацией, что стало мне нужно в массив закинуть адреса полей структуры.Но что-то ничего не выходит, да и в сети не нашел ответа...Есть ли такая возможность в си?[/uquote]
В таких случаях лучше использовать указатели на члены структуры, а не просто указатели на uint8_t. Так:
Использование:
Разница думаю понятна. Хотя конкретно в Вашем случае (когда адресуемые члены расположены подряд), я бы использовал наложенный через union массив (как тут уже посоветовали).
Правда указатели на члены имеют размерность равную указателям и в случаях маленьких структур экономнее (по флеши) может быть просто хранить смещения к членам структуры и когда нужно - приводить тип.
PS: И ещё - в таких случаях как у вас (массив констант), нужно всё-таки использовать квалификатор const для массива указателей. Чтоб не тратить понапрасну ОЗУ.
Столкнулся с такой ситуацией, что стало мне нужно в массив закинуть адреса полей структуры.Но что-то ничего не выходит, да и в сети не нашел ответа...Есть ли такая возможность в си?[/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: Вопросы по С/С++ (СИ)
[uquote="jcxz",url="/forum/viewtopic.php?p=3668040#p3668040"][/uquote] чет не знаком мне этот :: синтаксис это не С++?
Добавлено after 28 minutes 49 seconds:
[uquote="WiseLord",url="/forum/viewtopic.php?p=3667981#p3667981"]Тогда можно проще, через union:
[/uquote]
как это работает?
почему в массив сразу залетают элементы структуры?
Код: Выделить всё
static u8 Mytyp:: * const ttz[] = {&Mytyp::a, &Mytyp::b, &Mytyp::c};Добавлено 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] |
*/
как это работает?
почему в массив сразу залетают элементы структуры?- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Потому что это union. Один из базовых типов в C, кстати.
- ROMan2947
- Грызет канифоль
- Сообщения: 287
- Зарегистрирован: Сб янв 23, 2016 00:59:59
- Откуда: Чебоксары
Re: Вопросы по С/С++ (СИ)
[uquote="WiseLord",url="/forum/viewtopic.php?p=3668478#p3668478"]Потому что это union. Один из базовых типов в C, кстати.[/uquote] в книге было дело про этот тип,но там как-то поверхностно описано было,и больше всего меня смутило как элементы,причем разных типов, занимают одну область памяти...а сейчас увидел то, что данные в структуре,что в массиве одинаковые......пока не понимаю для чего эти объединения нужны. пример бы конкретный увидеть.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
А чем этот пример не устраивает?
В двух словах - все элементы union лежат в одной области памяти. Размер всего union-а равен максимальному из размеров его полей. Запись в любое из полей, соответственно, "портит" все остальные поля, потому что это одна и та же память.
Ещё один полезный пример:
В двух словах - все элементы 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: Вопросы по С/С++ (СИ)
[uquote="WiseLord",url="/forum/viewtopic.php?p=3668534#p3668534"]Ещё один полезный пример:[/uquote]
класс, теперь понял как это, и для чего можно применять! спасибо! только ещё момент, а что если в объединение определить тип int и float, что за каша получится?
класс, теперь понял как это, и для чего можно применять! спасибо! только ещё момент, а что если в объединение определить тип int и float, что за каша получится?
Re: Вопросы по С/С++ (СИ)
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3668387#p3668387"][uquote="jcxz",url="/forum/viewtopic.php?p=3668040#p3668040"][/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;
};
и прагмы не нужны, а значит будет корректно компилироваться разными компиляторами.
Код: Выделить всё
static u8 Mytyp:: * const ttz[] = {&Mytyp::a, &Mytyp::b, &Mytyp::c};С++. Прочитайте про "Указатели на член структуры/класса".
Это указатели на член типа структуры, а не на член конкретного экземпляра структуры (как у Вас). Т.е. - не указатель на ячейку памяти, а смещение члена структуры внутри структуры от её начала - если так понятнее. Их можно использовать с любым экземпляром структуры/класса.
Добавлено 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: Вопросы по С/С++ (СИ)
Доброго вечера!Не могу сообразить как проще и правильнее решить следующую задачу:
есть переменная типа UL. в ней хранится число,которое является показанием счетчика воды. максимальное число которое мне нужно это от 0 до 99999999 л. мне необходимо редактировать это число поразрядно,для задания данных ручками. мысль пока одна, считать область побайтно,после отработать с полубайтами и собрать снова все в кучу.Как-то мудрено получается.Хотелось бы услышать Ваши варианты.
есть переменная типа UL. в ней хранится число,которое является показанием счетчика воды. максимальное число которое мне нужно это от 0 до 99999999 л. мне необходимо редактировать это число поразрядно,для задания данных ручками. мысль пока одна, считать область побайтно,после отработать с полубайтами и собрать снова все в кучу.Как-то мудрено получается.Хотелось бы услышать Ваши варианты.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Преобразовать в массив символов перед редактированием, после редактирования - обратно в число.
Re: Вопросы по С/С++ (СИ)
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3669095#p3669095"]есть переменная типа UL. в ней хранится число,которое является показанием счетчика воды. максимальное число которое мне нужно это от 0 до 99999999 л. мне необходимо редактировать это число поразрядно,для задания данных ручками. мысль пока одна, считать область побайтно,после отработать с полубайтами и собрать снова все в кучу.[/uquote]
Почему "полубайтами"? Число в BCD-формате что-ль?
Если не BCD, а обычное бинарное, то:
Чтобы удалить цифру в дес.разряде ix из числа u32 x (со сдвигом в пустое место из более старших разрядов):
Примерно так.
Вставка цифры со сдвигом других разрядов - аналогично, в обратном порядке.
Почему "полубайтами"? Число в 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: Вопросы по С/С++ (СИ)
[uquote="jcxz",url="/forum/viewtopic.php?p=3669133#p3669133"]Почему "полубайтами"? Число в BCD-формате что-ль?[/uquote]
допустим в моей переменной хранится десятичное число 12345678 или 0xBC614E;
дело в том,что эта переменная находиться в eeprom. стандартными функциями могу читать и писать побайтно->по 8 бит. считав один байт я получу
78 или 0x4E. т.е. два разряда 7 и 8, которые я должен редактировать отдельно. а после все это надо еще собрать в единое число
допустим в моей переменной хранится десятичное число 12345678 или 0xBC614E;
дело в том,что эта переменная находиться в eeprom. стандартными функциями могу читать и писать побайтно->по 8 бит. считав один байт я получу
78 или 0x4E. т.е. два разряда 7 и 8, которые я должен редактировать отдельно. а после все это надо еще собрать в единое число
Re: Вопросы по С/С++ (СИ)
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3669249#p3669249"]допустим в моей переменной хранится десятичное число 12345678 или 0xBC614E;
дело в том,что эта переменная находиться в eeprom. стандартными функциями могу читать и писать побайтно->по 8 бит. считав один байт я получу 78 или 0x4E. т.е. два разряда 7 и 8, которые я должен редактировать отдельно.[/uquote]
А если число будет 87654321, то прочитав младший байт получишь 177, и что с ним потом делать?
дело в том,что эта переменная находиться в eeprom. стандартными функциями могу читать и писать побайтно->по 8 бит. считав один байт я получу 78 или 0x4E. т.е. два разряда 7 и 8, которые я должен редактировать отдельно.[/uquote]
А если число будет 87654321, то прочитав младший байт получишь 177, и что с ним потом делать?