C ++ указатели локальные в функциях - PullRequest
0 голосов
/ 09 июня 2011

Это фрагмент кода, который я создал для целей обучения на C ++, и в настоящее время я пытаюсь учить его сам.Мой вопрос:

Почему *ptr = 30 изменяет выходные значения двух последних операторов cout в моем main?(выход 30, 30, 30).Следовательно, почему int y = 30; и ptr = &y; не изменяют вывод в моей основной и остаются локальными для функции?(если я закомментирую * ptr = 30, а не предыдущие два утверждения, результат будет 30, 5, 5)

Если я изменю ввод функции на void printPointer(int *&fptr) - и закомментирую только *ptr = 30 - тогда изменится *ptr у меня в основной, но не х.Я понимаю это, поскольку передача по ссылке модифицирует указатель, но не то, как мой первый оператор изменяет * ptr и x в моем main.

#include <iostream>

using namespace std;

void printPointer(int *fptr);

int main()
{
    int x = 5;

    int *ptr = &x;

    printPointer(ptr);

    cout << *ptr << endl;
    cout << x << endl;

    return 0;
}

void printPointer(int *fptr)
{

//  int y = 30;             // this does not change the output of the last two couts in main, output = 30, 5, 5
 // fptr = &y;

    *fptr = 30;          // uncommenting this and commenting out the former two statements: output = 30, 30, 30

    cout <<  *fptr << endl;
}

Ответы [ 3 ]

3 голосов
/ 09 июня 2011

*ptr = 30 изменяет значение , на что указывает . В вашем случае вы установили ptr для указания на x (когда вы сделали ptr = &x, а затем передали это в качестве аргумента printPointer()). Таким образом, значение x изменяется.

Когда вы вместо этого делаете int y = 30; fptr = &y;, все, что вы делаете, это изменяете fptr, чтобы указать на другую переменную . Вот и все. Вы не меняете значение того, на что указывает (то есть значение x). И вы не влияете на ptr, потому что fptr - это отдельная локальная переменная. Так что ptr по-прежнему указывает на x, а x по-прежнему 5.

Когда вы изменяете свою функцию так, чтобы указатель брался по ссылке, то при изменении fptr на y также изменяется ptr, поскольку они являются одной и той же переменной.

0 голосов
/ 09 июня 2011

Если я правильно понимаю, вы спрашиваете о двух частях кода. Первое, что вы отправили:

#include <iostream>

using std::cout;

void f(int* fptr) {
    *fptr = 30;  // 11
    cout << "*fptr = " << *fptr << '\n'; // 12
}

int main() {
    int x = 5; // 1
    int* ptr = &x; // 2
    f(ptr); // 21
    cout << "*ptr = " << *ptr << '\n'; // 22
    cout << "x = " << x << '\n'; // 23
}

В этом случае указатель всегда указывает на x, а в функции вы все равно изменяете значение x, так как именно на это указывает fptr. Если это помогает, вот демонстрация значения переменных в конце каждой строки: NE означает, что переменная в настоящее время не существует.

1.  x = 5, ptr = NE, fptr = NE
2.  x = 5, ptr = &x, fptr = NE
11. x = 30, ptr = &x, fptr = &x
12. x = 30, ptr = &x, fptr = &x
21. x = 30, ptr = &x, fptr = NE

После этого значения не изменяются, и все три оператора будут печатать 30.

Второй:

#include <iostream>

using std::cout;

void f(int*& fptr) {
    int y = 30; // 11
    fptr = &y; // 12
    cout << "*fptr = " << *fptr << '\n'; // 13
}

int main() {
    int x = 5; // 1
    int* ptr = &x; // 2
    f(ptr); // 21
    cout << "*ptr = " << *ptr << '\n'; // 22
    cout << "x = " << x << '\n'; // 23
}

В первом случае указатель передается по ссылке и указывает на y. Фактически, в этом случае строка 21 включает неопределенное поведение, так как y больше не существует. Опять же, построчный анализ:

1.  x = 5, y = NE, ptr = NE, fptr == NE
2.  x = 5, y = NE, ptr = &x, fptr == NE
11. x = 5, y = 30, ptr = &x, fptr == ptr
12. x = 5, y = 30, ptr = &y, fptr == ptr
13. x = 5, y = 30, ptr = &y, fptr == ptr
21. x = 5, y = NE, ptr = &y, fptr == NE

Значения снова не меняются после этого: однако в строке 22 вы пытаетесь взять адрес ptr. Как видите, *ptr = y = NE, а значит и поведение не определено. Выход может быть любым.

(Еще одно замечание: вам следует избегать using namespace std;, так как это может вызвать конфликт имен; используйте using std::cout; и аналогичные, как в приведенном выше коде.)

0 голосов
/ 09 июня 2011

*fptr = 30 разыменовывает адрес, сохраненный в fptr, и записывает 30 в позицию в памяти.этот адрес в памяти вы дали функции с printPointer(ptr).ptr в этом случае был адрес x, который вы присвоили ptr с помощью ptr = &x.

int y= y объявляет переменную, локальную для функции.fptr = &y назначает адрес y для fptr (и перезаписывает значение из ptr).поэтому последняя строка в этом случае изменит локальную переменную y вместо x.

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