|
|
  |
структуры в С, копирование в байтовый массив |
|
|
|
Apr 29 2007, 00:35
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(lks @ Apr 29 2007, 01:26)  Непонятно пока где описать этот тип данных - TBootSector *p; Тип TBootSector задается в typedef, см. исходный пример у dxp. Если вопрос: где именно объявить этот тип, то однозначного ответа у меня нет. Это зависит от стиля программирования. Я, например, создаю типы переменных и структур в хидерах, которые потом включаю к общий хидер проекта. В свою очередь общий хидер проекта включаю во все модули, которые этого требуют. Чтобы не было недоразумений все новые типы обрамляю условной компиляцией #ifdef/#endif. Цитата(lks @ Apr 29 2007, 01:26)  Этот адрес потом непереписать в обычный указатель? Ну и как на эту "баламутину" отреагирует Keil допустим. Извините, но я не понимаю термина "обычный указатель". Цитата(lks @ Apr 29 2007, 01:26)  И все же читал где-то, сейчас не могу вспомнить, не должно быть запрета на получение адреса структуры. Указатель на структуру должен быть всеже адресом первого байта в выделенном адресном пространстве, точно также как и в массивах - тип тут ни при чем. Тут что-то с компиляторами. Дык, а с чего вы взяли что есть такой запрет? Я же вроде доступную аналогию с гайками и автомобилем привел. Указатель это отмашка в сторону объекта. Но без дополнительного пояснения о том, как именно извлекать части (элементы структуры) этого объекта (структуры), он не имеет смысла и даже опасен. О чем компиляторы вас и предупреждают. Цитата(lks @ Apr 29 2007, 01:26)  Указатель на структуру должен быть всеже адресом первого байта в выделенном адресном пространстве, точно также как и в массивах - тип тут ни при чем. Тут что-то с компиляторами. Вы все время забываете о реальном железе в котором работает программа. Минимальная адресуемая единица зависит от разрядности CPU и способа его доступа к памяти. Если минимальная адресуемая единица байт, то да - указатель на структуру будет указывать на первый байт структуры. А если минмимальная адресуемая единица слово или 32-разрядное слово? Или наоборот, CPU с байтовым доступом к памяти, но первый элемент структуры не байт, а длинное длинное целое? Впрочем здесь я уже вслед за другими начинаю все повторять то же самое по третьему разу. Неужели вы до сих пор не поняли/не осознали? Понятие структуры в ЯВУ аналогично описанию объекта. Например, про детский мяч можно сказать что он: - круглый (описание формы) - даже шарообразный (описание формы) - красного цвета (описание цвета) - с двумя синими полосками (описание цвета) - упругий (описание реакции на внешнее воздействие) - резиновый (описание материала) - не тонет в воде (описание плотности) и т.п. каждое свойство в отдельности не дает полного описания объекта, но если их объединить, то получим полное описание мяча. Проблема в том, что все описания имеют разный тип/размерность. Объединив их в одно общее описание объекта, нельзя все свойства описания менять одинаково, т.к. они имеют разный тип и разный диапазон. Форме нельзя указать цвет, а реакции на внешнее воздействие нельзя назначить свойство формы. В противном случае мы можем получить такое описание мяча: форма - синяя, цвет - пирамидальный, упругость - тонет в парах ртути, плотность - тверже алмаза. Вам до сих пор еще не понятно?
|
|
|
|
|
Apr 29 2007, 14:26
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(Legotron @ Apr 28 2007, 23:58)  Я делал когда-то таким образом: Был массив, который представлял собой файл EMF формата. Там структуры записаны. У меня было несколько разных типов структур и 1 указатель, который я каждый раз приводил к типу той структуры, которая мне нужна. И получал доступ к их полям. Тока с упаковкой структур (надо/ненадо) нужно быть внимательнее. Возможно, что это и вариант. Непонял пока. Тут вопрос у меня очень похож - как у автора этой темы. В корневом каталоге SD - FAT16 дискрипторы файлов по 32 байта. Читаем данные секторами по 512 в буфер. Само собой напрашивается путь чтобы таскать структуру с описанием переменных (дискриптор) - по буферу. Что-то вроде маски должно получиться. По идее, нужно адрес байта в массиве - который легко извлекается - &BUFFER[i]; - присвоить началу структуры. Даже с получением адреса начала структуры проблемы нарисовались. Пока не получилось. Цитата(rezident @ Apr 29 2007, 01:35)  Извините, но я не понимаю термина "обычный указатель". Когда вы извлекаете адрес переменной с помощью оператора амперсанд - вы получаете адрес переменной. Вы знаете тип переменной? Простая процедура. Этот тип не требует описание его в "хидере". Это не термин - это просто обычный указатель, поддерживаемый стандартными процедурами. Цитата(rezident @ Apr 29 2007, 01:35)  Если минимальная адресуемая единица байт, то да - указатель на структуру будет указывать на первый байт структуры. Неужели вы до сих пор не поняли/не осознали?  Что я не понял/ не осознал? Цитата(rezident @ Apr 29 2007, 01:35)  Например, про детский мяч можно сказать что он: - круглый (описание формы) - даже шарообразный (описание формы) - красного цвета (описание цвета) - с двумя синими полосками (описание цвета) - упругий (описание реакции на внешнее воздействие) - резиновый (описание материала) - не тонет в воде (описание плотности) и т.п. Вы блещете интеллектом, мне прямо не удобно... Цитата(rezident @ Apr 29 2007, 01:35)  Вам до сих пор еще не понятно? Что мне еще до сих пор не понятно?
|
|
|
|
|
Apr 29 2007, 15:21
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(lks) Когда вы извлекаете адрес переменной с помощью оператора амперсанд - вы получаете адрес переменной. Вы знаете тип переменной? Простая процедура. Этот тип не требует описание его в "хидере". Это не термин - это просто обычный указатель, поддерживаемый стандартными процедурами. Ну я уже не знаю как вам объяснять.  На гайках и автомобилях не понимаете, на яблоки, арбузы и семячки перейти что ли? Указатель в СИ это такая же абстракция как и структура. Поведение указателя после компиляции программы в машинные коды, выполняемые CPU, зависит от конкретного CPU. Если CPU обращается к памяти побайтно, то нет никаких проблем, чтобы адресовать каждый байт. Но если разрядность шины памяти шире 8 бит, то возникают нюансы. На языке ассемблера разница выразится, например в том, что вместо команды MOV.W 0x8(R10), R14 будет использоваться команда MOV.B 0x8(R10), R14. В 16-битной архитектуре такая команда позволяет получить доступ к байту, в отличие от доступа к слову "по-умолчанию". Если в такой системе структура будет иметь выравнивание на байт, то есть вероятность 50/50, что вы обязательно налетите на глюки при использовании "словного" (16-битного) доступа к такой структуре. Причем это даже при доступе к массиву однородных данных относится. Пример. unsigned char mas[5]={0x00, 0x01, 0x02, 0x03, 0x04}; Вне зависимости от архитектуры и способа доступа к памяти байты могут расположится в памяти в порядке как 0x00, 0x01, 0x02, 0x03, 0x04, это нам гарантирует стандарт СИ. Однако извлечение их из памяти будет зависеть от описания способа доступа к памяти, т.к. в физической памяти первый байт массива может расположиться по нечетному адресу, который 16-разрядный CPU напрямую адресовать не может, т.к. у него счетчик (PC) кратно слову (2 байтам) инкрементируется, а не кратно 1 байту. Тогда при извлечении из физической памяти такого массива с 16-разядным доступом мы можем получить двоякий результат 0x00XX, 0x0201, 0x0403 или 0x0100, 0x0302, 0xXX04. Вот к чему может привести свободное манипулирование типами данных.
|
|
|
|
|
Apr 29 2007, 15:29
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(lks @ Apr 29 2007, 14:26)  Возможно, что это и вариант. Непонял пока. Слава Богу, что хоть зародилась мысль, что что-то "Непонял", а то до этого момента складывалось впечатление, что просто какой-то мессия удостоил нас своим присутсутствием  . С попыткой встать на путь истинный, Вас! Цитата Читаем данные секторами по 512 в буфер. Само собой напрашивается путь чтобы таскать структуру с описанием переменных (дискриптор) - по буферу. Что-то вроде маски должно получиться. По идее, нужно адрес байта в массиве - который легко извлекается - &BUFFER[i]; - присвоить началу структуры. Подсказка - байты не нужны. Массивы могут быть не только байтовые, но массивами структур. Цитата Когда вы извлекаете адрес переменной с помощью оператора амперсанд - вы получаете адрес переменной. Вы знаете тип переменной? Прочитайте медленно и по слогам, что писал, например, dxp по поводу указателя на void. Преред этим постарайтесь забыть, что Вы "опытный программист" на усеченном (стуктуры данных явно не использовали  )диалекте ASM под исключительно 8bit, контроллеры.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 29 2007, 15:44
|

