|
|
  |
структуры в С, копирование в байтовый массив |
|
|
|
Apr 28 2007, 14:01
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(lks @ Apr 28 2007, 15:11)  Значок & - называется амперсанд, или оператор указания. Неверно. & - это оператор взятия адреса, а не оператор указания. Цитата(lks @ Apr 28 2007, 15:11)  Когда пишу "амперсанд структуры" - подразумеваю - &BootSector, т.е. получение адреса по которому располагается данные описанные в структуре. Какие данные? Все, что-ли? "Амперсанд структуры" - это совершенно неверная терминология, отсюда и путаница, и вопросы. &BootSector - это адрес структуры (а не амперсанд). Употребляйте правильную терминологию и Вас правильно поймут. Цитата(lks @ Apr 28 2007, 15:11)  Этот пример кода взят (судя по всему) из учебника - автором темы. Никто не сомневается что он должен работать. unsigned char *ptr = &BootSector (где BootSector - структура), работать не должно и не работает. Цитата(lks @ Apr 28 2007, 15:11)  Автор темы попытался применить его в ИАР компиляторе - результат: не работатет. Потому, что не должен он работать. Ни в каком компиляторе, а не только в IAR. Цитата(lks @ Apr 28 2007, 15:11)  Вопрос в том: почему он не работатет Потому, что в этом выражении возникает элементарная несовместимость типов - нельзя указателю на один тип присваивать адрес объекта другого типа. Потому, что в этом случае работать с указателем будет небезопасно - компилятор, зная тип указателя, будет выполнять действия, пригодные к типу этого указателя, а на самом деле будет работать с объектом совершенно другого типа. Вслепую. Это источник очень гадких и трудноуловимых глюков. Статический контроль типов защищает от этой ситуации. Присваивать указателю void* разрешается потому, что с этим указателем ничего делать нельзя - к объекту не доступиться. Цитата(lks @ Apr 28 2007, 15:11)  и развивая мысль дальше - неплохо бы сделать совмещение начала адресов массива и структуры в памяти - тогда необходимость копирования данных из одного места в другое автоматически отпадает. Глубины этой мысли я асилить не смог. Цитата(lks @ Apr 28 2007, 15:11)  Так лучше? No comments.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Apr 28 2007, 15:22
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(dxp @ Apr 28 2007, 15:01)  Неверно. & - это оператор взятия адреса, а не оператор указания. Вот так, да? Вы меня насмешили. Тогда указатель на что будет указывать? Кстати термин не я придумал : Энциклопедия языка Си. Я. Белецкий. М. Мир. Стр 52. Цитата(dxp @ Apr 28 2007, 15:01)  &BootSector - это адрес структуры (а не амперсанд). Употребляйте правильную терминологию и Вас правильно поймут. Вы там это серъезно об этом? Вот эта хрень "&" - собстно и называется амперсанд. Так как (всеже) присвоить адрес структуры указателю? Цитата(dxp @ Apr 28 2007, 15:01)  нельзя указателю на один тип присваивать адрес объекта другого типа. Потому, что в этом случае работать с указателем будет небезопасно - компилятор, зная тип указателя, будет выполнять действия, пригодные к типу этого указателя, а на самом деле будет работать с объектом совершенно другого типа. Ну тогда обясните почему я всегда могу получить адресс массива через амперсанд не зависимо от типа данных, а от структуры не получается. Я могу привести ссылку где утверждается, что в этом случае возможны ошибки чтения данных (в случае со структурой), и программисту надо быть внимательным. Т.е. не предполагается что эта функция заблокирована. Мы говорим о начальном адресе структуры, а не о типе данных. Вот пример приведен во всех учебниках со структурой - а вы заладили - нельзя, нельзя. Цитата(dxp @ Apr 28 2007, 15:01)  Глубины этой мысли я асилить не смог. No comments.  Чтож тут такого умного? Полистайте какие-нибудь исходники написанные на языке Си - это типовая операция, вааще-то. Вам сказать нечего - вот и придумываете разные предлоги. Нет бы сказали честно - не пишем мы на Си - только на Дэлфи (фортране, или кто на чем). :-)
|
|
|
|
|
Apr 28 2007, 15:47
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(o-henry @ Apr 28 2007, 16:40)  Уважаемый tolik_zp! На Ваш вопрос Вы уже получили ответ. Закрыли бы Вы этот топик, а то тут такой поток бреда начинается - не дай бог другие начинающие программировать на "C" это читать будут. "Хвост", перед школьниками, будете распускать в другом месте. А я не начинающий программист, к вашему сведению..
|
|
|
|
|
Apr 28 2007, 16:58
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(zltigo @ Apr 28 2007, 16:57)  Тем хуже  , что Вам так кажется. Мои соболезнования. Чем хуже? Говорим, говорим. По существу проблемы что сказать можете? Вы предложили использовать библиотечную процедуру memcpy для копирования данных из структуры в массив. Это вызовет увеличение кода, время выполнения и ненужное копирование всего массива - это очень плохо, вы согласны? Я предложил добавить в структуру пременную типа unsigned char (если она там отсутствует) и использовать присвоение на указатель ее адреса. В остальном все без изменений. Положительный момент в том что не нужно копировать весь массив, не расходуется память для библиотечной программы memcpy и т.д. Это работает везде - можете проверить. Также я предложил обсудить вариант когда адрес массива и структуры совпадают в памяти. В этом случае не потребуется производить вообще никаких действий с данными. В ответ слышу только вопли... Ну разве я виноват, что вы плохо разбираетесь в языке Си?
|
|
|
|
|
Apr 28 2007, 17:10
|

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

