質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。

受付中

C言語におけるポインタを用いたスタックの実装

kez_yuyuyu
kez_yuyuyu

総合スコア6

Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。

2回答

0評価

0クリップ

273閲覧

投稿2022/05/28 08:15

編集2022/05/28 18:51

解決したいこと

  • 勉強をしていて、配列を用いることでスタックを実装できることを知りました。
  • そこで配列の代わりにポインタを使うことでも実装できるのではないかということで実装を試しました。
  • しかしどうしてもうまくいかないため、どうしたらうまくいくのか教えていただきたいです。

ソースコード

//ポインタを用いた実装 # 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; }

やりたいこと

  1. まず配列を指定します。
  2. 次に[0]のポインタを取得して、それを保持します
  3. popの関数が呼ばれると、保持しているポインタから値を取り出し、int分ポインタの値を下げます
  4. 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ができればいいものとします。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

y_waiwai

2022/05/28 08:21

で、しつもんはなんでしょうか
hoshi-takanori

2022/05/28 08:22

> 配列の代わりにポインタを使う そのコードでも配列は使ってるので、「添字の代わりにポインタを使う」でしょうか? エラーの原因は実行文を関数の外に書いてるからですね。 あと、ポインタのインクリメント・デクリメント幅が大きすぎるような…。
kez_yuyuyu

2022/05/28 08:26

>>「添字の代わりにポインタを使う」でしょうか? はいその通りです。分かりにくくて申し訳ございません。 main関数の中に記載するということでしょうか? グローバル変数にしたかったので外に書いたのですがそれが不味かったということでしょうか? またint型で指定しているので4バイト分動かせばいいと考えたのですが大きいのはなぜですか?
hoshi-takanori

2022/05/28 08:59 編集

宣言と代入を分けてるので、関数の外では代入がエラーになります。宣言と初期化を同時に行えば大丈夫なはず。 また、よくある間違いですが、ポインタの足し算や引き算は、ポインタの指す型のサイズ倍されます。ので、単純に 1 足したり引いたりすれば良いのです。もっと言うと ++ や — を 1 回で大丈夫です。 https://www.ei.fukui-nct.ac.jp/2019/05/21/pointer-array/

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。