2015-02-17 2 views
2
void double_trouble(int *p, int y); 
void trouble(int *x, int *y); 

int 
main(void) 
{ 
    int x, y; 
    trouble(&x, &y); 
    printf("x = %d, y = %d\n", x, y); 
    return (0); 
} 

void 
double_trouble(int *p, int y) 
{ 
    int x; 
    x = 10; 
    *p = 2 * x - y; 
} 

void 
trouble(int *x, int *y) 
{ 
    double_trouble(x, 7); 
    double_trouble(y, *x); 
} 

Для приведенного выше кода, я знаю выход x и y должны быть 13 и 7. Однако я немного запутался, что, поскольку это в пустоту, почему бы значение все еще сохраняется в x и y? Другими словами, так какуказатель и указатель осветление

double_trouble(x, 7); 

называется, почему значение x еще 13? Я имею в виду, что это пустое, сохраненное значение будет удалено, не так ли?

Если мой вопрос не очень понятно, пожалуйста, объясните немного вызова функции в

void trouble(int *, int *) 
+1

[Каковы препятствия для понимания указателей и что можно сделать для их преодоления?] (Http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and- что может быть сделано для преодоления) –

+0

Значение x в функции проблемы не равно 13. Значение x - это некоторый адрес памяти, который содержит целое число со значением 13. Это целое число также называется именем x в основном. Это плохая идея. Его следует называть xp или что-то в этом неприятности. –

ответ

2

Здесь происходит некоторая путаница имен. Как только вы проложите себе путь, вы увидите, что все работает точно так, как должно.

Я имею в виду, что это void, сохраненное значение будет удалено, не так ли?

Есть три целочисленных переменных в игре здесь: x и y из main и x из double_trouble. Чтобы отличить их, я буду ссылаться на первые два как m::x и m::y, в то время как последний будет dt::x.

Ваш trouble функция передает указатели на m::x и m::y к double_trouble как указатель p. В первом вызове, p относится к m::x, так что присваивание

*p = 2 * x - y; 

означает то же самое, как

m::x = 2 * dt::x - 7; 

с 7 приходит в качестве параметра double_trouble. Поскольку dt::x был назначен 10 раньше, это станет присвоением m::x = 20 - 7 или просто m::x = 13.

Во втором вызове, y передается значение m::x и p точки к m::y, поэтому такое же выражение соответствует этому:

m::y = 2 * dt::x - m:x; 

, который является таким же, как m::y = 20 - 13 или m::y = 7.

+0

Thx @dasblinkenlight, теперь ясно. Еще один вопрос, поэтому, когда мы вызываем функцию void, будет сохранен только адрес указателя, и он не будет удален? Я довольно уверен, прежде чем я узнаю указатели, как только функция void вызывается, значение, хранящееся в функции void, будет удалено. – Yolo

+0

@Wii Когда вы вызываете функцию void, любая ее модификация останется «невидимой» для внешних функций, если только они не будут сделаны с помощью указателей. Модификация, выполняемая локальной переменной или параметром, включая изменения самих указателей, игнорируется в вызывающем: значения выходят за пределы области видимости и становятся недоступными (это не совсем правильно назвать это «удаление», хотя ничего не сделано к самому значению). – dasblinkenlight

1

p указывает на x от основной, поэтому писать что-то *p также изменяет x в основном.

Вот как работает указатель и не имеет ничего общего с возвращаемым значением функции.

вашего trouble(&x, &y); вызова переходит к функции trouble и присваивает адрес x от основных до x в беде (x в пунктах проблем с x в основном). То же самое происходит с y. Итак, первый звонок double_trouble выглядит как double_trouble(<the address of x from main>, 7); So p указывает на x от основного и так *p =... изменений x от основного.

Было бы легче объяснить и понять, имеют ли переменные разные имена.

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