|
Цитата(lks @ Apr 28 2007, 16:58)  По существу проблемы что сказать можете? Позвольте спросить прямо - Вы дурак или прикидываетесь? Здесь не единожды расказано, как: 1. делать явное приведение типов указателей если не нужно копировать структуру в массив, или как автор первоначального вопроса хотел для дальнейшего побайтного копирования. 2. как эффективно скопировать структуру в массив (что собственно и являлось первоначальным вопросом) 3. как сделать union из массива и структуры (хотя я лично не вижу в этом никакого смысла) ввиду естественности п.1.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 28 2007, 17:21
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(lks @ Apr 28 2007, 19:22)  Вот так, да? Вы меня насмешили. Тогда указатель на что будет указывать? Кстати термин не я придумал : Энциклопедия языка Си. Я. Белецкий. М. Мир. Стр 52. Не читайте больше эту книжку. Фтопку ее. Серьезно. Читайте Д.Ричи, Б.Керниган "Язык программирования С". Цитата(lks @ Apr 28 2007, 19:22)  Вы там это серъезно об этом? Вот эта хрень "&" - собстно и называется амперсанд. Да, эта хрень "&" действительно называется амперсандом. А вот эта хрень &BootSector в языках программирования С/С++ называется адресом объекта. Цитата(lks @ Apr 28 2007, 19:22)  Так как (всеже) присвоить адрес структуры указателю? Код typedef struct { ... } TBootSector;
TBootSector *p; TBootSector BootSector;
p = &BootSector; Если же хочется присвоить адрес структуры указателю на ДРУГОЙ тип, что является потенциально опасным, то это тоже можно сделать, но при этом надо сообщить компилятору, чтобы он не возмущался, что мы делаем эту опасную вещь осознанно. Для этого используется ручное преобразование типа: Код char *p;
p = (char*)&BootSector; Я понятно объясняю?  Цитата(lks @ Apr 28 2007, 19:22)  Ну тогда обясните почему я всегда могу получить адресс массива через амперсанд не зависимо от типа данных, а от структуры не получается. И от структуры взять адрес тоже получается. Вот только пихать его куда попало не получается просто так. И это правильно. С массивом есть одна особенность: про массивы есть правило, что адрес массива является адресом его первого элемента. Это логично и безопасно, т.к. все элементы в массиве одинаковые - т.е. адресная арифметика с указателем, имеющим адрес массива, работает правильно. А вот с другими агрегатными объектами, к которым относится и структура, это не верно. Кстати, адрес массива сунуть, например, в указатель на структуру Вам вряд ли удастся по тем же причинам, почему нельзя адрес структуры сунуть в указатель на char. Цитата(lks @ Apr 28 2007, 19:22)  Вот пример приведен во всех учебниках со структурой - а вы заладили - нельзя, нельзя. Чтож тут такого умного? Какой пример? Приведите его сюда, плиз. Со ссылкой на учебник. Цитата(lks @ Apr 28 2007, 19:22)  Полистайте какие-нибудь исходники написанные на языке Си - это типовая операция, вааще-то. Вам сказать нечего - вот и придумываете разные предлоги. Нет бы сказали честно - не пишем мы на Си - только на Дэлфи (фортране, или кто на чем). :-) Я уже много всякого полистал насчет и С, и С++, не надо меня отсылать. Не хочу показаться невежливым, но приходится констатировать факт, что Вы не знаете элементарных вещей из ЯП С и, что самое плохое (для Вас) и неприятное (для меня), упорствуете в этом невежестве. P.S. Дельфи и фортран я почти не знаю, никогда на них ничего серьезного не писал. На Си действительно уже давно не пишу, все больше на С++, но в обсуждаемых аспектах эти языка почти совершенно одинаковы. P.P.S. Что-то я утомился и желание вести эту дискуссию (в тоне последней Вашей фразы) у меня пропало. Всего Вам хорошего.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Apr 28 2007, 17:48
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(lks @ Apr 28 2007, 18:22)  Ну тогда обясните почему я всегда могу получить адресс массива через амперсанд не зависимо от типа данных, а от структуры не получается. lks, может вам образный пример поможет?  Пускай данные будут гайками, массив данных - ящик с одинаковыми гайками, разложенными по ячеечкам, а структура это автомобиль. Когда вы указываете на массив данных, то даете отмашку в направлении ящика с гайками. Причем все гайки в этом ящике одинаковые и расположение их тоже одинаково. Когда же вы указываете на структуру, то отмашка будет уже на весьма сложное устройство - автомобиль. В этом устройстве тоже есть такие же гайки, как и в ящике, но кроме гаек там еще туева хуча других железок, расположенных и соединенных между собой весьма замысловатым образом. Если вы указали на данные (гайки) и попросили кого-либо принести третью по счету гайку, то он выполнит это без проблем. А вот с автомобилем, так просто не получится. Чтобы достать из автомобиля третью гайку, этому "кому-либо" понадобится как минимум список деталей автомобиля (описание структуры) и инструмент для его разборки/сборки и извлечения этой третьей гайки (механизм доступа к структуре). Надеюсь, такая аналогия отличий указателя на данные и структуру вам будет понятна?
|
|
|
|
|
Apr 28 2007, 19:00
|
Участник

