Здравствуйте!При вызове функции funcx(int *ptr_xxx) в нее передаю указатель, нужно знать точно при этом действии функция получает именно адрес внешнего указателя и создает еще один, правда локальный указатель внутри себя, или же локальный указатель с тем же адресом не создается, а расширяется область видимости внешнего?
Интуитивно думал, что будет расширятся область видимости внешнего указателя, чтобы не тратить время на создание нового локального, но тесты показали, что дополнительный указатель создается и минус при этом, что нельзя внутри функции присвоить новый адрес локальному указателю и чтобы при этом внешний указатель принял новый адрес...
Пример:
==============
#include <iostream>
void funcx(int *ptr_xxx) {
std::cout << "2: " << ptr_xxx << "!\n";
ptr_xxx = new int;
std::cout << "3: " << ptr_xxx << "!\n";
}
int main() {
int* ptr_int;
std::cout << "1: " << ptr_int << "!\n";
funcx(ptr_int);
std::cout << "4: " << ptr_int << "!\n";
return 0;
}
==============
После выполнения:
1: 0x1! (в мейн)
2: 0x1! (внутри функции получили адресс)
3: 0x804d030! (в нутри функции новый адрес)
4: 0x1! (опять в мейн)---------
конкретно этот пример можно решить и вернуть указатель через int* funcx(); но как быть если одна функция меняет адреса наподобие примера нескольким указателям funcx(int *ptr_xxx, int *ptr_yyy ). новые адреса для ptr_xxx и ptr_yyy одновременно не вернешь...Спасибо заранее за пояснения!
Для этих целей есть указатель на указатель:int **ptr_ptr_xxx
То есть, в Вашем случае будет что-то вроде:
#include <iostream>
void funcx(int **ptr_ptr_xxx) {
std::cout << "2: " << *ptr_ptr_xxx << "!\n";
*ptr_ptr_xxx = new int;
std::cout << "3: " << *ptr_ptr_xxx << "!\n";
}int main() {
int* ptr_int = NULL;
std::cout << "1: " << ptr_int << "!\n";
funcx(&ptr_int);
std::cout << "4: " << ptr_int << "!\n";
return 0;
}
>Для этих целей есть указатель на указатель:
>
>int **ptr_ptr_xxx
>
>То есть, в Вашем случае будет что-то вроде:Спасибо за ответ и спасибо, что именно с примером. То что нужно. Думал про указатель на указатель, когда специально, прежде чем написать здесь, искал ответ в книге Страуструпа. Видел там указатель на указатель без примера, попробовал, но не получилось использовать. По Вашему примеру все вышло, сейчас попытаюсь найти описание логики работы с ними(что именно делают), чтобы применять не путаясь в программе.
>Интуитивно думал, что будет расширятся область видимости внешнего указателя, чтобы не тратить
>время на создание нового локального, но тесты показали, что дополнительный указатель
>создается и минус при этом, что нельзя внутри функции присвоить новый
>адрес локальному указателю и чтобы при этом внешний указатель принял новый
>адрес...Надо было внимательнее читать книги по С (для прокачки скила интуиция :) ), в них во всех ясно говориться что создается копия аргумента и в этом плане указатель ни чем не отличается от просто переменной, т.е. для него точно также создается копия. А значит надо использовать указатель на этот указатель (**ptr). (как бы коммент к посту jd2) :)
PS для C++ есть кроме указателей еще и ссылки, ссылка это просто второе имя для переменной, соответственно можно использовать в данном случае ссылку на указатель в качестве аргумента.
>Надо было внимательнее читать книги по С (для прокачки скила интуиция :)
>), в них во всех ясно говориться что создается копия аргументаДа, про копию знаю, если речь о переменных, в первом своем после про это писал. Просто думал в случае с указателем прозрачно все без копирования. Теперь все ясно.
>PS для C++ есть кроме указателей еще и ссылки, ссылка это просто
>второе имя для переменной, соответственно можно использовать в данном случае ссылку
>на указатель в качестве аргумента.ссылки знаю, конечно, теперь буду знать про ссылки на указатели :) вижу теперь, что вещи очевидные, но до этого о указателе, как о переменной с адресом просто не думал видимо в силу того, что недавно начал си++ изучать и таких ситуаций еще не встречал в процессе.
Еще раз всем спасибо за ответы!
>PS для C++ есть кроме указателей еще и ссылки, ссылка это просто
>второе имя для переменной, соответственно можно использовать в данном случае ссылку
>на указатель в качестве аргумента.попробовал, чтобы знать на будущее - вариант со ссылкой не проходит, возможно не так что-то делаю, с указателем на указатель работает.
#include <iostream>
void funcx(int &xxx)
{
std::cout << "2: " << &xxx << "!\n";
&xxx = new int;
std::cout << "3: " << &xxx << "!\n";
}
int main()
{
int* ptr_int;
std::cout << "1: " << ptr_int << "!\n";
funcx( *ptr_int );
std::cout << "4: " << ptr_int << "!\n";
}test.cpp: In function `void funcx(int&)':
test.cpp:13(&xxx = new int;): error: ISO C++ forbids cast to non-reference type used as lvalue
>попробовал, чтобы знать на будущее - вариант со ссылкой не проходит, возможно
>не так что-то делаю, с указателем на указатель работает.
#include <iostream>void f(int *&p) // ссылка на указатель
{
p = new int(5); //создаем объект int и возвращаем указатель на него
}int main()
{
int *i = NULL;std::cout << i << std::endl;
f(i);
std::cout << i << " " << *i << std::endl;
delete i;return 0;
}