Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Господа, что-то не понимаю следующего: Даю описание структуры 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, хотя теоретически я получил в качестве адреса структуры адрес первого поля этой структуры. Как бы это правильно разрулить??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 (изменено) · Жалоба 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; // Указатель ... в этом случае программа соберется и будет работать примерно так, как Вы рассчитываете Изменено 17 декабря, 2007 пользователем sergik_vrn Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Хотите массив - используйте!!! typedef struct SettingMenu { unsigned int P[100]; } Setup; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Спасибо sergik_vrn , попробую... А насчет массива: имеется добрая сотня значений меню, и в теле программы помнить какой элемент массива за что отвечает - нереально!!! Надо иметь бумажку, где все эти элементы сопоставляются - короче, гемороище... Проще указать каждой переменной адрес, где она будет лежать в RAM, а не использовать массив. Спасибо за ответы... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Спасибо sergik_vrn , попробую... А насчет массива: имеется добрая сотня значений меню, и в теле программы помнить какой элемент массива за что отвечает - нереально!!! Надо иметь бумажку, где все эти элементы сопоставляются - короче, гемороище... Проще указать каждой переменной адрес, где она будет лежать в RAM, а не использовать массив. Спасибо за ответы... 1. тот вариант, что я привел - вовсе не оптимальный, просто в нем исправлены Ваши ошибки 2. адрес элемента массива это <имя_массива>+<номер элемента> 3. также настоятельно рекомендую воспользоваться массивом и не заниматься ерундой. судя из того, что я понял по приведенному исходнику, Вам массив и нужен, причем даже без всякой обрамляющей структуры пассаж насчет указания адресов "лежания" для переменных до моего понимания не дошел Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
YuraFCZ 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба ... 2. адрес элемента массива это <имя_массива>+<номер элемента> ... Я так понял, что Andrei_S говорит о том, что в структуре каждой переменной он может задать осмысленное имя, в то время как для массива потребуется некий список на "бумажке", чтоб знать какой элемент что означает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба 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] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 (изменено) · Жалоба присоединяюсь к sergik_vrn Структура, все элементы которой имеют одинаковый тип, явно напрашивается на то, чтобы быть массивом. Тем более, автор сам использует цикл для перебора элементов. Сложно запомнить? Хорошо. А для чего тогда используются комментарии? Комирование структуртоже никто не отменял __eeprom Setup eeSetup; ... Setup LocalSetup;// Создаем структуру типа Setup Setup *sptr;// Указатель LocalSetup = eeSetup; ... *sptr = eeSetup; Изменено 17 декабря, 2007 пользователем zhevak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
YuraFCZ 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба ... Используя прямую адресацию в 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) :07: Это не скомпилиться без явного приведения типа в нормальном компиляторе: sptr = & P1x; если P1x - структура. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vmp 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Почитайте про перечислимый тип (enum). Именно он напрашивается в качестве индекса массива. Вы получите и массив, допускающий последовательный перебор, и мнемонические имена элементов этого массива. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
YuraFCZ 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба ... Сложно запомнить? Хорошо. А для чего тогда используются комментарии? ... Согласитесь, что работать всеже удобнее, когда имя переменной сразу дает полное представление о ней без необходимости плодить пачками комментарии возле строк типа: array[12] = 9600; // здесь я установил BaudRate К тому же в случае необходимости есть возможность легко ввести в структуру данные других типов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrei_S 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Интересно, ну и что Вы хотели этим пояснить: unsigned int P1x __at(0x00000000000000000) unsigned int P2x __at(0x00000000000000001) :07: Это не скомпилиться без явного приведения типа в нормальном компиляторе: 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++; } } Пардон, скомпилилось без вопросов... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 68 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Пардон, скомпилилось без вопросов... Ага, только работать не будет (int по адресу 0x40003002). Честное слово, не могу понять, что Вам нужно получить в результате - структуру меню с возможностью загрузки из EEPROM? Зачем эти фиксированные адреса и прочие извращения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
YuraFCZ 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба Пардон, скомпилилось без вопросов... Пардон, почему то решил что P1x ранее объявлена как некая структура. Но не понял зачем Вы так делаете, что мешает просто объявить STRUCT_TYPE P1x; и работать с указателем на нее, чем укладывать все в определенном месте RAM, а потом все арвно придется создавать указатель типа структуры на этот адрес Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 17 декабря, 2007 Опубликовано 17 декабря, 2007 · Жалоба ... А в теле программы читать и писать, например, пункт меню Baud_Rate гораздо понятнее и приятнее чем, например, Array[64] убедился, что все понял правильно, просто формулировка про адреса меня смутила. посмотрите в треде Вам кто-то уже советовал использовать enum, присоединяюсь. наиболее правильно собирать однотипные элементы в массив, а для адресации на уровне идентификатора использовать enum Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться