Подтвердить что ты не робот

Значит ли размер указателей в C?

Возможные дубликаты:
Может ли размер указателей различаться в зависимости от того, на что он указывает?
Существуют ли какие-либо платформы, где указатели на разные типы имеют разные размеры?

Возможно ли, что размер указателя на float в c отличается от указателя на int? Пробовав это, я получаю тот же результат для всех видов указателей.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("sizeof(int*): %i\n", sizeof(int*));
    printf("sizeof(float*): %i\n", sizeof(float*));
    printf("sizeof(void*): %i\n", sizeof(void*));
    return 0;
}

Какие выходы здесь (OSX 10.6 64 бит)

sizeof(int*): 8
sizeof(float*): 8
sizeof(void*): 8

Можно ли предположить, что указатели разных типов имеют одинаковый размер (на одной арке, конечно)?

4b9b3361

Ответ 1

Указатели не всегда имеют одинаковый размер на одной арке.

Вы можете больше узнать о понятиях "ближнего", "дальнего" и "огромного" указателей, как пример случая, когда размеры указателя отличаются...

http://en.wikipedia.org/wiki/Intel_Memory_Model#Pointer_sizes

Ответ 2

В старые дни, используя, например, Borland C на платформе DOS, было в общей сложности (я думаю) 5 моделей памяти, которые в какой-то мере могут быть смешаны. По сути, у вас был выбор небольших или больших указателей на данные, а также небольшие или большие указатели на код и "крошечная" модель, где код и данные имели общее адресное пространство (если я правильно помню) 64K.

В программе, которая иначе была построена в "крошечной" модели, можно было указать "огромные" указатели. Поэтому в худшем случае в одной и той же программе можно было указать указатели разного размера на один и тот же тип данных!

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

Ответ 3

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

Этот оператор не относится к указателям на функции, они могут иметь разную ширину. По этой причине в указателях функции каста C99 на void* присутствует поведение undefined.

Ответ 4

Как я понимаю, в стандарте C нет ничего, что гарантирует, что указатели на разные типы должны быть одного размера, поэтому теоретически int * и float * на одной платформе могут быть разных размеров без нарушения каких-либо правил.

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

На практике вы вряд ли столкнетесь с какой-либо реализацией, которая использует указатели разного размера, если вы не отправитесь в некоторые довольно неясные места.

Ответ 5

Да, размер указателя зависит от платформы. В частности, размер указателя зависит от архитектуры целевого процессора и "битности", которую вы компилируете.

Как правило, на 64-битной машине указатель обычно 64 бит, на 32-битной машине обычно 32 бита. Однако есть исключения.

Поскольку указатель - это просто адрес памяти, он всегда имеет тот же размер, независимо от того, что содержит в нем память. Таким образом, указатель на float, char или int имеют одинаковый размер.

Ответ 6

Да. Это необычно, но это, безусловно, произойдет в системах, которые не являются байтовыми. Например. 16-разрядная система с 64 Кб = 128 КБ памяти. В таких системах у вас все еще есть 16-битные int-указатели. Но указателю char на 8 бит char нужен дополнительный бит, чтобы указать высокий байт/младший байт внутри слова, и, следовательно, у вас будут указатели 17/32 бит char.

Это может звучать экзотично, но многие DSP тратят 99.%% времени на выполнение специализированного числового кода. Звуковой DSP может быть немного проще, если все, с чем ему приходится иметь дело, - это 16-битные данные, в результате чего компилятор может эмулировать случайную 8-битную математику.

Ответ 7

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

Например, в архитектуре, где целые числа составляют 4 байта и должны быть выровнены по 4 байт, указатель int может быть на два бита меньше, чем указатель char или void. Если на самом деле актер делает смещение в обоих направлениях, с C99 вы в порядке. Он с благодарностью говорит, что результат приведения указателя char к некорректно выровненному указателю int undefined.

См. стандарт C99. Раздел 6.3.2.3

Ответ 8

Можно ли предположить, что указатели разных типов имеют одинаковый размер (на одной арке, конечно)?

Для платформ с плоской моделью памяти (== все популярные/современные платформы) размер указателя будет таким же.

Для платформ с сегментированной моделью памяти для повышения эффективности часто существуют типы указателей разных типов. (Например, far указатели в DOS, так как 8086 CPU использует сегментированную модель памяти.) Но это специфичная для платформы и нестандартная.

Вероятно, вам следует помнить, что в С++ размер обычного указателя может отличаться от размера указателя на виртуальный метод. Указатели на виртуальные методы должны сохранять дополнительный бит информации, чтобы не работать должным образом с полиморфизмом. Это, вероятно, только исключение, о котором я знаю, что по-прежнему актуально (поскольку я сомневаюсь, что сегментированная модель памяти никогда не вернется).

Ответ 9

Указатель - это адрес памяти - и, следовательно, должен быть одинаков на конкретной машине. 32-разрядная машина = > 4 байта, 64 бит = > 8 байтов.

Следовательно, независимо от типа элемента, на который указывает указатель, размер указателя на конкретном компьютере будет таким же (поскольку пространство, необходимое для хранения адреса памяти, будет одинаковым.)

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

Ответ 10

Указатели всегда имеют одинаковый размер на одной и той же арке, независимо от того, какой тип данных он указывает. В противном случае такие вещи, как кастинг между разными типами указателей, будут бесполезны и ломают много вещей.

Многие общие методы кодирования зависят от различения между, например, указателем void (или char) для различных структур, в зависимости от размера.

Возьмите даже стандартный printf(), он должен иметь возможность отображать указатели на различные типы данных. Если указатели имели разный размер, реализация printf может стать очень запутанной.

Ответ 11

Существуют платформы, где указатели на функции отличаются от других указателей.

Я никогда не видел больше вариаций, чем это. Все остальные указатели должны быть не больше sizeof (void *), поскольку стандарт требует, чтобы их можно было отбросить на void * без потери информации.