LINUX.ORG.RU

[C][указатели][вопрос] Похоже, чего-то не понимаю

 , ,


0

1

Почему каждому типу нужен свой тип указателя? Он же, вроде как, хранит только адрес, длина которого не зависит от типа данных, на который он указывает. Почему нельзя было сделать единый тип указателя для всего? Или это чтобы люди не запутались?

★★★★

Есть единый тип - void *, к нему можно скастовать что угодно

Или это чтобы люди не запутались?

Да.

annulen ★★★★★
()

1. Что это делает в Talks?

2. Статическая типизация.

3. Разыменовывание, адресная арифметика.

4. Почему не сделать один тип для всего?

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

>> Чтобы было меньше багов.

А как ты определишь разыменовыния для void*?

Правильно, в общем случае никак, т.к. информация о типе потеряна. Поэтому язык предоставляет средство для сохранения этой информации — типизированные указатели.

Relan ★★★★★
()
Ответ на: комментарий от Xenesz

Кроцессоры с сегментной адресацией, разделение кода и данных

namezys ★★★★
()
Ответ на: комментарий от Xenesz

Питоновские переменные приблизительно void*

Слишком приблизительно, да.

Begemoth ★★★★★
()

> Почему каждому типу нужен свой тип указателя

потому что на абстрактной машине может использоваться разный размер для разных указателей + примитивная статическая типобезопасность

Он же, вроде как, хранит только адрес, длина которого не зависит от типа данных

указатель != адрес, указатель определяет не только адрес памяти, но и тип данных

Почему нельзя было сделать единый тип указателя для всего?

void* есть

sched
()
Ответ на: комментарий от Xenesz

Простой указатель и указатель на член класса имеют разный размер. Но это конечно не относится к Си. В старых компиляторах для 16-битного реального режима помнится тоже был набор костылей для указателей. Т.н. модификаторы near, far. Но это тоже сильно притянутый за уши пример.

m0rph ★★★★★
()
Ответ на: комментарий от m0rph

модификаторы near, far

Курил, но не думал, что ещё актуальны.

Xenesz ★★★★
()
Ответ на: комментарий от sched

указатель != адрес

Компилятор располагает метаданными (этот самый тип указателя), а в скомпилированном коде они где? Я могу найти в массиве указателей их тип?

Xenesz ★★★★
()
Ответ на: комментарий от Xenesz

Массив - набор данных (объектов) одного типа, в нём не содержится тип данных, он уже определён массивом.

Компилятор располагает метаданными

тип данных - это не метаданные, это размер объекта, операции над ним и набор значений, которые он может представлять

sched
()
Ответ на: комментарий от sched

Вполне себе метаданные, если не располагаются в данных, но с ними связаны.

не содержится тип данных, он уже определён массивом

Если ты получил этот массив по указателю, приведённому к void*, сможешь определить, какого типа указатели в нём хранятся?

Xenesz ★★★★
()
Ответ на: комментарий от Xenesz

Нет, так как я получу void* указатель, который может быть преобразован в типизированный указатель, структуру, массив или вообще что угодно.

Или ты про массив указателей типа void*? Тогда я получаю массив объектов типа (void*). Определять их тип мне не нужно, так как он задан - void*. Типизированный указатель можно преобразовать в указатель типа void*, но с последним набор операций урезан.

Возвращаясь к вопросу указателей и адресов, void*, на практике может быть синонимом адреса. Но, в общем случае указатель - это более общее понятие. Например, про char* p известен не только адрес, но и его размер (CHAR_BIT) и набор значений (CHAR_MIN-CHAR_MAX).

sched
()
Ответ на: комментарий от Xenesz

В виндовом API до сих пор указатели обозначаются как LP… — long-pointer-чтототам. Рудимент со времён Win16, когда были и short-pointer'ы.

Miguel ★★★★★
()

[code=cpp] void *voidPtr = ...; int *intPtr = ...; [/code] а теперь *voidPtr сколько байт считывать из памяти? *intPtr - считывает sizeof(int) байт

anonymous
()
Ответ на: комментарий от encyrtid

Тьфу ты, блин. А слона-то я и не заметил...

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.