Путаница с указателями - PullRequest
       1

Путаница с указателями

3 голосов
/ 22 сентября 2011

Я пытаюсь выучить C. Чтение, которое я делал, объясняет указатели как таковые:

/* declare */
int *i;

/* assign */
i = &something;

/* or assign like this */
*i = 5;

Что я понимаю под i = адрес вещи, хранящейся в something

Или

Поместите 5 или внутреннее представление 5 в адрес, на который указывает * i.

Однако на практике я вижу:

i = 5;

Разве это не должно вызывать несоответствие типов?

Редактировать: Полуколоны. Рубиновые привычки ..

Ответы [ 6 ]

3 голосов
/ 22 сентября 2011

Хорошо, да, в вашем примере установка указателя int на 5 - это несоответствие типов, но это C, так что ничто не мешает вам. Это, вероятно, приведет к неисправностям. Некоторые настоящие хакеры могут ожидать получения соответствующих данных по абсолютному адресу 5, но вы никогда не должны этого делать.

Английские эквиваленты:

i = &something

Назначьте i равным адресу чего-либо

*i =5

Назначьте то, на что я указываю, 5.

2 голосов
/ 23 сентября 2011

Если вы видите что-то вроде

int *i;
...
i = 5;

тогда кто-то пытается присвоить адрес 0x00000005 i. Это разрешено , хотя и несколько опасно ( N1256 ):

6.3.2.3 Указатели
...
3 Целочисленное константное выражение со значением 0 или такое выражение, приведенное к типу void *, называется константой нулевого указателя . 55) Если константа нулевого указателя преобразуется в Тип указателя, результирующий указатель, называемый нулевой указатель , гарантированно сравнивается с неравным указателем на любой объект или функцию.
...
5 Целое число может быть преобразовано в любой тип указателя. За исключением случаев, указанных ранее, результат определяется реализацией, может быть неправильно выровнен, может не указывать на объект ссылочного типа и может быть представлением прерываний. 56)
...
55) Макрос NULL определен в <stddef.h> (и других заголовках) как константа нулевого указателя; см. 7.17.

56) Функции отображения для преобразования указателя в целое число или целое число в указатель предназначены для согласования со структурой адресации среды выполнения.

В зависимости от архитектуры и среды, в которой вы работаете, 0x00000005 может быть недопустимым целочисленным адресом (большинство знакомых мне архитектур требуют, чтобы многобайтовые типы начинались с четных адресов), и такой низкий адрес может не совпадать напрямую доступны для вашего кода (я не делаю встроенную работу, так что возьмите это с крошкой соли).

2 голосов
/ 23 сентября 2011

Если вы установите i = 5, как написали в своем вопросе, i будет содержать адрес 0x00000005, который, вероятно, указывает на мусор.

Надеюсь, это поможет объяснить:

int *i;           /* declare 'i' as a pointer to an integer */
int something;    /* declare an integer, and set it to 42 */
something = 42;   
i = &something;   /* now this contains the address of 'something' */
*i = 5;           /* change the value, of the int that 'i' points to, to 5 */
                  /* Oh, and 'something' now contains 5 rather than 42 */ 
1 голос
/ 22 сентября 2011

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

удачи в изучении c.

1 голос
/ 22 сентября 2011

Надеюсь, это поможет.

Это объявляет имя переменной «myIntPointer», которая имеет тип «указатель на int».

int *myIntPointer;

Это принимает адрес переменной int с именем"blammy" и сохраняет его в указателе int с именем "myIntPointer".

int blammy;
int *myIntPointer;

myIntPointer = &blammy;

Это принимает целочисленное значение 5 и сохраняет его в пространстве памяти, к которому обращается переменная int с именем "blammy", присваивая значение через указатель int с именем "myIntPointer".

int blammy;
int *myIntPointer;

myIntPointer = &blammy;

*myIntPointer = 5;

Устанавливает указатель int с именем myIntPointer, указывающий на адрес памяти 5.

int *myIntPointer;

myIntPointer = 5;
1 голос
/ 22 сентября 2011

Я понимаю, что я имею в виду i = адрес вещи, хранящейся в чем-то

На самом деле я содержит адрес, который ДОЛЖЕН быть адресом переменной, содержащей int.Я сказал "должен", потому что вы не можете быть уверены в этом в C:

char x;
int *i;
i = (int *)&x;

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

int *i;
i = 5;
*i; //undefined behavior..probably segfault

вот несколько примеров:

int var;
int *ptr_to_var;

var = 5;
ptr_to_var = var;

printf("var %d ptr_to_var %d\n", var, *ptr_to_var); //both print 5
printf("value of ptr_to_var %p must be equal to pointed variable var %p \n" , ptr_to_var, &var);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...