Разыменование члена struct Struct_type с помощью (* variable) .member vs * variable.member - PullRequest
0 голосов
/ 07 октября 2019

Дано:

typedef struct Person_struct { char name[10]; int age; } Person;
Person bob;

void makePerson(Person *human) { 
   strcpy((*human).name, "Bob Bee");
   (*human).age = 36;
}

Разыменование затем принимает общую форму:

(*variable).member //variable could be bob, member could be age

Я знаю, что оператор доступа к элементу . имеет приоритет над *, поэтому мы используем скобкисначала разыменовать переменную. Я действительно не понимаю, почему это необходимо.

На самом деле кажется более интуитивным, что *variable.member сначала будет работать с оператором доступа к элементу, чтобы получить указатель на struct_type, а затем .member добавит sizeof(member) чтобы получить локацию, которую нужно защитить.

Но правильная форма (*variable).member очень неинтуитивна. Неясно, какое «значение» на самом деле возвращается (*variable), и неясно, как будет получен доступ к члену из того, что возвращается.

Мой вопрос:

Что происходитв памяти, когда используется (*variable).member, а не *variable.member?

Я видел это , но он не ответил на мой вопрос.

Ответы [ 3 ]

0 голосов
/ 07 октября 2019

Я знаю, что оператор доступа к элементу . имеет приоритет над *, поэтому мы используем скобки для разыменования переменной в первую очередь. Я не очень понимаю, почему это необходимо.

Вы только что сказали: оператор доступа к элементу . имеет приоритет над оператором разыменования *. Если вы спрашиваете , почему . имеет приоритет , это просто выбор дизайна.

правильная форма (* переменная) .member очень не интуитивно

Я бы сказал, что это скорее раздражает, чем не интуитивно. На самом деле, это настолько распространенная операция, что для нее есть оператор. Вы можете использовать оператор -> для доступа к полям структуры, когда у вас есть указатель на нее.

human->age = 36
// same as
(*human).age = 36

Что происходит в памяти, когда используется (*variable).member вместо *variable.member?

Выполнение (*variable).member - это то же самое, что сказать "взять адрес внутри variable и разыменовать его, затем взять поле member структуры, которую вы только что получили".

Выполнение *variable.member - это то же самое, что сказать «взять адрес внутри поля member структуры variable, а затем разыменовать его». Если variable - указатель, это, конечно, просто неправильно.

0 голосов
/ 07 октября 2019

Хороший вопрос!

Многое зависит от того, как ваш компилятор обрабатывает значение символа.

Например, в C ++ оператор (*variable).member,(*variable) можно интерпретировать как reference для фактического объекта.

Person bob;
Person* ptr = &bob;

Person& ref = *ptr;

Ссылка может использоваться в качестве фактического объекта в его контексте.

Но в перспективекомпилятор, (*variable) имеет значение только в immediate step в процессе компиляции.

На последнем шаге (двоичном), (*variable) теряет свое значение.

Осталось только(*variable).member интерпретируется как variable->member. Это означает, что взять указатель variable, разыменовать его, используя тип Person, получить фактический атрибут из прототипа Person struct.

Пример:

struct Person {
    char* name;
    int age;
};
Person bob;
printf("%d\n", bob.age);

Возможнодвоичный код может быть

1. advance stack pointer about `sizeof(Person) = 16 bytes` (determined at compile time for 64bit machine). Top of the stack now contains the value of object bob
2. put the last 8 bytes on top of the stack into `printf` function. (You are gonna learnt more about this later)

Надеюсь, это поможет

0 голосов
/ 07 октября 2019

Причина, по которой вы не можете использовать *variable.member, заключается в том, что переменная в этом случае является указателем, а не структурой, и вы не можете использовать оператор доступа к элементу в указателе. У нас есть отдельный оператор -> для доступа к элементу по разыменованному указателю:

strcpy(human->name, "Bob Bee");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...