sizeof (некоторый указатель) всегда равняются четыре?

Предупреждение: Деление на ноль

Предупреждающее сообщение «Подразделение на ноль» является одним из наиболее часто задаваемых вопросов среди новых разработчиков PHP. Эта ошибка не вызовет исключения, поэтому некоторые разработчики будут иногда подавлять предупреждение, добавляя оператор подавления ошибок @ перед выражением. Например:

$value = @(2 / 0);

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

Чтобы исправить это предупреждение, вы должны переписать свое выражение, чтобы проверить, что значение не равно 0, если оно есть, сделать что-то еще. Если значение равно нулю, вы не должны делиться или изменять значение на 1, а затем делить так, что деление приводит к эквиваленту того, что он разделен только дополнительной переменной.

if ( $var1 == 0 ) { // check if var1 equals zero
    $var1 = 1; // var1 equaled zero so change var1 to equal one instead
    $var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
    $var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}

Вопросы, относящиеся:

217
задан user2618142 7 March 2014 в 22:07
поделиться

12 ответов

Гарантия, которую Вы получаете, является этим sizeof(char) == 1. Нет никаких других гарантий, включая никакую гарантию это sizeof(int *) == sizeof(double *).

На практике, указатели будут размером 2 в 16-разрядной системе (если можно найти один), 4 в 32-разрядной системе, и 8 в 64-разрядной системе, но нет ничего, чтобы быть полученным в доверии данному размеру.

183
ответ дан moffeltje 23 November 2019 в 04:16
поделиться

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

1
ответ дан Ed S. 23 November 2019 в 04:16
поделиться

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

1
ответ дан Will Bickford 23 November 2019 в 04:16
поделиться

Нет, размер указателя может варьироваться в зависимости от архитектуры. Существуют многочисленные исключения.

3
ответ дан Judge Maygarden 23 November 2019 в 04:16
поделиться

В целом, sizeof (в значительной степени что-либо) изменится, когда Вы скомпилируете на различных платформах. На платформе на 32 бита указатели всегда являются тем же размером. На других платформах (64 бита, являющиеся очевидным примером), это может измениться.

3
ответ дан Sean Reilly 23 November 2019 в 04:16
поделиться

Из того, что я вспоминаю, это основано на размере адреса памяти. Таким образом в системе с 32-разрядной схемой адреса, sizeof возвратится 4, так как это составляет 4 байта.

3
ответ дан Will Mc 23 November 2019 в 04:16
поделиться

В дополнение к различиям в бите 16/32/64 могут произойти еще более странные вещи.

были машины, где sizeof (интервал *) будет одним значением, вероятно, 4, но где sizeof (символ *) больше. Машины, что естественно адресные слова вместо байтов должны "увеличить" символьные указатели для определения, какую часть слова Вы действительно хотите для надлежащей реализации стандарта C/C++.

Это теперь очень необычно, поскольку аппаратные разработчики изучили значение адресуемости байта.

6
ответ дан Darron 23 November 2019 в 04:16
поделиться

С технической точки зрения стандарт C только гарантирует, что sizeof (символ) == 1, и остальное до реализации. Но на современной x86 архитектуре (например, Intel/МИКРОПРОЦЕССОРЫ AMD) это довольно предсказуемо.

Вы, вероятно, услышали процессоры, описанные как являющийся 16-разрядным, 32-разрядным, 64-разрядным и т.д. Это обычно означает, что процессор использует N-биты для целых чисел. Так как указатели хранят адреса памяти, и адреса памяти являются целыми числами, это эффективно говорит Вам, сколько битов будет используемыми для указателей. sizeof обычно измеряется в байтах, таким образом, код, скомпилированный для 32-разрядных процессоров, сообщит, что размер указателей 4 (32 бита / 8 битов за байт), и код для 64-разрядных процессоров сообщит, что размер указателей 8 (64 бита / 8 битов за байт). Это - то, куда ограничение 4 ГБ RAM для 32-разрядных процессоров прибывает из - если каждый адрес памяти соответствует байту, для обращения к большей памяти Вам нужны целые числа, больше, чем 32 бита.

17
ответ дан Joseph Garvin 23 November 2019 в 04:16
поделиться

если Вы компилируете для 64-разрядной машины, то это может быть 8.

24
ответ дан FryGuy 23 November 2019 в 04:16
поделиться

Просто другое исключение к уже отправленному списку. На 32-разрядных платформах указатели могут взять 6, не 4 , байты:

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

int main() {
    char far* ptr; // note that this is a far pointer
    printf( "%d\n", sizeof( ptr));
    return EXIT_SUCCESS;
}

, Если Вы компилируете эту программу с, Открывают Watcom и выполняют его, Вы доберетесь 6, потому что далекие указатели, которые это поддерживает, состоят из 32-разрядного смещения и 16-разрядных значений сегмента

30
ответ дан dmityugov 23 November 2019 в 04:16
поделиться

Даже на плоскости x86 платформа на 32 бита, можно получить множество размеров указателя, испытать это для примера:

struct A {};

struct B : virtual public A {};

struct C {};

struct D : public A, public C {};

int main()
{
    cout << "A:" << sizeof(void (A::*)()) << endl;
    cout << "B:" << sizeof(void (B::*)()) << endl;
    cout << "D:" << sizeof(void (D::*)()) << endl;
}

Под Visual C++ 2008, я добираюсь 4, 12 и 8 для размеров pointers-to-member-function.

Raymond Chen говорил об этом здесь .

36
ответ дан Eclipse 23 November 2019 в 04:16
поделиться

В дополнение к тому, какие люди сказали о 64-разрядном (или безотносительно) системы, существуют другие виды указателя, чем указатель на объект.

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

4
ответ дан Steve Jessop 23 November 2019 в 04:16
поделиться