|
struct - непонятка с косвенной адресацией |
|
|
|
Dec 17 2007, 09:51
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Господа, что-то не понимаю следующего:
Даю описание структуры
typedef struct SettingMenu { unsigned int P1, P2, ... ... P100; } Setup;
Где-то в модуле(да неважно где) создаем новую структуру типа Setup
Setup LocalSetup;
Требуется заполнить поля структуры какими-нибудь значениями. Так как количество полей большое, резонно использовать косвенную адресацию. Берем адрес структуры и в цикле запихиваем в структуру данные.
Setup LocalSetup;// Создаем структуру типа Setup Setup *sptr;// Указатель ... ...
sptr = & LocalSetup;// Определяем адрес структуры
for (c=0; c<100; c++) { *sptr = c; // Записываем по адресу некое значение sptr++; // Увеличиваем адрес }
Это классический пример С, значения пишутся во все поля без проблем
В Keil-е номер не проходит - ругается на разные типы данных строки *sptr = c, хотя теоретически я получил в качестве адреса структуры адрес первого поля этой структуры. Как бы это правильно разрулить???
|
|
|
|
|
Dec 17 2007, 10:05
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Andrei_S @ Dec 17 2007, 12:51)  Setup *sptr;// Указатель for (c=0; c<100; c++) { *sptr = c; // Записываем по адресу некое значение sptr++; // Увеличиваем адрес } [/b] Это классический пример С, значения пишутся во все поля без проблем насчет классики не уверен, особенно в том месте, где Вы указываете имя структуры сперва в стандарте С++ (после struct), а потом еще и в classic - после закрывающей скобки, но в принципе любой уважающий себя современный компилятор не должен разрешать подобные вольности. 1. переменная sptr имеет тип Setup *, соответственно, *sptr - типа Setup, а Вы пытаетесь инициализировать ее с помощью переменной типа (предположительно) int 2. даже если приведенную Вами конструкцию скомпилировать путем явного приведения типа (то есть, написав Код *(( int *)sptr) = c; все равно инструкция sptr++ выполнится неправильно (Вы, очевидно, ожидаете инкремента на размер int, а получите - на размер Setup) Не могу сказать, что это пример хорошего кода, но очевидно Вы в классическом примере упустили тот факт, что там, думаю, было написано так: Код int *sptr = (*int)&LocalSetup; // Указатель ... в этом случае программа соберется и будет работать примерно так, как Вы рассчитываете
Сообщение отредактировал sergik_vrn - Dec 17 2007, 10:08
|
|
|
|
|
Dec 17 2007, 10:35
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Спасибо sergik_vrn , попробую... А насчет массива: имеется добрая сотня значений меню, и в теле программы помнить какой элемент массива за что отвечает - нереально!!! Надо иметь бумажку, где все эти элементы сопоставляются - короче, гемороище... Проще указать каждой переменной адрес, где она будет лежать в RAM, а не использовать массив.
Спасибо за ответы...
|
|
|
|
|
Dec 17 2007, 10:52
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Andrei_S @ Dec 17 2007, 13:35)  Спасибо sergik_vrn , попробую... А насчет массива: имеется добрая сотня значений меню, и в теле программы помнить какой элемент массива за что отвечает - нереально!!! Надо иметь бумажку, где все эти элементы сопоставляются - короче, гемороище... Проще указать каждой переменной адрес, где она будет лежать в RAM, а не использовать массив.
Спасибо за ответы... 1. тот вариант, что я привел - вовсе не оптимальный, просто в нем исправлены Ваши ошибки 2. адрес элемента массива это <имя_массива>+<номер элемента> 3. также настоятельно рекомендую воспользоваться массивом и не заниматься ерундой. судя из того, что я понял по приведенному исходнику, Вам массив и нужен, причем даже без всякой обрамляющей структуры пассаж насчет указания адресов "лежания" для переменных до моего понимания не дошел
|
|
|
|
|
Dec 17 2007, 11:25
|
Частый гость
 
Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371

|
Цитата(sergik_vrn @ Dec 17 2007, 13:52)  ... 2. адрес элемента массива это <имя_массива>+<номер элемента> ... Я так понял, что Andrei_S говорит о том, что в структуре каждой переменной он может задать осмысленное имя, в то время как для массива потребуется некий список на "бумажке", чтоб знать какой элемент что означает.
|
|
|
|
|
Dec 17 2007, 11:35
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Цитата(sergik_vrn @ Dec 17 2007, 13:52)  1. тот вариант, что я привел - вовсе не оптимальный, просто в нем исправлены Ваши ошибки 2. адрес элемента массива это <имя_массива>+<номер элемента> 3. также настоятельно рекомендую воспользоваться массивом и не заниматься ерундой. судя из того, что я понял по приведенному исходнику, Вам массив и нужен, причем даже без всякой обрамляющей структуры
пассаж насчет указания адресов "лежания" для переменных до моего понимания не дошел Пояснение по адресам "лежания": имеется установочное меню, включающее в себя несколько десятков пунктов. Каждому пункту меню соответствует своя переменная. В процессе работы используются значения этих переменных. Если будет сделан массив, как Вы предлагаете, то мне придется помнить, какой из элементов массива за что отвечает. Да, будет очень удобно в этот массив переписывать данные, например, из ПЗУ в одном единственном цикле Код for(a=0;a<Lengh;a++){Array[a]=Read_Eprom(a);} , но в программе помнить о том, какая ячейка чему соответствует - весьма тяжело, и не исключены ошибки. Используя прямую адресацию в RAM, типа Код unsigned int P1x __at(0x00000000000000000) unsigned int P2x __at(0x00000000000000001) я смогу в одном цикле выполнить действия аналогичные примеры выше, но только с косвенной адресацией Код unsigned int *sptr;
sptr = & P1x; for(a=0;a<Lengh;a++;sptr++){*sptr=Read_Eprom(a);} Значения из Eprom автоматом перепишутся по нужным адресам. Только для этого я предполагаю явное указание адреса. А в теле программы читать и писать, например, пункт меню Baud_Rate гораздо понятнее и приятнее чем, например, Array[64]
|
|
|
|
|
Dec 17 2007, 11:41
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
присоединяюсь к sergik_vrn Структура, все элементы которой имеют одинаковый тип, явно напрашивается на то, чтобы быть массивом. Тем более, автор сам использует цикл для перебора элементов. Сложно запомнить? Хорошо. А для чего тогда используются комментарии? Комирование структуртоже никто не отменял Код __eeprom Setup eeSetup; ... Setup LocalSetup;// Создаем структуру типа Setup Setup *sptr;// Указатель
LocalSetup = eeSetup; ... *sptr = eeSetup;
Сообщение отредактировал zhevak - Dec 17 2007, 11:52
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 17 2007, 11:48
|
Частый гость
 
Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371

|
Цитата(Andrei_S @ Dec 17 2007, 14:35)  ... Используя прямую адресацию в RAM, типа Код unsigned int P1x __at(0x00000000000000000) unsigned int P2x __at(0x00000000000000001) я смогу в одном цикле выполнить действия аналогичные примеры выше, но только с косвенной адресацией Код unsigned int *sptr;
sptr = & P1x; for(a=0;a<Lengh;a++;sptr++){*sptr=Read_Eprom(a);} Интересно, ну и что Вы хотели этим пояснить: Код unsigned int P1x __at(0x00000000000000000) unsigned int P2x __at(0x00000000000000001) Это не скомпилиться без явного приведения типа в нормальном компиляторе: Код sptr = & P1x; если P1x - структура.
|
|
|
|
|
Dec 17 2007, 12:01
|
Частый гость
 
Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371

|
Цитата(zhevak @ Dec 17 2007, 14:41)  ... Сложно запомнить? Хорошо. А для чего тогда используются комментарии? ... Согласитесь, что работать всеже удобнее, когда имя переменной сразу дает полное представление о ней без необходимости плодить пачками комментарии возле строк типа: Код array[12] = 9600; // здесь я установил BaudRate К тому же в случае необходимости есть возможность легко ввести в структуру данные других типов.
|
|
|
|
|
Dec 17 2007, 12:01
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Цитата(Юрий Санвальд @ Dec 17 2007, 14:48)  Интересно, ну и что Вы хотели этим пояснить: Код unsigned int P1x __at(0x00000000000000000) unsigned int P2x __at(0x00000000000000001) Это не скомпилиться без явного приведения типа в нормальном компиляторе: Код sptr = & P1x; если P1x - структура. Код unsigned int P111 __at (0x40003000); unsigned int P112 __at (0x40003002);
int main(void){
unsigned int *aptr;
aptr = & P111; for(hhh=0;hhh<10;hhh++) { *aptr=hhh; aptr++; }
} Пардон, скомпилилось без вопросов...
|
|
|
|
|
Dec 17 2007, 12:18
|
Частый гость
 
Группа: Свой
Сообщений: 125
Регистрация: 21-03-07
Из: Санкт-Петербург
Пользователь №: 26 371

|
Цитата(Andrei_S @ Dec 17 2007, 15:01)  Пардон, скомпилилось без вопросов... Пардон, почему то решил что P1x ранее объявлена как некая структура. Но не понял зачем Вы так делаете, что мешает просто объявить Код STRUCT_TYPE P1x; и работать с указателем на нее, чем укладывать все в определенном месте RAM, а потом все арвно придется создавать указатель типа структуры на этот адрес
|
|
|
|
|
Dec 17 2007, 12:20
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Andrei_S @ Dec 17 2007, 14:35)  ... А в теле программы читать и писать, например, пункт меню Baud_Rate гораздо понятнее и приятнее чем, например, Array[64] убедился, что все понял правильно, просто формулировка про адреса меня смутила. посмотрите в треде Вам кто-то уже советовал использовать enum, присоединяюсь. наиболее правильно собирать однотипные элементы в массив, а для адресации на уровне идентификатора использовать enum
|
|
|
|
|
Dec 17 2007, 12:26
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Цитата(aaarrr @ Dec 17 2007, 15:12)  Ага, только работать не будет (int по адресу 0x40003002). Честное слово, не могу понять, что Вам нужно получить в результате - структуру меню с возможностью загрузки из EEPROM? Зачем эти фиксированные адреса и прочие извращения? Имеется большое количество переменных. Я хочу как можно сильней упростить их перезапись (в том числе и в ПЗУ). Например писать: BaudRate = Read_Eprom(10); StopBit = Read_Eprom(11); и так сто раз весьма утомительно. Вариант с адресацией, на мой взгляд, избавит от рутины, к тому же имена переменных будут осмысленны, в отличие от массива. Может есть какие-то отлаженные решения?
|
|
|
|
|
Dec 17 2007, 12:34
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Andrei_S @ Dec 17 2007, 15:26)  Имеется большое количество переменных. Я хочу как можно сильней упростить их перезапись (в том числе и в ПЗУ).
Например писать: BaudRate = Read_Eprom(10); StopBit = Read_Eprom(11); и так сто раз весьма утомительно.
Вариант с адресацией, на мой взгляд, избавит от рутины, к тому же имена переменных будут осмысленны, в отличие от массива. Может есть какие-то отлаженные решения? как я понимаю, фактически Вы хотите кешировать в ОЗУ некий набор параметров, хранящийся в NVRAM. в таком случае если структура конфигурации сложная, то необходимо оформить ее в виде структуры, и читатьиз NVRAM блоком примерно как Вы и собирались (путем приведения типа указателя), только я бы оформил такое чтение отдельной функцией. если же параметры конфигурации однотипные, и Вы всего лишь желаете их поименовать по-разному, объявляйте массив и адресуйте его элементы через enum.
|
|
|
|
|
Dec 17 2007, 12:36
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zhevak @ Dec 17 2007, 13:41)  Структура, все элементы которой имеют одинаковый тип, явно напрашивается на то, чтобы быть массивом. Вовсе нет. Смотрите: Код typedef struct { uint8_t Size_X; uint8_t Size_Y; uint8_t Bitmap[]; } bmp_font_t; Здесь Size_X и Size_Y имеют такой же тип, что и члены следующего за ними массива, но включать их в этот массив было бы очень ненаглядно. Как я понял, автор вопроса хранит в структуре данные, которые хоть и имеют один и тот же интегральный тип, но логически не эквивалентны. Если я не прав, то красивым и верным будет решение, предложенное vmp, если же я прав, то подход автора в осмысленным именовании каждого члена безусловно правильный, а для удобства на каких-то операциях работать со структурой как с массивом можно использовать union: Код typedef union { struct { uint8_t member1; uint8_t member2; uint8_t member3; }; uint8_t Array[1]; } setup_t использование здесь массива размером 1 является некоторым хаком чтобы не именовать структуру. При проверке индекса массива нужно использовать sizeof() от union. Если структуре дать имя, тогда можно в качестве размера массива задать sizeof() структуры, но в коде при доступе к членам появляется в общем-то ненужное имя структуры.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 17 2007, 12:52
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Цитата(Сергей Борщ @ Dec 17 2007, 15:36)  Вовсе нет. Смотрите: Код typedef struct { uint8_t Size_X; uint8_t Size_Y; uint8_t Bitmap[]; } bmp_font_t; Здесь Size_X и Size_Y имеют такой же тип, что и члены следующего за ними массива, но включать их в этот массив было бы очень ненаглядно. Как я понял, автор вопроса хранит в структуре данные, которые хоть и имеют один и тот же интегральный тип, но логически не эквивалентны. Если я не прав, то красивым и верным будет решение, предложенное vmp, если же я прав, то подход автора в осмысленным именовании каждого члена безусловно правильный, а для удобства на каких-то операциях работать со структурой как с массивом можно использовать union: Код typedef union { struct { uint8_t member1; uint8_t member2; uint8_t member3; }; uint8_t Array[1]; } setup_t использование здесь массива размером 1 является некоторым хаком чтобы не именовать структуру. При проверке индекса массива нужно использовать sizeof() от union. Если структуре дать имя, тогда можно в качестве размера массива задать sizeof() структуры, но в коде при доступе к членам появляется в общем-то ненужное имя структуры. Вообще-то типы переменных разные, но для упрощения я их привел к одному типу, нехваткой памяти я не жалуюсь... Простите за серость, но адресацию элементов через enum я еще не делал... Pls, не подскажете ли конструкцию???
|
|
|
|
|
Dec 17 2007, 13:27
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Andrei_S @ Dec 17 2007, 15:52)  Вообще-то типы переменных разные, но для упрощения я их привел к одному типу, нехваткой памяти я не жалуюсь...
Простите за серость, но адресацию элементов через enum я еще не делал... Pls, не подскажете ли конструкцию??? если разные, делайте как делали, это правильно по поводу enum: Код const u8 CONFIG_SIZE = 3; enum Config_Items { baud_rate = 0, parity, stop_bits }; // и т.д. - по необходимости typedef u8 Configuration[CONFIG_SIZE]; Configuration my_config;
for (int i = 0; i < CONFIG_SIZE; ++i) my_config[i] = Read_EEEPROM(i);
...
Set_UART(my_config[baud_rate], my_config[parity], my_config[stop_bits]); ...
|
|
|
|
|
Dec 17 2007, 13:33
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Большое спасибо всем! Буду пробовать...
|
|
|
|
|
Dec 17 2007, 14:40
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата Господа, что-то не понимаю следующего:
Даю описание структуры
typedef struct SettingMenu { unsigned int P1, P2, ... ... P100; } Setup;
Где-то в модуле(да неважно где) создаем новую структуру типа Setup
Setup LocalSetup;
Требуется заполнить поля структуры какими-нибудь значениями. Так как количество полей большое, резонно использовать косвенную адресацию. Берем адрес структуры и в цикле запихиваем в структуру данные.
Setup LocalSetup;// Создаем структуру типа Setup Setup *sptr;// Указатель ... ...
sptr = & LocalSetup;// Определяем адрес структуры
for (c=0; c<100; c++) { *sptr = c; // Записываем по адресу некое значение sptr++; // Увеличиваем адрес }
Это классический пример С, значения пишутся во все поля без проблем
В Keil-е номер не проходит - ругается на разные типы данных строки *sptr = c, хотя теоретически я получил в качестве адреса структуры адрес первого поля этой структуры. Как бы это правильно разрулить??? Я всегда делал так. Код Setup LocalSetup; // Создаем структуру типа Setup char *sptr;// Указатель на char (Если структра выровнена по памяти можно и другие типы использовать для более быстрого доступа все зависит от типа CPU и его команд)
sptr = (char*)&LocalSetup;// Определяем адрес структуры for (c=0; c<sizeof(Setup); c++) *sptr++ = 0x00; // Записываем по адресу некое значение
|
|
|
|
|
Dec 17 2007, 16:29
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
А если такая ситуация Код for (c=0; c<sizeof(Setup); c++) *sptr++ = get_eeprom(BASE_IMAGE+c); // Записываем по адресу некое значение P.S. А првельней мне кажеться Код Read_eeprom(BASE_IMAGE, sptr, sizeof(Setup)); //:)
|
|
|
|
|
Dec 18 2007, 08:34
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Итак, общими усилиями получилось следующее: имеется некая структура типа setup (все-таки структура а не массив, т.к. типы данных разные ) Код typedef struct SettingMenu { char Parametr1; char Parametr2; int Parametr3; char Array[10]; float Parametr5; ..........
};Setup .......... .......... Setup LocalSetup;// Структура char *sptr; // Указатель
sptr = (char*)&LocalSetup;// Получили адрес a=sizeof(Setup);// и размер
for (c=0; c<a; c++) { *sptr++ = ReadEprom(StartSetupAdress+c); } Работает отлично, заморочек с чтением/записью разных типов данных нет. Большое спасибо!! Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент. Мне нужно узнать его адрес и размерность. Указано явно: Код sptr = (char*)&LocalSetup.Parametr5; a = sizeof(LocalSetup.Parametr5);// Получили размерность, например, он float - 4 байта for (c=0; c<a; c++) { *sptr++ = ReadEprom(StartSetupAdress+N+c);// где N-адрес в ПЗУ Параметра 5 } Такой вопрос: как это сделать не с явным указанием, а по номеру элемента структуры например, ReadSinglePar(LocalSetup,5), где 5 - пятый элемент структуры, т.е. Parametr5 ? Если это делать явно, то модуль установочного меню раздуется весьма ощутимо, и будет проблемка синхронизации при изменении самой структуры(при изменении количества или названия элементов). Можно, конечно, переписать всю структуру, но критично время.
|
|
|
|
|
Dec 18 2007, 09:00
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Andrei_S @ Dec 18 2007, 11:34)  Итак, общими усилиями получилось следующее: [..] Работает отлично, заморочек с чтением/записью разных типов данных нет. Большое спасибо!! я бы на Вашем месте еще оформил чтение блока памяти как функцию, тогда программа приобрела бы законченый вид. типа, Read_EEPROM((u8 *)&config, MEM_ADDR, sizeof(config)); Цитата(Andrei_S @ Dec 18 2007, 11:34)  Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент. Мне нужно узнать его адрес и размерность. для этого есть макросы sizeof() и offsetof() например: Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1));
|
|
|
|
|
Dec 18 2007, 10:26
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Цитата(sergik_vrn @ Dec 18 2007, 12:00)  я бы на Вашем месте еще оформил чтение блока памяти как функцию, тогда программа приобрела бы законченый вид. типа, Read_EEPROM((u8 *)&config, MEM_ADDR, sizeof(config)); для этого есть макросы sizeof() и offsetof() например: Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1)); Уже сделал, большое спасибо!
|
|
|
|
|
Dec 18 2007, 10:45
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Цитата(sergik_vrn @ Dec 17 2007, 15:20)  убедился, что все понял правильно, просто формулировка про адреса меня смутила. посмотрите в треде Вам кто-то уже советовал использовать enum, присоединяюсь. наиболее правильно собирать однотипные элементы в массив, а для адресации на уровне идентификатора использовать enum ...как вариант #define BAUD_RATE 2 unsigned int Settings[64]; .... Settings[BAUD_RATE] = 9600;
|
|
|
|
|
Dec 18 2007, 11:48
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Цитата(tag @ Dec 18 2007, 13:45)  ...как вариант #define BAUD_RATE 2 unsigned int Settings[64]; .... Settings[BAUD_RATE] = 9600; В принципе, ничего, и ремарки не нужны... Но годится в случае одного типа переменных.
|
|
|
|
|
Dec 18 2007, 13:01
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 3-08-07
Из: Орловская обл.
Пользователь №: 29 535

