|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
|
Указатель на void и работа с ниим28.04.2021, 18:12. Показов 8730. Ответов 45
Здравствуйте!
Недавно начал знакомство с программированием на C. Читал про указатели. Наткнулся на указатели на void. Насколько я понимаю, эта штука позволяет реализовывать обобщённые алгоритмы?! Предположим, я хочу реализовать алгоритм линейного поиска в массиве. Какой дизайн данной функции? Мой массив хранит указатели типа void? Как мне в таком случае пробежаться по массиву? Мне нужно знать размер элемента? Как мне сравнить элементы? Я должен передавать в функцию компаратор (в виде указателя на функцию?). Вопросы, одни вопросы. Ответов на которые у меня нет.
0
|
|
| 28.04.2021, 18:12 | |
|
Ответы с готовыми решениями:
45
Функция принимает указатель на void и возвращает указатель на int Дописать методы void pop_back(void); T& back(void); T& front(void); void erase (iterator p) |
|
844 / 353 / 68
Регистрация: 20.11.2012
Сообщений: 852
|
|||||||||||||
| 28.04.2021, 22:21 | |||||||||||||
|
Зачем так делать вообще? К типу void* можно привести любой указатель. Т.е.
1
|
|||||||||||||
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
||||||||||||||||||||
| 28.04.2021, 22:29 | ||||||||||||||||||||
int никто никогда не сравнивает путем вычитания, ибо при переполнении получится чушь.qsort с параметрами конкретных типов, чтобы потом заниматься "овнокодингом": пионэрским приведением типа с неопределенным поведением.Функции сравнения для qsort всегда имеют параметры типа const void * и только const void *, без вариантов. Сравнение двух int делается так
Во-вторых, item вы в таком случае получаете через memcpy
Вы сами пока не знаете, чего хотите. Порка вы сами не поймете, чего вы хотите, тратить время в форуме совершенно бесполезно.
2
|
||||||||||||||||||||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
||||||||||||
| 28.04.2021, 22:42 [ТС] | ||||||||||||
|
я понял.
Когда я пишу
0
|
||||||||||||
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
||
| 28.04.2021, 22:48 | ||
|
0
|
||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
|||||||||||||||||||||
| 28.04.2021, 22:50 [ТС] | |||||||||||||||||||||
|
Получается, если у меня есть такие куски кода:
0
|
|||||||||||||||||||||
|
844 / 353 / 68
Регистрация: 20.11.2012
Сообщений: 852
|
|||
| 28.04.2021, 22:51 | |||
|
Однако почему приведение типа функции это UB? Размер указателя на void и указателя на int равны ведь? (x86) push 4 байта, push 4 байта, call func. В стандарте Си это есть? Надо посмотреть.
0
|
|||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
|
| 28.04.2021, 22:51 [ТС] | |
|
WhiteP, вы мне очень помогли. Большое спасибо.
0
|
|
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
||
| 28.04.2021, 22:57 | ||
|
Типы int (const int *, const int *) и int (const void *, const void *) не совместимы. (http://port70.net/~nsz/c/c11/n1570.html#6.2.7, http://port70.net/~nsz/c/c11/n1570.html#6.7.6.3p15)Языку С глубоко плевать на то, какие там размеры имеют указатели void * и int *. Это здесь никакой роли не играет. Однако в общем случае в С void * и int * имеют разные размеры.
0
|
||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
|
| 28.04.2021, 23:00 [ТС] | |
|
0
|
|
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
||
| 28.04.2021, 23:13 | ||
void * - это универсальный указатель, который должен уметь представлять любой адрес данных.А int * - это указатель, который может указывать только на int (или быть нулевым). Вполне может быть, что особенности хранения int на данной платформе (выравнивание, регион памяти) таковы, что для int * можно использовать более компактный адрес, чем для void *.Язык С гарантирует совпадение представлений указателей только для 1. void *, char *, signed char *, unsigned char *2. Указатели на квалифицированные версии одного и тот же типа ( const, volatile)3. Все struct * указатели между собой4. Все union * указатели между собойБольше никаких совпадений нет.
1
|
||
|
844 / 353 / 68
Регистрация: 20.11.2012
Сообщений: 852
|
||||
| 28.04.2021, 23:36 | ||||
|
ISO/IEC 9899:201x 6.3.2.3-8
Получается, стандарт просто не оговаривает (читай не гарантирует) совпадение представлений для отличных от char* указателей с void*.
0
|
||||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
||
| 29.04.2021, 07:24 [ТС] | ||
|
0
|
||
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
||
| 29.04.2021, 07:34 | ||
int * и не должен уметь адресовать любой байт памяти. Указатель int * должен уметь адресовать только объекты типа int. На некоей машине с 8-байтовым int и строгими требованиями выравнивания в указателе int * три младших бита будут всегда равны нулю - вот мы уже получили указатель, которому "не нужны" его младшие три бита.А если на какой-то экзотической платформе требования выравнивания для типа int равны 256 - мы получаем указатель, которому "не нужен" его младший байт.
1
|
||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
||||||||
| 01.05.2021, 16:35 [ТС] | ||||||||
|
Такой вопрос. Предположим, у нас есть такой массив:
Как правильно организовать функцию удаления? Ну т.е.. если бы мы писали на ООП языке, то можно было бы вызвать деструктор, а как тут? Добавлено через 3 минуты Я придумал только один способ удаления. Это передавать функцию удаления в качестве параметра! Кажется, что по другому нельзя?!
0
|
||||||||
|
фрилансер
6501 / 5732 / 1134
Регистрация: 11.10.2019
Сообщений: 15,350
|
|
| 01.05.2021, 18:08 | |
|
0
|
|
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
||
| 01.05.2021, 18:26 | ||
|
Мы адресуем не указатели, мы адресуем объекты типа int - целые числа. Если объекты типа int на некоей платформе выравниваются на границу 8 байтов, то для адресации таких объектов на этой платформе уже не нужен полный адрес, а достаточно "урезанного" адреса: на 3 бита короче, чем полный.То есть указатель int * на такой платформе может быть на 3 бита короче, чем указатель void *. Вот вам готовая потенциальная разница в представлениях между указателями int * и void *. Все.Это совсем не обязательно означает, что такая разница выльется в физическое "укорачивание" указателя int *. Она может вылиться в укорачивание, а может вылиться в просто обнуление младших битов указателя или еще во что-то. А может вообще ни во что не вылиться. Это лишь абстрактный пример.Каким боком здесь "адресация битов" и зачем вы ее сюда приплели - мне не ясно. --- P.S. Именно по этой причине стандарты языков С и С++ говорят, что если вы сделаете преобразование указателей "туда-сюда" по схеме T * -> U * -> T *, то в результате вы гарантированно получите исходное значение указателя только в том случае, когда требования выравнивания типа U не являются более строгими, чем требования выравнивания типа T.
0
|
||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
|
| 01.05.2021, 18:29 [ТС] | |
|
0
|
|
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
||||||
| 07.05.2021, 15:41 [ТС] | ||||||
|
Подскажите, пожалуйста, какой дизайн должен быть, если я хочу создать простой связный список, который будет хранить любой тип дынных.
Я думал, сделать так:
0
|
||||||
|
фрилансер
6501 / 5732 / 1134
Регистрация: 11.10.2019
Сообщений: 15,350
|
||
| 07.05.2021, 16:45 | ||
|
1
|
||
|
3 / 3 / 1
Регистрация: 02.03.2013
Сообщений: 231
|
|||||||||||
| 14.05.2021, 08:48 [ТС] | |||||||||||
|
Как быть, если я хочу написать алгоритм бинарного поиска. Для стандартных типов всё просто, например, для чисел это будет так:
Кликните здесь для просмотра всего текста
Но как быть, если тип производный? Когда я писал свою реализацию линейного поиска, то передавал компаратор, и выглядело это так: Кликните здесь для просмотра всего текста
Получается, что в случае с бинарным поиском я должен передавать два компаратора? Или можно обойтись одним?
0
|
|||||||||||
| 14.05.2021, 08:48 | |
|
Указатель на void Указатель типа void Указатель типа void c++ Указатель void в структуре Структуры и указатель на void Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
|
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2.
Задача:
Обеспечить запись документа в регистр сведений независимо от. . .
|
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется.
Ну как вам?
|
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания
источниках данных и элементов формы(текстовые поля и метки), опирается все
это на технологию событий и мета. . .
|
|
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml,
в чате форсили функторы модулей как суперфичу.
Пытаясь отдуплить концепт, наткнулся на тутор с простым примером.
А главный принцип обучения от. . .
|
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
|
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
|
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства.
Жизнь действительно предъявляет каждому. . .
|