解決したいこと
- 勉強をしていて、配列を用いることでスタックを実装できることを知りました。
- そこで配列の代わりにポインタを使うことでも実装できるのではないかということで実装を試しました。
- しかしどうしてもうまくいかないため、どうしたらうまくいくのか教えていただきたいです。
ソースコード
//ポインタを用いた実装 # include <stdio.h> int stack[8]; //ポインタ変数の宣言 int *head; //配列の先頭のポインタを代入 head = &stack[0]; //pop関数の実装(値を取り出す) int pop(){ int pop_num = *head; head = head-sizeof(stack[0]); return pop_num; } //push関数の実装(値の追加) void push(int a){ head = head + sizeof(stack[0]); *head = a; } int main(){ push(1); push(2); int ans = pop(); printf("%d",ans); push(3); int ans_2 = pop(); printf("%d",ans); return 0; }
やりたいこと
- まず配列を指定します。
- 次に[0]のポインタを取得して、それを保持します
- popの関数が呼ばれると、保持しているポインタから値を取り出し、int分ポインタの値を下げます
- pushが呼ばれたときはint型の引数を受け取り、ポインタの値をint分増加したのち、値を格納します。
エラーメッセージ
point.c:8:1: warning: data definition has no type or storage class 8 | head = &stack[0]; | ^~~~ point.c:8:1: warning: type defaults to 'int' in declaration of 'head' [-Wimplicit-int] point.c:8:1: error: conflicting types for 'head'; have 'int' point.c:6:6: note: previous declaration of 'head' with type 'int *' 6 | int *head; | ^~~~ point.c:8:8: warning: initialization of 'int' from 'int *' makes integer from pointer without a cast [-Wint-conversion] 8 | head = &stack[0]; | ^ point.c:8:8: error: initializer element is not computable at load time point.c: In function 'pop': point.c:12:19: error: invalid type argument of unary '*' (have 'int') 12 | int pop_num = *head; | ^~~~~ point.c: In function 'push': point.c:20:5: error: invalid type argument of unary '*' (have 'int') 20 | *head = a; | ^~~~~
補足説明
- 今回のコードは空かどうか、満タンかどうかを判断する関数を実装していないので、pushした後にpopができればいいものとします。
で、しつもんはなんでしょうか
> 配列の代わりにポインタを使う
そのコードでも配列は使ってるので、「添字の代わりにポインタを使う」でしょうか?
エラーの原因は実行文を関数の外に書いてるからですね。
あと、ポインタのインクリメント・デクリメント幅が大きすぎるような…。
>>「添字の代わりにポインタを使う」でしょうか?
はいその通りです。分かりにくくて申し訳ございません。
main関数の中に記載するということでしょうか?
グローバル変数にしたかったので外に書いたのですがそれが不味かったということでしょうか?
またint型で指定しているので4バイト分動かせばいいと考えたのですが大きいのはなぜですか?
宣言と代入を分けてるので、関数の外では代入がエラーになります。宣言と初期化を同時に行えば大丈夫なはず。
また、よくある間違いですが、ポインタの足し算や引き算は、ポインタの指す型のサイズ倍されます。ので、単純に 1 足したり引いたりすれば良いのです。もっと言うと ++ や — を 1 回で大丈夫です。
https://www.ei.fukui-nct.ac.jp/2019/05/21/pointer-array/