C ++ Передача Структурного Адреса - PullRequest
2 голосов
/ 20 января 2011

Я немного запутался, передавая структуры в функции.Я понимаю указатели и все.

Но например:

struct stuff
{
   int one
   int two 
};

int main{
    stuff fnc;
    fnc.two = 2;
    fnc.one = 1;
    multiply(&fnc);

}

void multiply(const stuff * pm){
    cout << pm->one * pm->two;
}

Прежде всего .... я даже делаю это правильно.И во-вторых, почему мы используем оператор адреса, когда передаем функцию, но используем оператор * указателя в реальном вызове функции?Я в замешательстве?

Ответы [ 9 ]

2 голосов
/ 20 января 2011

Да, ваш код компилируется, кроме пропущенных точек с запятой в определении struct stuff. Я не совсем уверен, что именно вы спрашиваете о передаче функции и фактическом вызове функции, но я думаю, вы задаетесь вопросом, почему вызов функции использует &fnc, а параметр stuff *pm? В этом случае объявленная переменная fnc является простой stuff. Это не указатель, это относится к фактическому экземпляру этой структуры.

Теперь функция multiply объявлена ​​как принимающая stuff* - указатель на stuff. Это означает, что вы не можете передать fnc напрямую - это stuff, а multiply ожидает *stuff. Однако вы можете передать fnc как stuff*, используя оператор &, чтобы получить адрес, а &fnc - это действительный stuff*, который можно передать в multiply.

Когда вы используете функцию multiply, теперь у вас есть stuff*, называемый pm. Чтобы получить переменные one и two из этого stuff*, вы используете указатель на оператор-член (->), поскольку они являются указателями на stuff, а не на простые stuff. После получения этих значений (pm->one и pm->two) код затем умножает их вместе, прежде чем распечатать (pm->one * pm->two).

2 голосов
/ 20 января 2011

Операнды * и & означают разные вещи в зависимости от того, описывают ли они тип или описывают переменную:

int  x;        // x is an integer
int* y = &x;   // y is a pointer that stores the address of x
int& z =  x;   // z is a reference to x
int  a = *y;   // a in an integer whose value is the deference of y

Ваша переменная pm объявлена ​​как указатель, поэтому *Тип 1007 * изменен с *.Ваша переменная fnc используется (а именно для ее адреса), и, таким образом, сама переменная помечается &.

Вы можете представить приведенные выше примеры как следующие (C ++ на самом деле не имеет этихтак что не ищите их):

int x;
pointer<int> y = addressof(x);
reference<int> z = x;
int a = dereference(y);

Это разница между описанием типа и выполнением операции.

1 голос
/ 20 января 2011

In

void multiply(const stuff * pm){
    cout << pm->one * pm->two;
}

stuff * pm говорит, что pm является адресом структуры вещи.

&fnc

говорит "адрес fnc".

Когда переменная объявлена ​​как:

stuff * pm;

, это говорит нам, что pm следует рассматривать как адрес, базовый тип которого stuff.

. И если мы хотим получить адрес переменной stuff fnc, мы должны использовать

& fnc

0 голосов
/ 30 мая 2013

Следующий код расскажет вам о иллюстрации указателя

Адрес структуры передается в функцию с именем multiply, и эта функция выполняет некоторые операции с элементом переданной структурыи сохраните результат в переменной результата.

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

#include <iostream.h>



struct stuff
{
   int one;
   int two ;
   int result;
};
void multiply(stuff *pm);
int main(){
    stuff fnc;
    fnc.two = 2;
    fnc.one = 3;
    fnc.result = 0;
    multiply(&fnc);
    cout<<fnc.result;

return 0;

}

void multiply(stuff *pm)
{
    pm->result = pm->one * pm->two;
}
0 голосов
/ 20 января 2011

У вас есть пара синтаксических ошибок в вашей программе, но кроме этого, основная идея в порядке. Вот синтаксические проблемы, которые я должен был исправить перед компиляцией вашей программы:

#include <iostream>

using namespace std;

struct stuff
{
   int one;
   int two; 
};

void multiply(const stuff * pm) {
    cout << pm->one * pm->two;
}

int main() {
    stuff fnc;
    fnc.two = 2;
    fnc.one = 1;
    multiply(&fnc);

}

Чтобы ответить на ваши вопросы о разнице между оператором '&' (address of) и оператором '*' (разыменование указателя), нам просто нужно подумать о типах, которые вы передаете в функцию.

Возьмите функцию умножения:

void multiply(stuff *fnc) {
...
}

В определении этой функции вы описываете что-то, что принимает указатель на структуру вещи. В этой первой строке вы не говорите, что разыменовываете этот объект, просто ожидаете указатель на объект вещи.

Теперь при вызове умножения:

stuff fnc;
multiply(&fnc);

Вы используете оператор «&» (адрес), чтобы получить указатель на объект. Поскольку функция умножения ожидает указатель, и у вас есть простой старый объект, вам нужно использовать оператор &, чтобы получить указатель для функции умножения.

Возможно, яснее будет назвать это так:

stuff fnc; //The actual object
stuff* fnc_ptr = &fnc; //A pointer to a stuff object, initialized to point at fnc created above
multiply(fnc_ptr); //Call the function with the pointer directly
0 голосов
/ 20 января 2011

Вот рабочий пример того, что вы хотели бы увидеть.

#include <iostream>
using namespace std;
struct stuff
{
   int one;
   int two;
};

void multiply(stuff* pm)
{
    cout << pm->one * pm->two;
}
int main()
{
    stuff* fnc = new stuff;
    fnc->two = 1;
    fnc->one = 2;
    multiply(fnc);
    delete fnc;
    cin.ignore(1000, 10);
    return 0;
}
0 голосов
/ 20 января 2011

Ваш код правильный.В основном вы успешно создаете объект «вещи» и устанавливаете его значения.Затем вы передаете постоянный адрес объекта в функцию умножения.Затем функция умножения использует этот адрес для доступа к двум переменным структуры для вывода умножения переменных.

* in "const stuff * pm" означает, что он принимает постоянный указатель на объект вещи.

0 голосов
/ 20 января 2011

Вам нужен адрес оператора, чтобы вы могли получить адрес объекта, создав указатель, которого ожидает функция. Символ * в списке параметров не является оператором указателя, он просто говорит, что переменная является указателем.

0 голосов
/ 20 января 2011

Конечно, это будет работать, кроме вашего ошибочного определения функции main.

Причина, по которой это работает, заключается в том, что когда вы используете унарный оператор &, он по существу возвращает указатель на операндтак что в вашем случае, fnc, который имеет тип stuff, если вы сделали &fnc, это вернет stuff *.Вот почему функция multiply должна принимать stuff *.

struct stuff
{
   int one, two;
};

int main(int argc, const char* argv[]) {
    stuff fnc;
    fnc.two = 2;
    fnc.one = 1;
    multiply(&fnc); //passes a pointer to fnc
}

void multiply(const stuff * pm){
    //the "*" operator is the multiplication operator, not a pointer dereference
    cout << pm->one * pm->two; //->one is equivalent to (*pm).one
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...