Группа: Новичок
Сообщений: 29
Регистрация: 16-03-07
Из: МО, г.Балашиха
Пользователь №: 26 210

|
Дежа-вю... Юзер: - Я решил сварить яйцо в микроволновке - оно взорвалось. Что я сделал не так? Суппорт: - Читайте инструкцию. Яйца в микроволновке готовить нельзя. Юзер: - Я завернул его в фольгу - оно всё равно взорвалось. Что я сделал не так? Ну и т.д.
lks, несколько уважаемых тут человек с многолетним стажем попытались тебе доступно, с примерами объяснить, что желаемое тобой - это ошибка, описана в стандарте, по которому пишуться компиляторы. Ты с этим не согласен и продолжаешь убеждать присутсвующих в своей правоте, вводя свою новую терминологию и новые сущности на общепринятые понятия и термины. Ладно, право на заблуждение - это тоже твой законное право, никто на него не посягает. И люди, потратившие своё жизненное время на твои заблуждения, не павлины, распушающие хвосты перед новичками, они бестолковые бараны, т.к. сразу не врубились что их усилия и потраченное время тщетны на корню. Я, наверное такой же баран, раз трачу время и пишу это.
Давай попробую попроще объяснить. Чисто по ситуации. Любой компилятор, написанный по существующим стандартам, в том числе и ИАР, будет выдавать ошибку на неявное приведение типов. Это сущность, данность, факт, фича (выбрать понятный термин), которая есть и от непонимания/неприятия тобой этой сущности она НЕ изменится, данный компилятор НЕ перестанет выдавать ошибку на этот код.
Как в рекламе в метро, выход есть! Их два: 1) Исправить код для соответсвия правилам и не трах... себе и людям мозги, 2) Написать или заказать написание компилятора под свои требования. И будет тебе счастье. Адрес московской фирмы, пишущей компиляторы, дам, если надо.
(lks @ Apr 28 2007, 15:47) >> А я не начинающий программист, к вашему сведению..
Тем более, раз плюнуть LKS-компилер написать. А кстати, звучит!
|
|
|
|
|
Apr 28 2007, 21:34
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(dxp @ Apr 28 2007, 18:21)  P.P.S. Что-то я утомился и желание вести эту дискуссию (в тоне последней Вашей фразы) у меня пропало. Всего Вам хорошего. Извините если чем обидел - в мыслях не было ничего плохого. typedef struct { ... } TBootSector; TBootSector *p; TBootSector BootSector; p = &BootSector; Честно сказать с такой конструкцией как вы предлагаете не сталкивался. У меня установлен Keil, завтра попробую загрузить в проц - посмотрим что получится. Цитата(rezident @ Apr 28 2007, 18:48)  Надеюсь, такая аналогия отличий указателя на данные и структуру вам будет понятна?  С гайками то это вы круто завернули! Аналагии отличий указателей на данные и структуру в гаечном варианте принимаются. Если бы я сначала не попробовал этот фрагмент на компиляторе и не загружал бы его потом в демоплату - может быть тут умные излияния "богоподобных титанов программирования" пропустил бы мимо ушей. Мы не говорим о теории программирования. Как должно быть кого интересует? Разработчиков компиляторов? Тут товарищ знает адрес. Это к нему. Цитата(Vladimir Chekin @ Apr 28 2007, 20:00)  Давай попробую попроще объяснить. Давайка я тебе тоже попроще объясню. Есть компиляторы, а есть компиляторы. На одних твоя фича идет, на других нет. Трудно понять?
Сообщение отредактировал lks - Apr 28 2007, 21:36
|
|
|
|
|
Apr 28 2007, 22:26
|
Местный
  