инопланетянин
  
Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832

|
Цитата(Legotron @ Apr 28 2007, 23:58)  У меня было несколько разных типов структур и 1 указатель, который я каждый раз приводил к типу той структуры, которая мне нужна. И получал доступ к их полям. Тока с упаковкой структур (надо/ненадо) нужно быть внимательнее. Б.Р.Е.Д!Ой каюсь-каюсь я был в перегреве, когда писал это сообщение! Лучше поздно чем никогда! Уважаемый dxp писал: "чтобы можно было работать с объектом класса, указатель на него должен "знать" о строении (структуре) класса." тутТакже и со структурой: Код struct A {...}a; int * Ptr; struct A * Ptr2;
Ptr = (struct A *)&a; // сделать можно (и даже 1 поле структуры можно получить, если типы совпадут) :)))) Ptr->(поле); // так сделать нельзя (будет ругаться компилятор)
Ptr2 = &a; // всё тип-топ Ptr2->(поле); // анологично
Сообщение отредактировал Legotron - Apr 29 2007, 15:45
|
|
|
|
|
Apr 29 2007, 15:49
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(zltigo @ Apr 29 2007, 16:29)  Подсказка - байты не нужны. Массивы могут быть не только байтовые, но массивами структур. Могут, могут. А память где для них брать? Чтобы загрузить структуру предлагаете memcpy, а место в памяти пргограмм где взять? Меня этот путь не устраивает. Цитата(zltigo @ Apr 29 2007, 16:29)  Прочитайте медленно и по слогам, что писал, например, dxp по поводу указателя на void. Преред этим постарайтесь забыть, что Вы "опытный программист" на усеченном (стуктуры данных явно не использовали  )диалекте ASM под исключительно 8bit, контроллеры. Я месяца полтора назад в Keil-е все это уже попробовал. Структура у меня заполняется данными замечательно из буфера по указателю, но только когда я указывал на переменную внутри структуры. Это понятно? Пример: struct S{...}s; struct S* ps; ps=&s; не работатет, хотя должен. Я действительно программы пишу много и давно, только я не преподаватель информатики, я реальные вещи делаю, на реальном "железе". Общетеоретические иссенуации меня не интересуют.
|
|
|
|
|
Apr 29 2007, 15:54
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Legotron @ Apr 29 2007, 15:44)  Ptr = (struct A *)&a; // сделать можно (и даже 1 поле структуры можно получить, если типы совпадут) "Неможно". Цитата(lks @ Apr 29 2007, 15:49)  Могут, могут. А память где для них брать? Чтобы загрузить структуру предлагаете memcpy, а место в памяти пргограмм где взять? Обалдеть  . Все, граждане-господа-товарищи, я "пас"  . Возраст, нервы...
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 29 2007, 15:56
|

