スタックをCで
やっぱり世の中はCでできてるんじゃないかという気がして、少しCをやってみた。構造体とかポインタの練習に簡単なスタックを作ってみた。
#include <stdio.h> #include <stdlib.h> typedef struct { int size; int ptr; int *stk; } Stack; int Allocate(Stack *s, int size){ s->ptr = 0; if((s->stk = calloc(size, sizeof(int))) == NULL) return -1; s->size = size; return 0; } int FreeStack(Stack *s){ s->size = 0; free(s->stk); } int ShowStack(Stack *s){ int i; for(i = 0; i < s->size; i++){ printf("stack[%2d]: %3d\n",i,s->stk[i]); } } int Push(Stack *s, int i){ if(s->ptr < s->size){ s->stk[s->ptr] = i; s->ptr++; }else{ puts("cannot push any more"); return -1; } } int Dup(Stack *s){ int i, *ptr = &s->stk[s->ptr]; if(s->ptr < s->size){ i = *(--ptr); *(++ptr) = i; s->ptr++; }else{ puts("cannot dup any more"); return -1; } } int main (int argc, char *argv[]){ Stack s; int i, size; if(argc <= 1){ puts("need an argument"); return -1; }else{ size = atoi(argv[1]); } if(Allocate(&s, size) == -1){ puts("cannot allocate stack area"); return 1; } for(i = 11; i < 15; i++){ Push(&s, i); Dup(&s); } ShowStack(&s); FreeStack(&s); }
実行結果は、こんな感じ。
$ gcc -o stack stack.c ; ./stack 10 stack[ 0]: 11 stack[ 1]: 11 stack[ 2]: 12 stack[ 3]: 12 stack[ 4]: 13 stack[ 5]: 13 stack[ 6]: 14 stack[ 7]: 14 stack[ 8]: 0 stack[ 9]: 0 $ gcc -o stack stack.c ; ./stack 6 cannot push any more cannot dup any more stack[ 0]: 11 stack[ 1]: 11 stack[ 2]: 12 stack[ 3]: 12 stack[ 4]: 13 stack[ 5]: 13 $
これだけ動かすだけでも苦労した。そして、スタックの上から2つを入れ替えるswap関数を作ろうとして、ポインタの使い方がよく分からなくなった。いや、もともと分かってないんだけど。
#include <stdio.h> int main(void){ char *ptr; char x[] = "This test is dead simple"; ptr = x; ptr += 2; printf("%c%c\n",*ptr, *(ptr + 1)); }
とやると、結果は「is」となる。3文字め(*ptr)と4文字目(*(ptr + 1))が表示されている。ところが、
printf("%c%c\n",*ptr, *(ptr++));
とやると、「si」と逆順になる。さらに、
printf("%c%c\n",*ptr, *(++ptr));
とやると、「ss」となってしまう。まだしも、ptr++とやった場合に結果が「ii」なら意味が分かるんだけどなぁ。根本的に分かってない感じが強い。