В последних двух утверждениях существует любая реальная разница между realPointer
и fakePointer
. Будут ли они оба обеспечивать те же функциональные возможности?
int num = 0;
int *realPointer = #
int fakePointer = #
В последних двух утверждениях существует любая реальная разница между realPointer
и fakePointer
. Будут ли они оба обеспечивать те же функциональные возможности?
int num = 0;
int *realPointer = #
int fakePointer = #
int fakePointer = #
Это недействительно C, он нарушает правила простого назначения и не компилируется.
Однако, если бы вы сделали int fakePointer = (int)#
, тогда единственное различие заключалось бы в том, что нет никаких гарантий того, что вы можете надежно использовать fakePointer, конверсии из указателей в целые числа определены по реализации и могут также привести к поведению undefined (6.3.2.3):
Любой тип указателя может быть преобразован в целочисленный тип. Кроме того, ранее указанный, результат определяется реализацией. Если результат не может быть представлен в целочисленном типе, поведение undefined. Результат не должен находиться в диапазоне значений любых целочисленный тип.
Чтобы безопасно и переносимо конвертировать между указателями и целыми числами, вы не должны использовать int
, но тип uintptr_t
найден в stdint.h.
Переменная, объявленная как указатель, семантически отличается от переменной, не объявленной как указатель. Компилятор (и язык) позволит вам делать вещи с указателем, который вы не можете сделать с помощью не указателя. И наоборот.
Самое большое отличие заключается в том, что вы можете разыменовывать указатель, но вы не можете сделать это с помощью не указателя.
Например, используя переменные в вашем коде, мы можем сделать *realPointer = 5
, чтобы сделать num
назначено значение 5
, но выполнение *fakePointer = 5
не допускается и не имеет смысла, так как fakePointer
на самом деле не указатель.
int num = 0;
int *realPointer = #
int fakePointer = #
В последних двух утверждениях любая реальная разница между realPointer и fakePointer.
Ваш fakePointer
НЕ является указателем. Это целое число со значением как адрес переменной num. При компиляции с настройками по умолчанию вы можете уйти. Но, как заметил Лундин, это действительно неверный код. Используя gcc
с флагом CFLAGS="-g -Wall -std=c99 -O3 -pedantic-errors"
, вы получите эту ошибку:
error: initialization makes integer from pointer without a cast
Пока ваш realPointer
действительно указывает на переменную num
, и вы можете разыменовать ее. Вы не можете сделать ничего подобного с помощью fakePointer
- и на самом деле назначение в fakePointer
недействительно.
Если вы переходите к литеральным значениям (то есть фактическим значениям), удерживаемым этими двумя переменными, они одинаковы (то есть адрес переменной num), но только значения одинаковы. Но, как говорят другие, они семантически две разные переменные и не могут использоваться взаимозаменяемо.
Возвращаясь к вашему последнему вопросу:
Оказывают ли они оба одинаковые функции? Ответ: Нет, они этого не делают. Рассуждение, они не одного типа. Ваш первый вопрос: любая реальная разница между realPointer и fakePointer. Есть так много различий, и самые основные различия заключаются в следующем:Кроме того, что этот
int fakePointer = #
может привести к одному или нескольким из следующих
Имеются следующие отличия:
*
-/disereference не может быть применен к int
напечатанному fakePointer
.fakePointer++
скорее всего приведет к чему-то другому, чем к realPointer++
. Это относится ко всем другим способам добавления и вычитания любого значения (но 0
). Подробнее читайте в "арифметике указателя" и "арифметике".[]
-/indexing к int
напечатанному fakePointer
.