С++ Передача указателя на функцию (Howto) + С++ Pointer Manipulation
Я немного запутался относительно того, как работают указатели прокрутки.
Скажем, у меня есть следующая функция и указатель, и...
ИЗМЕНИТЬ:
... Я хочу использовать указатель на какой-либо объект в качестве аргумента в функции.
то есть:.
void Fun(int Pointer){
int Fun_Ptr = ---Passed Pointer---;
//So that Fun_Ptr points to whatever ---Passed Pointer points to
Между обозначениями * Pointer и & Pointer, я очень смущен. Я знаю, что * Указатель означает дать то, на что он указывает.
Я помещаю void (int * pointer) в объявление. Что делать, когда я использую функцию?
Ваша помощь приветствуется.
ИЗМЕНИТЬ 2:
Хорошо, теперь я понимаю, что использование переменной * в объявлении означает, что будет передан указатель. Однако, как насчет того, когда я использую эту функцию?
то есть.
int main(){
int foo;
int *bar;
bar = foo;
Fun(bar);
}
ИЗМЕНИТЬ 3:
Ладно, так исправьте меня, если я ошибаюсь:
В соответствии с соглашениями приведенного выше кода:
bar = & foo означает: Сделать точку бара в foo в памяти
* bar = foo означает изменение значения, которое балл указывает на равное значение foo равно
Если у меня есть второй указатель (int * oof), то:
bar = oof означает: bar указывает на указатель oof
bar = * oof означает: bar указывает на значение, которое указывает на точки, но не на собственный указатель
* bar = * oof означает: изменить значение, которое указывает бар, на значение, которое указывает на
& bar = & oof означает: изменить адрес памяти, который указывает на бар, таким же, как адрес памяти, который указывает на
Есть ли у меня это право?
EDIT 4: Большое спасибо за вашу помощь (я бы хотел принять более одного ответа, но мне нужно пойти с первым. Я не знаю, как работает wiki сообщества, но я оставлю это этот способ для редактирования (не стесняйтесь превращать его в справочник, если хотите).
Ответы
Ответ 1
Существует разница в использовании *, когда вы определяете переменную и когда вы ее используете.
В объявлении
int *myVariable;
Обозначает указатель на целочисленный тип данных. Однако в использовании
*myVariable = 3;
Обозначает указатель и делает структуру, указывающую на равную три, а затем делает указатель равным адресу памяти 0x 0003.
Итак, в вашей функции вы хотите сделать это:
void makePointerEqualSomething(int* pInteger)
{
*pInteger = 7;
}
В объявлении функции * означает, что вы передаете указатель, но в его фактическом теле кода * означает, что вы получаете доступ к тому, на что указывает указатель.
В попытке отбросить любую путаницу, которую у вас есть, я кратко перейду в амперсанд (&)
& означает получить адрес чего-то, его точное местоположение в памяти компьютеров, поэтому
int & myVariable;
В объявлении подразумевается адрес целого числа или указатель!
Это однако
int someData;
pInteger = &someData;
Средство делает сам указатель pInteger (помните, указатели - это только адреса памяти того, на что они указывают), равный адресу 'someData' - теперь pInteger укажет на некоторые данные и может быть использован для доступа к нему, когда вы уважайте его:
*pInteger += 9000;
Разве это имеет смысл для вас? Есть ли что-то еще, что вы считаете непонятным?
@Edit3:
Почти правильно, за исключением трех утверждений
bar = *oof;
означает, что указатель штриха равен целому числу, а не тому, что указывает на бар, что является недопустимым.
&bar = &oof;
Амперсанд подобен функции, как только он возвращает адрес памяти, который вы не можете изменить, откуда он пришел. Также как этот код:
returnThisInt("72") = 86;
Недопустимо, так же как и ваш.
Наконец,
bar = oof
Не означает, что "bar указывает на указатель oof". Это означает, что бар указывает на адрес, на который указывает точка, поэтому барин указывает на то, что указывает foo, а не на бары на foo, что указывает на oof.
Ответ 2
Чтобы объявить функцию, которая принимает указатель на int:
void Foo(int *x);
Чтобы использовать эту функцию:
int x = 4;
int *x_ptr = &x;
Foo(x_ptr);
Foo(&x);
Если вы хотите указатель на другой тип объекта, то он будет таким же:
void Foo(Object *o);
Но вы можете использовать ссылки. Они несколько менее запутанны, чем указатели:
// pass a reference
void Foo(int &x)
{
x = 2;
}
//pass a pointer
void Foo_p(int *p)
{
*x = 9;
}
// pass by value
void Bar(int x)
{
x = 7;
}
int x = 4;
Foo(x); // x now equals 2.
Foo_p(&x); // x now equals 9.
Bar(x); // x still equals 9.
С помощью ссылок вы все равно можете изменить x, который был передан функции (как и с указателем), но вам не нужно беспокоиться о разыменовании или адресе операций.
Как рекомендовано другими, посмотрите С++ FAQLite. Это отличный ресурс для этого.
Отредактируйте 3 ответа:
bar = & foo означает: Сделать точку бара в foo в памяти
Да.
* bar = foo означает изменение значения, которое балл указывает на равное значение foo равно
Да.
Если у меня есть второй указатель (int * oof), то:
bar = oof означает: bar указывает на указатель oof
bar будет указывать на любые точки. Они оба указывают на одно и то же.
bar = * oof означает: bar указывает на значение, которое указывает на точки, но не на собственный указатель
Нет. Вы не можете сделать это (предполагая, что bar имеет тип int *). Вы можете создавать указатели указателей. (int **), но не вдаваться в это... Вы не можете назначить указатель на int (ну, вы можете, но та деталь, которая не соответствует обсуждению).
* bar = * oof означает: изменить значение, которое указывает бар, на значение, которое указывает на
Да.
& bar = & oof означает: изменить адрес памяти, который указывает на бар, таким же, как адрес памяти, который указывает на
Нет. Вы не можете этого сделать, потому что адрес оператора возвращает rvalue. В принципе, это означает, что вы не можете присвоить ему что-то.
Ответ 3
Чтобы передать указатель на int, он должен быть void Fun(int* pointer)
.
Передача ссылки на int будет выглядеть так:
void Fun(int& ref) {
ref = 10;
}
int main() {
int test = 5;
cout << test << endl; // prints 5
Fun(test);
cout << test << endl; // prints 10 because Fun modified the value
return 1;
}
Ответ 4
Если вы хотите передать указатель в int в свою функцию,
Объявление функции (если вам это нужно):
void Fun(int *ptr);
Определение функции:
void Fun(int *ptr) {
int *other_pointer = ptr; // other_pointer points to the same thing as ptr
*other_ptr = 3; // manipulate the thing they both point to
}
Использование функции:
int main() {
int x = 2;
printf("%d\n", x);
Fun(&x);
printf("%d\n", x);
}
Обратите внимание на общее правило, что переменные с именем Ptr
или Pointer
никогда не должны иметь тип int
, который у вас есть в вашем коде. Указатель-на-int имеет тип int *
.
Если у меня есть второй указатель (int * oof), то:
bar = oof означает: bar указывает на oof указатель
Это означает, что "make bar указывает на то же самое, что указывает на точки".
bar = * oof означает: bar указывает на значение, которое указывает, но не сам указатель o
Это ничего не значит, это недействительно. bar
является указателем *oof
является int. Вы не можете назначить его другому.
* bar = * oof означает: измените значение, которое указывает бар, на значение, которое оо указывает на
Да.
& bar = & oof означает: изменение памяти адрес, который указывает, что тот же как адрес памяти, в котором указаны точки к
Нет, это неверно. &bar
является указателем на переменную bar
, но это то, что называется "rvalue" или "временным", и ему нельзя назначить. Это похоже на результат арифметического вычисления. Вы не можете написать x + 1 = 5
.
Это может помочь вам подумать о указателях как адресах. bar = oof
означает "make bar, который является адресом, равным oof, который также является адресом". bar = &foo
означает "make bar, который является адресом, равным адресу foo". Если bar = *oof
означало что-либо, это означало бы "make bar, который является адресом, равным *oof
, который является int". Вы не можете.
Тогда &
является адресом-оператора. Это означает "адрес операнда", поэтому &foo
является адресом foo (т.е. Указателем на foo). *
- это оператор разыменования. Это означает "вещь по адресу, заданному операндом". Итак, выполнив bar = &foo
, *bar
foo
.
Ответ 5
void Fun(int *Pointer)
{
//if you want to manipulate the content of the pointer:
*Pointer=10;
//Here we are changing the contents of Pointer to 10
}
* перед указателем означает содержимое указателя (кроме объявлений!)
& перед указателем (или любой переменной) означает адрес
EDIT:
int someint=15;
//to call the function
Fun(&someint);
//or we can also do
int *ptr;
ptr=&someint;
Fun(ptr);
Ответ 6
void Fun(int* Pointer) -- would be called as Fun( &somevariable )
позволит вам манипулировать содержимым, на которое указывает "Указатель", разыменовывая его внутри функции "Fun", т.е.
*Pointer = 1;
Объявление его, как указано выше, также позволяет вам манипулировать данными за пределами того, на что оно указывает:
int foo[10] = {0};
Fun(foo);
в функции, которую вы можете затем сделать как * (Указатель + 1) = 12; установив значение 2-го массива.
void Fun(int& Pointer) -- would be called Fun( somevariable )
вы можете изменить ссылку на указатель, но в этом случае вы не можете получить доступ к чему-либо, кроме ссылки на указатель.
Ответ 7
Вам может быть проще понять, используя Functionoids, которые являются более аккуратными и более мощными в использовании, см. этот отличный и рекомендуемый С++ FAQ lite, в частности, смотрите раздел 33.12 и далее, но, тем не менее, прочитайте его с самого начала этого раздела, чтобы понять и понять его.
Чтобы ответить на ваш вопрос:
typedef void (*foobar)() fubarfn;
void Fun(fubarfn& baz){
fubarfn = baz;
baz();
}
Edit:
-
&
означает ссылочный адрес
-
*
означает значение того, что содержится в ссылочном адресе, называемом де-ссылкой
Итак, используя приведенный ниже пример ссылки, мы показываем, что мы передаем параметр и непосредственно изменяем его.
void FunByRef(int& iPtr){
iPtr = 2;
}
int main(void){
// ...
int n;
FunByRef(n);
cout << n << endl; // n will have value of 2
}