При попытке понять указатель у меня есть следующая проблема:
В последних двух утверждениях существует любая реальная разница между realPointer
и fakePointer
. Будут ли они оба обеспечивать те же функциональные возможности?
int num = 0;
int *realPointer = #
int fakePointer = #
Ответы
Ответ 1
int fakePointer = #
Это недействительно C, он нарушает правила простого назначения и не компилируется.
Однако, если бы вы сделали int fakePointer = (int)#
, тогда единственное различие заключалось бы в том, что нет никаких гарантий того, что вы можете надежно использовать fakePointer, конверсии из указателей в целые числа определены по реализации и могут также привести к поведению undefined (6.3.2.3):
Любой тип указателя может быть преобразован в целочисленный тип. Кроме того, ранее указанный, результат определяется реализацией. Если результат не может быть представлен в целочисленном типе, поведение undefined. Результат не должен находиться в диапазоне значений любых целочисленный тип.
Чтобы безопасно и переносимо конвертировать между указателями и целыми числами, вы не должны использовать int
, но тип uintptr_t
найден в stdint.h.
Ответ 2
Переменная, объявленная как указатель, семантически отличается от переменной, не объявленной как указатель. Компилятор (и язык) позволит вам делать вещи с указателем, который вы не можете сделать с помощью не указателя. И наоборот.
Самое большое отличие заключается в том, что вы можете разыменовывать указатель, но вы не можете сделать это с помощью не указателя.
Например, используя переменные в вашем коде, мы можем сделать *realPointer = 5
, чтобы сделать num
назначено значение 5
, но выполнение *fakePointer = 5
не допускается и не имеет смысла, так как fakePointer
на самом деле не указатель.
Ответ 3
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
недействительно.
Ответ 4
Если вы переходите к литеральным значениям (то есть фактическим значениям), удерживаемым этими двумя переменными, они одинаковы (то есть адрес переменной num), но только значения одинаковы.
Но, как говорят другие, они семантически две разные переменные и не могут использоваться взаимозаменяемо.
Возвращаясь к вашему последнему вопросу:
Оказывают ли они оба одинаковые функции?
Ответ: Нет, они этого не делают.
Рассуждение, они не одного типа.
Ваш первый вопрос:
любая реальная разница между realPointer и fakePointer.
Есть так много различий, и самые основные различия заключаются в следующем:
- realPointer содержит адрес num и является указателем, поэтому, если вы изменяете значение num (путем изменения с помощью num variable или * realPointer), оно отражается в обоих местах, но это не относится к fakePointer
- вы можете передать realPointer в функции и любые изменения, внесенные в сторону, вызовы функций будут отражены обратно к функции вызываемого абонента.
Ответ 5
Кроме того, что этот
int fakePointer = #
может привести к одному или нескольким из следующих
- undefined, нарушая правила языка C (что, в свою очередь, может привести к "чему-либо" )
- потеря значительных цифр при конверсии
- вообще не компилируется
Имеются следующие отличия:
- Оператор
*
-/disereference не может быть применен к int
напечатанному fakePointer
.
- Выполнение
fakePointer++
скорее всего приведет к чему-то другому, чем к realPointer++
. Это относится ко всем другим способам добавления и вычитания любого значения (но 0
). Подробнее читайте в "арифметике указателя" и "арифметике".
- Невозможно применить оператор
[]
-/indexing к int
напечатанному fakePointer
.