C почему указатель будет больше, чем целое число - PullRequest
4 голосов
/ 20 февраля 2012

Я сейчас играю с sizeof () в GCC на Linux-машине, и я нашел кое-что очень удивительное.

printf ("\nsize of int = %lu\n", sizeof(int));
printf ("\nsize of int* = %lu\n", sizeof(int *));

выходов

size of int = 4
size of int* = 8

Я думал, что размер указателя на целое число будет намного меньше, чем само фактическое целое число!

Я исследую встроенное программное обеспечениеПрямо сейчас, и я понимал, что передача по ссылке была более эффективной (с точки зрения власти), чем передача по значению.

Может ли кто-нибудь уточнить , почему более эффективно передавать по ссылке, чем по значению , если размер указателя больше, чем фактическое значение.

Спасибо!

Ответы [ 8 ]

9 голосов
/ 20 февраля 2012

Целое число может быть любого размера, который нравится автору компилятора, единственными правилами (в стандарте C) являются: а) int не меньше короткого или больше длинного, а б) int имеет по крайней мере 16 бит.

На 64-битной платформе весьма распространено использование int как 32-битной для совместимости.

5 голосов
/ 20 февраля 2012

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

3 голосов
/ 20 февраля 2012

Передача по ссылке более эффективна, поскольку не нужно копировать данные (кроме указателя). Это означает, что это эффективнее только при передаче классов со многими полями или структурами или любыми другими данными, размер которых превышает указатель на используемую систему.

В случае, который вы упомянули, действительно может быть более эффективным не использовать указатель, потому что фактическое значение меньше, чем указатель на него (по крайней мере, на машине, которую вы использовали). Учтите, что на 32-битной машине указатель имеет 4 байта (4 * 8 = 32 бита), в то время как на 64-битной машине, которую вы, очевидно, используете, указатель имеет 8 байтов (8 * 8 = 64 бита).

На более старых 16-битных машинах указатели требуют только 2 байта, возможно, некоторые встраиваемые системы все еще используют эту архитектуру, но я не знаю об этом ...

2 голосов
/ 21 февраля 2012

Указатель на целое число может указывать на одно целое число, но тот же указатель может также указывать на десять, двадцать, сто или один миллион целых чисел.

Очевидно, что передается один 8-байтовый указатель вместоодиночное 4-байтовое целое число не является победой;но передача одного 8-байтового указателя вместо одного миллиона 4-байтовых целых чисел, безусловно, такова.

2 голосов
/ 20 февраля 2012

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

1 голос
/ 20 февраля 2012

Одна вещь не имеет ничего общего с другой.Одним из них является адрес, указатель на что-то, не имеет значения, является ли это символом или коротким или int или структурой.Другой - это специфическая для языка вещь, называемая int, которую компилятор для этой системы и этой версии компилятора и, возможно, параметров командной строки определяют как некоторый размер.

Похоже, что вы работаете в 64-битной системе, поэтому все ваши указатели / адреса будут 64-битными.То, на что они указывают, - это отдельное обсуждение: длинные, вероятно, тоже будут 64-битными, иногда целыми, шорты, вероятно, все еще 16-битными, но не жестким / быстрым правилом и, как мы надеемся, 8-битными, но также не жестким / быстрым правилом.

Где это может быть еще хуже - это кросс-компиляция, при использовании llvm-gcc, до того, как clang был таким же твердым, как и сейчас.На 64-битном хосте байт-код генерировался на основе 64-битного хоста, поэтому 64-битные целые, 64-битные указатели и т. Д. Затем, когда вы выполняли бэкэнд для цели arm, он должен был использовать вызовы библиотеки компилятора для всего этого64 битная работа.Переменные вряд ли должны были быть шортами намного меньше целых, но были целыми.ключ -m32 был сломан, вы все равно получили 64-битные целые числа, поскольку хост не является конечной целью.Непосредственно у gcc такой проблемы нет, и в настоящее время у clang + llvm такой проблемы тоже нет.

Краткий ответ: язык определяет некоторые типы данных char, short, int, long и т. д., и эти типы данных имеютРеализация компилятора определенного размера.и адрес - это просто другой тип данных, определенный реализацией.это все равно что спросить, почему короткое число не такое же количество байтов, как длинное?Поскольку это разные типы данных, один короткий, другой длинный.Один - это адрес, другой - переменная, две разные вещи.

0 голосов
/ 20 февраля 2012

Указатель должен иметь возможность ссылаться на всю память. Если (виртуальная) память больше 4 байтов или около того, указатель должен быть больше 32 бит.

0 голосов
/ 20 февраля 2012

http://developers.sun.com/solaris/articles/ILP32toLP64Issues.html

При преобразовании 32-битных программ в 64-битные, только длинные типы и типы указателей изменяются в размере от 32 до 64 бит; целые числа введите int с размером 32 бита.

В 64-битных исполняемых файлах указатели являются 64-битными. Длинные целые также 64-битные, но только 32-битные.

В 32-битных исполняемых файлах указатели, int и long int являются 32-битными. 32-разрядные исполняемые файлы также поддерживают 64-разрядные "длинные длинные" целые числа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...