#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 вы правы. Я чертовски новичок, но, по крайней мере, я понимаю ваше объяснение, и теперь я помню то же самое в обучающем видео. Требуется гораздо больше практики. Спасибо за разъяснения.