Created
June 12, 2014 17:21
-
-
Save w495/af6e13c306ec158f92e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
/** | |
* Создадим параметрические макросы с переменным числом аргументов. | |
* Они понадобятся для удобства отладки. | |
* | |
* @HINT_1: Что это такое (только для C99): | |
* http://en.wikipedia.org/wiki/Variadic_macro | |
* | |
* @HINT_2: Что за `033[` | |
* http://habrahabr.ru/post/119436/ | |
**/ | |
#define LOG_HELPER(fmt, ...) \ | |
fprintf( \ | |
stderr, \ | |
"\033[32mLOG:\033[0m " \ | |
"\033[33m%s\033[0m " \ | |
"\033[36m%s\033[0m " \ | |
"[\033[1m%d\033[0m] : " fmt "%s", \ | |
__FILE__, \ | |
__FUNCTION__, \ | |
__LINE__, \ | |
__VA_ARGS__ \ | |
) | |
#define LOG(...) LOG_HELPER(__VA_ARGS__, "\n") | |
struct stack; | |
/* Лучше называть понятно, «stek» --- это стейк по-польски. */ | |
typedef struct stack stack_t; | |
/* | |
* Это не совсем стек. Это элемент стека. | |
* Стек лучше будет описать отдельно. | |
*/ | |
struct stack { | |
int d; | |
// указатель на следующий элемент списка (стека) | |
struct stack *next; | |
}; | |
/* | |
* Если мы меняем сам указатель, то надо передавать указатель на указатель. | |
* Изначально x == (nil) | |
* | |
* + Обратите внимание, что `stacknew` и `push` делают одно и тоже. | |
* На самом деле можно push сделать так, что stacknew будет не нужен. | |
* Опять же у вас stack_t --- это не стек, а его элемент. | |
*/ | |
void stacknew(stack_t ** x, int dat) { | |
*x = malloc(sizeof(stack_t)); | |
(*x)->d = dat; | |
(*x)->next = NULL; | |
} | |
void push(stack_t ** x, int dat) { | |
// объявляем новую динамическую переменную типа stack_t | |
stack_t *pv = malloc(sizeof(stack_t)); | |
// записываем значение, которое помещается в стек | |
pv->d = dat; | |
// связываем новый элемент стека с предыдущим | |
pv->next = *x; | |
// новый элемент стека становится его вершиной | |
*x = pv; | |
} | |
int print(stack_t * x) { | |
/* Проверяем, что x вообще есть. */ | |
if (!x) | |
/* Если его нет, возвращаем 0. Как код ошибки. | |
* На самом деле, можем ничего не возвращать, | |
* и ничего не делать. | |
*/ | |
return 0; | |
if (x->next) { | |
print(x->next); | |
} | |
/* Смотрим что там */ | |
LOG("x = %p; x->d = %d; x->next = %p", (void*)x, x->d, (void*)x->next); | |
printf("%d\n", x->d); | |
return 1; | |
} | |
int main() { | |
/* Безопаснее инициализировать все */ | |
char c = 0; | |
int dat = 0; | |
stack_t *sta = NULL; | |
/* Смотрим что там */ | |
LOG("sta = %p", (void*)sta); | |
while (scanf("%c", &c) != EOF) | |
switch (c) { | |
case 'r':{ | |
LOG("sta = %p", (void*)sta); | |
if(scanf("%d", &dat) == EOF ) | |
return 0; | |
stacknew(&sta, dat); | |
LOG("sta = %p", (void*)sta); | |
break; | |
} | |
case '+':{ | |
LOG("sta = %p", (void*)sta); | |
if(scanf("%d", &dat) == EOF ) | |
return 0; | |
push(&sta, dat); | |
LOG("sta = %p", (void*)sta); | |
break; | |
} | |
case 'p':{ | |
LOG("sta = %p", (void*)sta); | |
print(sta); | |
LOG("sta = %p", (void*)sta); | |
break; | |
} | |
case 'q': | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment