2015-07-29 2 views
-2

Итак, я следую «Let Us C» книга, и у них есть пример для указателей, вы можете объяснить, почему значение i и j изменения значений в этом сценарии ?:Почему в этом сценарии изменяется адрес указателя var?

main() 
{ 

    int i = 3, *j, **k ; 
    j = &i ; 
    k = &j ; 

    printf ("\nAddress of i = %u", *k) ; 
    printf ("\nAddress of j = %u", &j) ; 

} 

Выходной

Адрес г = 65524
Адрес J = 65522

Я понимаю, в C, что новые объявления переменных, например int i =3; int k=5, назначаются разными ячейками памяти с помощью C, но, похоже, не склоняет голову, почему это выводит разные значения?

+6

Оффтопическое предложение: «Давайте C» - это хлам, не читающий его. Выберите хорошую книгу на C. Также используйте 'int main (void)' вместо 'main()' и 'return 0;' –

+0

Почему downvote? Я задаю вопрос ... И просто не говори «используйте новую книгу», рекомендую один. – Jshee

+3

'i' и' j' действительно разные переменные, поэтому они имеют разные адреса, как вы упоминаете. В чем проблема ? – Quentin

ответ

0

Когда ваша программа запускается, ядро ​​ОС решает, основываясь на многих критериях, куда поместить вашу программу и как ее отобразить в память.

Итак, когда вы запускаете его несколько раз подряд, ячейка памяти может изменяться или не изменяться.

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

+1

Я не думаю, что это отвечает на вопрос ... –

+0

Где вы видите абсолютные ячейки памяти в коде? – dhke

+0

О, может быть, я понял: «Почему он выводит разные значения каждый раз, когда я начинаю?». Не беспокойся в таком случае. – blue112

1

Пункт 1: использовать %p, чтобы распечатать адрес. Кроме того, отлитый соответствующий аргумент (void *)

пункта 2:*k (типа int *) и &j (тип int **) являются две разные вещи. Может быть, вы хотели напечатать либо из

  • k и &j (оба int **)
  • *k и j (оба int *)
+0

Любые рекомендации по книгам/учебным пособиям, чтобы лучше понять указатели ... супер новый для C – Jshee

+1

@ user700070 Конечно. См. [Это] (http://stackoverflow.com/q/562303/2173917) –

+0

Большое спасибо! – Jshee

4

Вы ожидаете *k (То же, что адрес i) и &j (адрес j). Они различного типа int * v/s int ** и разные значения.

Никогда не используйте %u печатать адреса, а использовать:

printf ("\nAddress of i = %p", (void *)*k) ; 

С другой стороны, если сравнивать &j и k, те должны быть одинаковыми.

Например:

printf ("%p v/s %p\n", (void *)&j, (void *)k); 
2

Потому что вы печатаете указатель K в первом printf заявлении, а не фактическое значение k. k имеет значение j, поэтому, если вы хотите, чтобы оба оператора были равными, просто напечатайте k.

0

при запуске программы, каждая переменная получает место в памяти:

int i = 3, *j, **k ; 

в вашем случае, мы знаем, что эти Адреса, телефоны получили решили:

address of (int i) = 65524 
address of (int* j) = 65522 
address of (int** k) = unknown 

оператор & получает адрес из переменная, поэтому вы получаете результат, который вы наблюдаете.

0

Учитывая код

int i = 3, *j, **k ; 
j = &i ; 
k = &j ; 

тогда следующие условия:

**k == *j == i == 3 
*k == j == &i 
    k == &j 

То есть, выражения **k, *j и i все имеют тип int и оценить, 3 выражения *k , j и &i все имеют тип int * и оценивают по адресу i , а выражения k и &j имеют тип int ** и оцениваются по адресу j.

Так,

printf("value of i = %d\n", i); 
printf("value of i (through j) = %d\n", *j); 
printf("value of i (through k) = %d\n", **k); 

printf("address of i = %p\n", (void *) &i); 
printf("address of i (through j) = %p\n", (void *) j); 
printf("address of i (through k) = %p\n", (void *) *k); 

printf("address of j = %p\n", (void *) &j); 
printf("address of j (through k) = %p\n", k); 

printf("address of k = %p\n", (void *) &k); 

Используйте спецификатор %p преобразования для печати значений указателей. Он ожидает void * в качестве соответствующего аргумента, и это одно из немногих мест (возможно, единственное место) на C, где вам нужно явно указать значение указателя на void *.

1
printf ("\nAddress of i = %u", *k); 

Здесь * k печатает значение, сохраненное в j, а не адрес j.

Чтобы получить адрес j, вам нужно распечатать k без его удаления.

Предположим, что ваши переменные хранятся в следующем местоположении. Примечание: Адреса являются лишь предположением. enter image description here

Теперь * K означает разыменовываются значение, сохраненное при к (то есть) значение, хранящееся в ячейке памяти 200.

значение, которое хранится в 200 100, который является адресом I, не адрес J ,

Смежные вопросы