|
Код Read_EEPROM((u8 *)&config.info_1, MEM_ADDR + offsetof(Config_Type, info_1), sizeof(config.info_1)); Но а все-таки, а как уйти от названия элементов структуры к порядковому номеру элемента этой структуры? Хотелось бы вместо названия поля info_1 писать номер этого поля, например 1 Например, я последовательно вывожу на индикацию эти 100 параметров структуры: N1 120 N2 300 .... и т.д. При нажатии кнопок я могу изменять значения и перезаписывать их в ПЗУ Если я, например, изменил один из параметров, то для записи в ПЗУ я должен сначала сопоставить значение переменной N и название соответствующего поля типа: Код switsh(N) { case 0: Addr = offsetof(Config_Type, info_1); break; case 1: Addr = offsetof(Config_Type, info_2); break; .... и так все 100 параметров Можно ли это модифицировать?
|
|
|
|
|
Dec 18 2007, 13:10
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(Andrei_S @ Dec 18 2007, 11:34)  Но, допустим, мне необходимо перезаписать всего один элемент структуры - пускай 5 элемент. Мне нужно узнать его адрес и размерность. Код //------------------------------------------------------------- // Вычисление смещения до поля в структуре //------------------------------------------------------------- #define OFFSET(type,field) ((char *)&(((type *)0)->field) - (char *)0) Как пользоваться - OFFSET(тип_структуры, имя_элемента) выдаст смещение от начала структуры до указанного элемента. Размер элемента можно получить по sizeof(type.field). Цитата(Andrei_S @ Dec 18 2007, 16:01)  Но а все-таки, а как уйти от названия элементов структуры к порядковому номеру элемента этой структуры?
Хотелось бы вместо названия поля info_1 писать номер этого поля, например 1 Тогда я бы сделал еще одну табличку с дескрипторами полей. Например, массив структур с описателями параметров. В него заносил бы тип поля, смещение от начала, размер, формат вывода, строку с именем, минимальное и максимальное значения и т.д. А индекс этого массива для читабельности описал как enum.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|