Указатель в C, не понимаю, как они получили этот результат - PullRequest
3 голосов
/ 11 октября 2010

вот фрагмент кода

void F (int a, int *b)
{
 a = 7 ;
 *b = a ;
 b = &a ;
 *b = 4 ;
 printf("%d, %d\n", a, *b) ;
}
int main()
{
 int m = 3, n = 5;
 F(m, &n) ;
 printf("%d, %d\n", m, n) ;
 return 0;
}

ответ

4 4 
3 7

Я вижу, как 4 4 был вычислен, я не понимаю, как они получили 3 7 (я понимаю, как вычисляется 3, он не изменяется, поскольку он не был передан по ссылке)

Спасибо!

Ответы [ 4 ]

7 голосов
/ 11 октября 2010

Я аннотировал функцию F комментариями, чтобы объяснить, что происходит:

a = 7 ;  // a is now 7
*b = a ; // b points to n, so n is now 7
b = &a ; // b now points to a and no longer to n
*b = 4 ; // a is now 4. n is unaffected
4 голосов
/ 11 октября 2010

В начале main мы имеем

m=3   n=5  // int m = 3, n = 5;

затем мы вызываем F(m, &n), передавая m по значению и n по указателю такой, что

m = 3   n = 5
a = 3   b->n   // F(m, &n);

Теперь внутри F() мы присваиваем 7 a:

m = 3   n = 5
a = 7   b->n     // a = 7

затем мы присваиваем a (= 7) адресу памяти, указанному b (-> n)

m = 3   n = 7
a = 7   b->n     // *b = a;

затем мы изменим b, так что теперь b указывает на a:

m = 3   n = 7
a = 7   b->a     // b = &a;

и затем мы присваиваем 4 адресу памяти, указанному b (-> a)

m = 3   n = 7
a = 4   b->a     // *b = 4;

печать a (= 4) и *b (-> a = 4)

и печать m (= 3) и n (= 7) вне функции

1 голос
/ 11 октября 2010

Довольно тонкий действительно. :)

В F происходит много глупостей: какое бы значение не передавалось через a, оно отбрасывается, и вместо него ему присваивается 7. Затем значение a (равное 7) присваивается переменной, на которую указывает b (то есть n, поэтому здесь n становится 7).

На следующей строке объект, на который указывает b, изменяется, так что b теперь указывает на локальный параметр a, а на следующей строке объект указывает на b (=> a) установлен на 4.

Таким образом, теперь у нас есть a, то есть 4, b, который указывает на a (=> так *b==4, так как *b==a), m по-прежнему 3 (было передано по значению таким образом, он не мог быть изменен с помощью F), а n был установлен на 7.

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

1 голос
/ 11 октября 2010

Внимательно посмотрите на эту строку

b = &a ;
*b = 4 ;

b получает ссылку a (это адрес памяти).Теперь, когда вы обращаетесь к * b, он указывает на память переменной a, а не на n

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...