現在「C言語10課 ポインタ編」という書籍を見ながら、C言語の勉強をしております。
以下のコード、関数内の2行目にて、
aのような変数と、ポインタ変数を区別するため、アスタリスクを付けて*pとするのは理解できます。
一方、
次の行のaを指す場合は、p=&a;というふうに、アスタリスクを付けないpとし、
次の次の行では、p=5;として、再びアスタリスクを付けたp としています。
この場合、両方ともアスタリスクを付けた*p、あるいは両方とも付けない方がスッキリするのですが、
片方は付け、片方は付けない、のは、どう解釈すれば良いでしょうか。
「変数を指す場合は、付けない決まりなんだよ」と言われれば、その通りなのですが..
なにか特別な事情があったりするのでしょうか。よろしくお願いいたします。
c
1# include <stdio.h> 2 3int main(void) 4{ 5 int a; 6 int *p; 7 p=&a; 8 *p=5; 9 return 0; 10}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
aのような変数と、ポインタ変数を区別するため、アスタリスクを付けて*pとするのは理解できます。
そういう考え方ではないです。
*p
は、「ポインタ変数p
の値であるアドレスの指し示す先の変数」を意味します。
2つの宣言は、
・int a;
⇒ a
はint
型変数を宣言
・int *p;
⇒ 「ポインタ変数p
の値であるアドレスの指し示す先の変数」がint
型変数であるような変数p
を宣言
という意味です。
p=&a;
は、変数p
に「変数a
のアドレス」を代入しています。
*p=5;
は、「ポインタ変数p
の値であるアドレスの指し示す先の変数」に、5
を代入しています。
変数p
には「変数a
のアドレス」が入っていますので、
これは、「変数a
のアドレスの指し示す先の変数」となり、結局「変数a
」のことです。
「ポインター変数には*
を付けるのか付けないのか?」という考えを捨てましょう。
「アドレスの指し示す先」を扱いたいのであれば付けます。「アドレス自体」を扱いたいときは付けません。
よく考えるか、頭の中で考えてわからない場合は、「ポインターとは何か」を復習した上で絵を描いてみましょう。
投稿2020/03/17 07:26
総合スコア85949
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/17 07:38
2020/03/17 07:42
2020/03/17 08:50
2020/03/17 09:46 編集
2020/03/23 02:59 編集
2020/03/23 03:27
2020/03/23 06:18
2020/03/23 06:40
2020/03/23 08:10
2020/03/23 09:09
2020/03/23 09:41
0
次のようなコードがあったとします。
C
1#include <stdio.h> 2 3int main(void) 4{ 5 char s[4] = "abc"; 6 printf("%s\n", s); 7 printf("%c\n", s[1]); 8}
質問
s を char変数と区別して配列変数とするために [] を付けて s[4] とするのは理解できます。
一方、printf の行で、[] を付けない s と、[] を付けた s[1] を使用しています。
この場合、両方とも [] 付けた s[1]、あるいは両方とも付けない方がスッキリするのですが、
片方は付け、片方は付けない、のは、どう解釈すれば良いでしょうか。
回答
使用目的が異なります。
・[] を付けない s は "abc" 全体の値を使用するため。
・[] を付けた s[2] は "abc" の中の 'b' の値を使用するため。
元の質問に対する回答
使用目的が異なります。
・* を付けない p = &a は、p 自身に a のアドレスを設定します。
・* を付けた *p = 5 は、pの指しているものである a に 5 を設定します。
投稿2020/03/19 01:32
編集2020/03/19 03:16総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
感覚的になってはしまいますが、理解のきっかけにでも使っていただければという「お話」として
int * p;
という宣言を区切った時、区切った左と右の型が同じもの、というのはいかがでしょう。
int *
とp
pは、int *(intへのポインタ)型、です。なので、pはintへのポインタ(アドレス)を扱います。p=の右辺にはポインタ(アドレス)を置いて下さい。
int
と* p
*pは(これを一体と見て) int型です。なので、*pは数値を扱えます。*p=の右辺には数値を置いて下さい。
(カッコがついたり複雑になると通用しない場合もあるでしょうが、この「感じ」を掴んでおけば理解の助けにはなるのでは)
投稿2020/03/17 21:56
総合スコア7703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
y_waiwaiさんのお答えが舌足らずだと思ったので。
p=&a;というふうに、アスタリスクを付けないpとし
操作対象がポインタ変数ならアスタリスクは不要です。p = &a; は(a のアドレスを)ポインタ変数pへ代入します。代入した結果、どこの値が変化するかと言えば、ポインタ変数 p それ自身です。この時、アスタリスクは不要です。
p=5;として、再びアスタリスクを付けたp としています
操作対象がポインタ変数が指すメモリならアスタリスクが必要です。*p=5;で値が変化するのは、ポインタ変数 p ではありません、ポインタ変数 p が指す先の a という変数(a というメモリ)です。いわゆる、ポインタ変数を使った間接参照などと呼びます。このためにポインタ変数があります。
この時、アスタリスクが必要です。
片方は付け、片方は付けない、のは、どう解釈すれば良いでしょうか
- 操作対象がそのポインタ変数ならアスタリスクは不要
- 操作対象がそのポインタ変数が指すメモリならアスタリスクが必要
操作とは次の3つを念頭に置いています。
- 値を読みだす
- 値を書き込む(代入)
- 演算を施す(例:a++ なら変数 a の値を1増やす)
さて、ここで私も質問者に訊いてみましょう。
int *p; p = &a;
をひとつにまとめると
int *p = &a;
と書けることをご存知ですか?
ここにアスタリスクを書く(アスタリスクがある)のは何故ですか?
追加の問い。int *p; と定義されたポインタ変数 p がある時、
- x = *p;
- y = p;
はどちらもありうるコードですが、 x, y の変数定義が無いとコンパイルエラーになります。x, y の変数定義を補ってみてください。それぞれ、どんな動作をしますか?
投稿2020/03/17 12:31
編集2020/03/17 21:29総合スコア1382
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/18 03:58
2020/03/18 11:59
0
宣言のところは,スペースの位置を変えてみれば,型が違うということが若干わかりやすくなる感.
int a; //【int】型 int* p; //【int*】型 int** q; //【int**】型
(正式な言葉(?)として「int*型」とかいう記述がOKかどうかは知りませんけども…)
投稿2020/03/17 07:47
総合スコア11996
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/17 08:54
2020/03/17 09:26
2020/03/17 12:37
2020/03/18 03:44
2020/03/18 11:53
2020/03/19 01:22
2020/03/23 02:21
0
ベストアンサー
提示の例では、
つけないのはアドレスを示し、つけるのは、アドレス先の内容を示します
投稿2020/03/17 07:09
総合スコア88051
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/17 07:13
2020/03/17 07:33
2020/03/17 08:18
2020/03/18 02:44
2020/03/18 03:25
2020/03/23 06:18 編集
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。