質問するログイン新規登録
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

558閲覧

C言語 ポインタのポインタの有用性に関して

takuchan111

総合スコア2

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2025/07/25 07:32

編集2025/07/25 07:59

0

0

#質問内容

C言語のポインタのポインタに関して質問です。
以下はポインタのポインタを用いて線形リストを作るプログラムです。
ポインタの動き方はわかるのですが、ポインタのポインタを使うメリットがわかりません。&headを実引数として渡さないとheadに影響を与えることができませんが、headは最初のノードを固定で指していればよく、更新の必要性がわかりません。
結局、ポインタのポインタは何のためにあるのでしょうか。

#include <stdio.h>
#include <stdlib.h>

typedef struct CELL{
int data; struct CELL *next;
} CELL;
CELL * CELL_alloc(int data){
CELL *p=malloc(sizeof(CELL));
p->data=data; p->next=NULL; return p;
}

void insert(CELL **head_p,int data){
CELL *new=CELL_alloc(data);
CELL **p=head_p;
while(*p!=NULL && (*p)->data<data){
p=&((*p)->next);
}
new->next=*p;
*p=new;
}

int main(){
CELL *head=NULL;
insert(&head,10);
insert(&head,30);
insert(&head,20);
}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2025/07/25 08:01

質問は何ですか? > 二個目のノードを挿入する際に前に呼び出した時のnewが邪魔になってしまいます > 原因が分かる方 題名に「有用性」とありますが、これは質問ですか? あと、コードが読みにくいので、コードを編集して</>ボタンを押して出てくる書式に沿って記入していただくことはできますか。
jimbe

2025/07/25 08:28 編集

そも head の初期値は NULL で、その後最初のノードのアドレスになるのですから、その時点で”固定”では無いのではありませんか? 既に fana さんの回答でも言われていますが、 >insert(&head,30); を >insert(&head,5); にしたらどう動いてどうなるのかを追って見られると良いかと思います。
takuchan111

2025/07/25 09:26

お手数をおかけしてしまい申し訳ありません。 疑問点が自分中でも明確ではないため、再度質問させていただきたいです。 解答していただいた皆様、ありがとうございます。
guest

回答1

0

ベストアンサー

&headを実引数として渡さないとheadに影響を与えることができませんが、headは最初のノードを固定で指していればよく、更新の必要性がわかりません。

その関数 insert() は,「データ値が昇順になるように新しいデータを加える(注※)」という処理を行っているのですから,新しく加えるデータの値次第では「最初のノード」を変更する必要がありますよね.

(……というか,最初は head=NULL なので,1個目のデータを加えた時点でそのデータを指すように更新したいですよね.)

(注※)リストはこの insert() だけで構築されるのだ,という前提での表現

投稿2025/07/25 08:02

編集2025/07/25 08:28
fana

総合スコア12253

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2025/07/25 08:10

この質問がなされていることから推測するに,そのコードはご自身が書いたものではないのだと思いますが, 勉強用に誰かが書いたコードを見て参考にしているのであって,且つ,参考にする物を自由に選べる状況にあるのだとしたら…… 関数とかが「何をする物なのか」という説明がしっかりと存在するものを参考するのが良いのではないかとおもいます. 今回のような「関数の内側の実装を読まないと何する物なのかがわからない」タイプのコードを相手にするのではなく.
takuchan111

2025/07/25 09:25

回答いただきありがとうございます。 おっしゃる通り、このコードは自分が書いたものではないのです。しかし、1か月後に控えた大学院入試の過去問で出題されたものであることからこのコードを解読しようと思っています。 このコードは、ポインタを実引数にすると場合分けが発生してしまい、それを避けるにはポインタのポインタを使うとよいという前振りがあってからの問題でした。正直、大学院入試が近くて焦っていることもあり、質問の内容もわかりにくくなってしまい申し訳ありません。 少し疑問点が自分の中でまとまっていないため、もう少し考えてから再度質問させていただきたいです。
fana

2025/07/25 10:42

> ポインタを実引数にすると場合分けが発生してしまい、それを避けるにはポインタのポインタを使うとよいという前振り (どういう話なのかこちらにはわかりませんが)ひょっとしたら,そこら辺の話から把握されるとよいのかもしれませんね. 例えば「場合分けが発生」したコードと本件のコードを比較してみると何かわかるかも,とか. (※特に返信とかは不要です)
takuchan111

2025/07/25 13:13

丁寧に追っていったら納得できました! 解答していただいた皆様、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問