Группа: Новичок
Сообщений: 493
Регистрация: 18-06-06
Пользователь №: 18 143

|
Цитата(dxp @ Apr 28 2007, 18:21)  Какой пример? Приведите его сюда, плиз. Со ссылкой на учебник. Еще один пример. struct S {...}s; struct S *ps; ps=&s; Программирование в среде Си для ПЭВМ ЕС. авторы. Стр 125. Тоже в топку? Цитата(rezident @ Apr 28 2007, 23:19)  А что у вас в "такой конструкции" вызывает удивление? Непонятно пока где описать этот тип данных - TBootSector *p; Этот адрес потом непереписать в обычный указатель? Ну и как на эту "баламутину" отреагирует Keil допустим. И все же читал где-то, сейчас не могу вспомнить, не должно быть запрета на получение адреса структуры. Указатель на структуру должен быть всеже адресом первого байта в выделенном адресном пространстве, точно также как и в массивах - тип тут ни при чем. Тут что-то с компиляторами.
Сообщение отредактировал lks - Apr 28 2007, 22:40
|
|
|
|
|
Apr 28 2007, 22:58
|

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

|
Цитата(lks @ Apr 28 2007, 23:26)  И все же читал где-то, сейчас не могу вспомнить, не должно быть запрета на получение адреса структуры. Указатель на структуру должен быть всеже адресом первого байта в выделенном адресном пространстве, точно также как и в массивах - тип тут ни при чем. Тут что-то с компиляторами. Я делал когда-то таким образом: Был массив, который представлял собой файл EMF формата. Там структуры записаны. У меня было несколько разных типов структур и 1 указатель, который я каждый раз приводил к типу той структуры, которая мне нужна. И получал доступ к их полям. Тока с упаковкой структур (надо/ненадо) нужно быть внимательнее.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|