Cпрограммирование: непонимание ссылки указателя на элемент структуры int и вложенной структуры (также целых чисел)

#c #pointers #struct

#c #указатели #struct

Вопрос:

Это примерный вопрос экзамена CLA института cpp

Вопрос в том, каков результат следующего кода? правильный ответ «8», и я получаю именно этот результат, но я не понимаю почему.

 #include <stdio.h>
#include <stdlib.h>
//struct of two ints
struct S1 {
    int p1,p2;
    };

// struct of an int, struct of two ints, and another int
struct S2 {
    int p1;
    struct S1 s1;
    int p2;
    };

int main(void) {
  // set an int to 0
    int s = 0;
  // invoke a struct type 2 and fill with 1, 2, 3, 4
  // like: 
  // struct S2 {
  // int p1; // = 1
  // struct S1 s1; // = 2,3
  // int p2; // = 4
  // };
    struct S2 s2 = { 1, 2, 3, 4 };
  // prepare a pointer of same type like the struct above
    struct S2 *p;
  // claim memory for the pointer
    p = (struct S2 *)malloc(sizeof(struct S2));
  // point to already filled struct
    *p = s2;
  // the int 1 is replaced with 0
    s2.p1 = 0;
  // s is assembled
  // = 1   0   4   3 = 7
    s = p->p1   s2.p1   p->p2   p->s1.p2; // WHY p->p1 IS 1 AND NOT 0 ???
    free(p);
    printf("%d",s);
    return 0;
}
 

Aus я это понял (и написал в комментариях, чтобы мне было ясно) p->p1 ссылается с помощью указателя на первый элемент структуры. это должно быть 0 (не 1), потому что при использовании «.»-operator в staement s2.p1 = 0; значение struct s2 в месте p1 должно было измениться с 1 на 0. таким образом, указатель на этот элемент, на который ссылается «->»-operator, также должен был измениться.

Где я ошибаюсь?

Комментарии:

1. *p = s2 не указывает на уже заполненную структуру (которая была бы p = amp;s2; ). Он копирует данные из s2 в необработанную память, на которую p указывает. Затем s2.p1 = 0 изменяет s2.p1 , но нет p->p1 . Это немного отличается от int x = 1; int y = x; x = 2; // y is still 1

2. Вы ожидаете чего-то вроде p = amp;s2; (вместо malloc и присвоения значения), и тогда ваши теории будут верны.

Ответ №1:

p не указывает на s2 изменения so s2 , на которые они не влияют p .

p указывает на память, возвращаемую malloc . Эта память была заполнена путем копирования содержимого s2 here *p = s2 , но это не p указывает на s2 (это было бы p = amp;s2 ).

Если вы правильно понимаете разницу между *p = s2 и p = amp;s2 , то вы пройдете верный путь к пониманию указателей.

Комментарии:

1. facepalm вы правы. Я чертовски новичок, но, по крайней мере, я понимаю ваше объяснение, и теперь я помню то же самое в обучающем видео. Требуется гораздо больше практики. Спасибо за разъяснения.