В учебнике приведен текст и описания программы по созданию стека. В более ранних примерах был явно виден процесс создания переменных, то здесь не совсем понятно на каком этапе создается структура, посему вопрос с продолжением: действительно ли структура создается через malloc в процессе выделения памяти и где тогда назначение переменной с "каким-либо названием" под эту структуру?
И дальше по списку, чтобы закрепить материал?
2) Если это так, то значит инициализация переменных - это по сути выделение памяти, а не назначение для них "имен" и при их инициализации через malloc мы получаем область памяти нужного размера с указателем, без имени (такой вот несчастный кусочек памяти), с которым работаем только через указатель, размечая эту область и записывая туда исходя из размеров данных внутри структуры?
Либо может дайте другое представление, чтобы нужный образ создался и закрепился.
#include
#include
struct stack {
int data;
struct stack *next;
};
struct stack *create(struct stack *, int); // присоединение элемента к голове, возврат адреса головы
void list(struct stack *); // просмотр стека
main() {
int i, n;
struct stack *head; // адрес, указывающий на голову стека
head = NULL;
scanf("%d", &n);
for (i=0; i <= n; i+=5) {
head = create(head,i);
printf("%d<--", head->data);
}
printf("\n");
list(head);
free(head);
}
struct stack *create(struct stack *head, int x) {
struct stack *element; // указатель на новую структуру
element = (struct stack *)malloc(sizeof(struct stack)); // выделяем память
element->next = head;
element->data = x;
return element;
}
void list(struct stack *p){
while (p != NULL) { // пока не конец стека
printf("%d-->", p->data);
p = p->next; // продвижение по списку
}
printf("\n");
}
В процессе выполнения эта программа запрашивает целое число и сначала выводит числа от 0 до указанного числа, а затем выводит их же в обратном порядке — от указанного число до нуля:
60
0<--5<--10<--15<--20<--25<--30<--35<--40<--45<--50<--55<--60<--
60-->55-->50-->45-->40-->35-->30-->25-->20-->15-->10-->5-->0-->
Осталось выяснить почему она так делает.
В программе определяется тип данных struct stack, одним из полей которого является указатель на структуру типа struct stack.
В функции main() создается указатель (head) на struct stack, которому сначала присваивается NULL, т.к. он никуда не указывает.
В цикле определенное количество раз вызывается функция create(), которой передается текущее значение указателя (адрес) и какое-то число.
В теле create() создается новый указатель (element) типа struct stack.
С помощью функции malloc() выделяется память, необходимая под одну структуру. Объем этой памяти вычисляется с помощью функции sizeof(). Возвращаемый malloc() указатель приводится к типу struct stack.
Адрес выделенной памяти под новую структуру присваивается переменной-указателю element.
В поле next новой структуры записывается адрес, который содержится в аргументе, переданном в функцию. При первом вызове create() там содержится NULL. При последующих вызовах адрес памяти созданной в предыдущем вызове функции структуры. Таким образом в поле next структуры, доступной по указателю element, сохраняется адрес, содержащийся в head. Следовательно head в дальнейшем можно изменить, не потеряв связь с предыдущими данными.
В поле data записывается число (какие-то существенные для нас данные).
Из функции create() возвращается указатель на только что выделенную память с новой структурой, в которой сохранен адрес на предыдущую структуру. Этот указатель присваивается head. В результате head постоянно указывает на последнюю созданную структуру.
На экран с помощью printf() выводится значение поля data структуры, на которую указывает в данный момент head.
Функция list() позволяется просмотреть стек, получив указатель на его последний (по времени создания) элемент. При вызове значение head присваивается переменной p. Обратите внимание, изменение p в теле list() не повлияет на значение head в теле main(). Переменная p получает копию адреса и далее изменяет лишь свое значение.