инопланетянин
  
Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832

|
Цитата(zltigo @ Apr 29 2007, 16:51)  "Неможно". why? Вот нормально работающий кусок... проверено. Код U16 TEMFClass::EMF_ScanRecords(const U8 * PData, U16 Size) { ENHMETAHEADER * MainHeader; EMR * Header; int i;
if(PData != NULL) { MainHeader = (ENHMETAHEADER *)PData; // вот тут Header = (EMR *)PData; for(i=0; i<MainHeader->nRecords; i++) // тут обращение к полю { //EMF_LUT.AddItem(Header); //EMF_LUT.CountItems(); #if DEBUG printf ("#%d - addr: %p value: %d \n",i,Header,Header->iType); #endif
Header = (EMR *)((U8 *)Header + Header->nSize); } return 0; } else return 1; }
|
|
|
|
|
Apr 29 2007, 16:23
|

инопланетянин
  
Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832

|
Цитата(zltigo @ Apr 29 2007, 17:06)  Потому, что указателю на int пытаетесь присвоить указатель на сруктуру, причем его еще дополнительно (масло маслянное) явно преобразовали к указателю на эту-же структуру. Полагаю там описка - должно быть явное преобразование указателя на структуру в указатель на int. К "куску" (в части работы с указателями) перетензий нет.  Блин, я опять все перепутал! Вы абсолютно правы! P.S. Я больше никогда не буду писать код в окне форума (ну разве, что очень простой), а то ерундовые вещи - и все равно ошибаюсь. Впредь буду приводить только реальные (работающие/неработающие) куски из программ, какими-бы там не были специфическими индентификаторы. P.S. P.S. Какими глючными были бы программы, если бы индентификаторы разрешалось писать тока 1 буквой (никогда бы не работали  )
|
|
|
|
|
Apr 29 2007, 16:43
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(rezident @ Apr 29 2007, 16:21)  Ну я уже не знаю как вам объяснять.  На гайках и автомобилях не понимаете, на яблоки, арбузы и семячки перейти что ли? Указатель в СИ это такая же абстракция как и структура. На семячках вы еще не упражнялись.  Если я напишу массив указателей unsigned char *buf[100]; - это абстракция? Если я напишу struct и перечислю список переменных - это тоже? Вообще-то компилятор выделит память под эти переменные - а память стоит денег - значит вещи вполне реальные.  Цитата(zltigo @ Apr 29 2007, 16:54)  Обалдеть  . Все, граждане-господа-товарищи, я "пас"  . Возраст, нервы... Если бы память позволяла - я бы поставил scanf со списком переменных и читал бы все из буфера, но это занимает памяти еще больше.
|
|
|
|
|
Apr 29 2007, 16:49
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(lks @ Apr 29 2007, 19:34)  Если я напишу массив указателей unsigned char *buf[100]; - это абстракция? Если я напишу struct и перечислю список переменных - это тоже? Вообще-то компилятор выделит память под эти переменные - а память стоит денег - значит вещи вполне реальные.  Мда. Тяжелый случай. Почти безнадежный.  Абстракция это сам термин "указатель". Потому что абстракции "указатель" нет однозначного соответствия его физической реализации. Пожалуй мне тоже придется последовать примеру zltigo и самоустраниться от дальнейшего жевания уже многократно пережеванной каши. А то в свете последних предложений выражение RTFM приравняют к самым грязным ругательствам и будут за его применение банить пожизненно
|
|
|
|
|
Apr 29 2007, 17:10
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(lks @ Apr 29 2007, 16:34)  Если я напишу struct и перечислю список переменных - это тоже? Вообще-то компилятор выделит память под эти переменные - а память стоит денег - значит вещи вполне реальные.  О какие тараканы в голове. Не выделит, если не будете перечислять список переменных. Объявление структуры, не содержащей списка переменных, не резервирует памяти, только описывает шаблон. Если структура имеет тег, то этим тегом далее можно пользоваться при определении структурных объектов - это то, что надо. P.S. Для тех, кто в танке - список переменных это то, что после закрывающейся фигурной скобки, а не внутри скобок. Цитата(rezident @ Apr 29 2007, 16:49)  Пожалуй мне тоже придется последовать примеру zltigo и самоустраниться... Не смог я  страсть к естествознанию не позволила
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 29 2007, 17:25
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(zltigo @ Apr 29 2007, 18:10)  Для тех, кто в танке - список переменных это то, что после закрывающейся фигурной скобки, а не внутри скобок. Список - это не только когда после фигурных скобок в структуре. Смотрите шире. Будем обсуждать варианты превода разных источников?
|
|
|
|
|
Apr 29 2007, 17:47
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(lks @ Apr 29 2007, 17:25)  Список - это не только когда после фигурных скобок в структуре. Не "список" а "список переменных", однако. Цитата Будем обсуждать варианты превода разных источников? Первоисточник он один. Варианты перевода, можно и пообсуждать (у меня настроение сегодня  ) Итак, пререводим. То, 'что в скобках' называется - "structure members" лично мне встречались варианты "члены структуры" и "'элементы структуры" больше по душе "элементы", но против буквального "членов" не возражаю  . Ваш ход. И, главное ,придавая филологический уклон беседе, не забудьте, что НЕ ВЫДЕЛЯЕТ память компилятор под структуру, если его об этом не попросить. Запомнили?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|