
No.7ベストアンサー
- 回答日時:
ポインタは、初心者が最もつまづきやすい部分だと言われています。
実際、おそらくポインタでつまづく人は多いのかも知れません。
しかし、ポインタというものは、慣れた人に言わせれば
「今になってみるとどうして悩んでいたのか分からないほどシンプルな機能」
なのだそうです。気楽にいきましょう。
(1)
C言語を扱うには、ハードウェアまわりの理解が少しばかり必要です。
ポインタについては、
1. メモリのこと
2. コンパイルして作った機械語のプログラムが実際に動くときのこと
を考えてください。
1. 変数を扱うためには、変数の内容を保存するためにメモリ内の領域を確保する必要があります。
2. メモリの領域は、1バイトごとのアドレスで管理されています。
3. マシンは複数のプログラムが共有するため、変数のアドレスは実行するたびに変わります。
(2)
変数とは何でしょうか。
変わる数と書いて変数です。マシンの中では音も絵も1と0の列ですから、数です。
実行するたびに変わる可能性があるものを一時的に記憶しておくためのものが変数です。
実行時に変数のために確保される領域のアドレスは毎回変わるので、アドレスを記憶する変数というものがあります。
それがポインタです。
(3)
/* サンプルプログラム */
#include<stdio.h>
int main(void)
{
char a; //char型の変数aを作成
char *pt_a; //charのポインタ型の変数pt_aを作成
a = 'A'; //変数aに割り当てられたメモリ領域に'A'を書き込む
pt_a = &a; //pt_aに割り当てられたメモリ領域に「変数aに割り当てられたメモリ領域の先頭のアドレス」を書き込む
(*pt_a)++; //pt_aの内容が指し示すメモリ領域に「そこにあるデータに1を加算したもの」を書き込む
*pt_a++;
/* 実行時のメモリの状態を出力 */
printf("char型変数 a の 中身: %c\n", a);
printf("char型変数 a の アドレス: %p\n", &a);
printf("\n");
printf("charのポインタ型変数 pt_a の 中身: %p\n", pt_a);
printf("charのポインタ型変数 pt_a の アドレス: %p\n", &pt_a);
return 0;
}
コンパイルして、実行してみましょう。
(4)
/* 余談 */
charの表現に必要なデータ長は1バイトですが、intになると、これが2バイトとか4バイト(コンパイラによって異なる)だったりします。
変数の型によって使用するメモリの領域の幅が異なるので、
「変数が利用する領域の先頭のアドレス」だけではデータを操作できません。
なので、ポインタにはアドレス以外にもう一つ、「領域の幅」という情報がくっついてきます。
但し、これはコンパイラ的にはソースコードを読むだけで判断でき、実行するたびに変わるというものではないため
直接的にポインタ変数の実体に含まれることはありません。
しかしながら、どこか別の場所で確実に「幅」が管理されているという事は、覚えておくと便利なことがあるかもしれません。
この回答への補足
t11uさん、ご回答ありがとうございます。
(3)の
(*pt_a)++; //pt_aの内容が指し示すメモリ領域に「そこにあるデータに1を加算したもの」を書き込む
までは、理解することができました。
が、次の、
*pt_a++;
はどんな意味合いになるのでしょうか?
何となく、そこにあるアドレスから指定したデータ型の分(幅?)だけ、移動するみたいなイメージではないのか? と思うのですが、そうだとすればどうしてそうなるのか、よく分かりません。( )があるとないとで、どうして上記と違うのか? など…。
あまりしつこいのもアレですので、理解するのは諦めて、
もう、そうなるもの、と暗記した方がよい感じでしょうか?
うーん、私には難しすぎる……。
No.4
- 回答日時:
▽1 *p++ の場合は、*(p+1) で、ポインタ位置をずらしている
ポインタ位置をずらしているのはあっています。
▽2 (*p)++ の場合は、*p = *p+1 で、pの値を変更している
*p = *p+1はあっていますが変更しているのはpの値ではなく*pの値ですね。
c[0]が2になっているのが確認できるはずです。
この回答への補足
php504さん、ご回答ありがとうございます。
「変更しているのはpの値ではなく*pの値ですね。」
の意味が理解できなかったのですが、
pの値と*pの値は違うのでしょうか?
No.3
- 回答日時:
このような疑問は、コンパイラに聞いてみると一目瞭然です。
コンパイルすると次のようになります。
int *p; //sizeof( int ) = 4
*p++
mov edx, DWORD PTR _p
add edx, 4
mov DWORD PTR _p, edx
(*p)++
mov eax, DWORD PTR _p
mov ecx, DWORD PTR [eax]
add ecx, 1
mov edx, DWORD PTR _p
mov DWORD PTR [edx], ecx
この回答への補足
yphkz4063さん、ご回答ありがとうございます。
add edx, が違うというのは分かったのですが、
これは、何を意味しているのでしょうか?

No.2
- 回答日時:
ポインタを覚える前の基本的なことですけど、インクリメントの・・・
int a=0,b;
while(b<10){
b= ++a; /* プレインクリメント */
printf("a=%d, b=%d\n",a,b);
}
と・・・
int a=0,b;
while(b<10){
b= a++; /* ポストインクリメント */
printf("a=%d, b=%d\n",a,b);
};
の違いについて、理解できていますでしょうか?
この回答への補足
maimi09さん、ご回答ありがとうございます。
両者の違いについては、理解できているつもりです。
前者は画面表示する前にインクリメント
後者は画面表示した後にインクリメント
で、ok?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 双方向リスト 1 2023/06/28 04:16
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- 日本語 日本語のアクセント 1 2022/05/12 13:26
- 英語 描写述語の条件(本来の性質、一時的な属性、又は両方)について 2 2022/07/25 13:41
- C言語・C++・C# C言語 配列とポインタについて 2 2022/06/02 11:53
- HTML・CSS WEBサイトの構築。表示データとWEBデザインを分離する考え方を専門用語・業界用語では何と言うか? 8 2022/09/27 09:16
- 英語 「第2文型主語のwhat節が前置詞の目的語である場合に、補語の前に同じ前置詞が必須なのか」について 2 2023/05/12 11:17
- 英語 総称的意味の「the+過去分詞」が無冠詞複数形で置き換えることができない理由について 5 2022/08/04 10:14
- 借地・借家 賃貸の違約金と更新について 4 2023/08/25 00:29
- 英語 「名詞+for...to不定詞句」で「for以降」が完全な文となる場合の名詞との関係について 4 2023/04/26 09:45
関連するカテゴリからQ&Aを探す
おすすめ情報
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
参照型で受け取った引数をポイ...
-
fopne で失敗する原因
-
PASCALとFARの意味
-
LPSTR型の初期化について
-
CWnd::EnableWindow()の扱い方
-
ポインタについて
-
プーさんのマウスポインタを教...
-
連結リスト 要素の入れ替え
-
ハンドルはポインタか
-
C++で関数ポインタから関数名を...
-
自作DLLの引数について、ポイン...
-
NULLポインタが0でない処理系と...
-
TCHAR文字列内の検索について
おすすめ情報