void foo()
{
int *ptrInt=0;
char *ptrChar=0;
ptrInt++;
ptrChar++;
}
Windows2000上で、上記を実行すると
ptrIntは4になります。
ptrCharは1になります。
なぜでしょうか。
32ビットとはいえ、
ptrIntとptrCharはアドレスを示しますよね。
アドレスに1加算するのだから、
int型、char型に関係なく、
いずれも1になるべきだと思います。
int型のポインタの場合示すデータは4バイトなので、
ポインタ1加算は、4(バイト)加算になるということでしょうか。
No.5ベストアンサー
- 回答日時:
mtsed さんは「ポインタ」とは「アドレス」であると思っているようですね。
まず、ポインタは「型」であると覚えたほうが良いと思います。
そして、ただの「ポインタ型」というものがあるわけではなく、必ず「何かの型へのポインタ型」になるわけです。
ですので、「char型へのポインタ型」と「int型へのポインタ型」とは別の型になるわけです。
そして、ポインタ演算をすると、この「○○型へのポインタ型」の○○型のサイズ分だけアドレスが加算されるわけです。
ちなみに、一般に単に「○○型へのポインタ」と言った場合、次の3つのいずれかの意味で使われていると思います。
1. ○○型へのポインタ型
2. ○○型へのポインタ型の変数
3. ○○型へのポインタ型の値
私は意識して使い分けるべきだと思うのですが、私の周りをみると結構いい加減な人が多いのも事実のように思います。
たとえば、以下の例の場合を考えて見ます。
----------------------------------------
int *hoge_ptr;
int hoge;
hoge_ptr = &hoge;
----------------------------------------
この場合、
「int *」が「int型へのポインタ型」をあらわしています。
「hoge_ptr」は「int型へのポインタ型の変数」として定義されます。
そして、hoge は「int型の変数」なので、&hoge は「int型へのポインタ型の値」を持つことになります。
hoge_ptr は「int型へのポインタ型の変数」ですから、当然「int型へのポインタ型の値」しか設定することができません。
そうしないと、*hoge_ptr としたときに正しい値を読み出せないですよね?
このあたりの話は問題ないと思いますが…大丈夫ですよね?
# 大丈夫な場合は、大変失礼いたしました。
ですので、hoge_ptr++ としたときに、アドレスが 1バイトしか進まなかった場合、*hoge_ptr で読み出せる値は、意味のない値になってしまうことになります。
意味のある値を読み出すためには、int型のサイズ分 (32ビットであれば、4バイトですよね) アドレスを加算しなければいけないわけです。
こんな説明でいかがでしょうか。
No.4
- 回答日時:
皆さんの言うとおりです。
int は4バイト charは1バイトです。
このように考えるとわかりやすいです。
縦に箱がずらっと並んでいることを想像してください。
int は4バイトなのでひとつの*ptrIntにたいして4つの箱が割り当てられます。
よって初期状態で*ptrIntは[0],[1],[2],[3]がわりあてられそのうちの[0]に、上記のプログラムによると0が代入している状態です。
ここでptrInt++をすると、次の4つ箱に進みます。
よって[4],[5],[6],[7]が割り当てられ、
そのうちの[4]を示している状態です。
なので、ここでアドレスを表示すると4になるわけです。
No.3
- 回答日時:
ポインタとただのアドレスの違いはまさにこの点だと思います。
たとえば構造体のポインタでも同じで、+1すると構造体サイズ分アドレスが進みます。ポインタは構造体の先頭アドレスを指すだけでなく、そのポイントした領域のサイズ(と構造)まで表します。
この辺をおさえておけば、ポインタも扱いやすくなると思います。
No.2
- 回答日時:
>int型のポインタの場合示すデータは4バイトなので、
>ポインタ1加算は、4(バイト)加算になるということでしょうか
そういうことになります。
ptrInt++で1ずつ加算されるとどうなるか?4ずつ加算されるとどうなるか?を実際のプログラミング上でのポインタの使い方と絡めて考えるとよりポインタのことが理解できると思います。
int pnInt[2];
char pbChar[2];
として考えると分かりやすいと思います。この場合もchar*やint*で宣言したときと同じです。
こうして
&(pnInt[0])
&(pnInt[1])
&(pbChar[0])
&(pbChar[1])
のようにアドレスを見るとcharの場合はアドレスが1差なのに、intの場合は4差になります。
sizeof(int);
sizeof(char);
でintデータとcharデータの大きさを見るとそれぞれのデータサイズが分かります(4と1)(実際にはプラットフォームによってintは2など違うこともあります)。この大きさごとにアドレスも大きくなります。
int*を4ずつではなく、1ずつ大きくするには。。。
((char*)ptrInt)++;
のようにします。*ptrIntに数値を代入してアドレスを1ずつ動かして値を出力したりすると面白いかもしれません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【お題】絵本のタイトル
- ・【大喜利】世界最古のコンビニについて知ってる事を教えてください【投稿~10/10(木)】
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
init関数の意味
-
CImage GetBitsメソッドについて
-
Run-Time Check Failure #3とい...
-
ポインタのミスでOS壊れるの...
-
C言語によるメモリ読み書き
-
DelphiでCreateProcessがうまく...
-
無効なポインタ操作のエラー
-
fopne で失敗する原因
-
関数から配列を返すには?
-
C言語にて構造体のメンバがNULL...
-
配列の要素数に変数を入れたい...
-
VB.NETでテキストボックスをコ...
-
C# ポインタ アクセス違反
-
C言語 配列の長さの上限
-
10個の整数を入力して小さい順...
-
VB6 任意の順番でのソート
-
C++Builder 2009 テキスト...
-
配列の問題
-
Excelですべての組合せ(重複組...
-
構造体のデータを丸ごとコピー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
セグメントエラー
-
init関数の意味
-
fopne で失敗する原因
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
ExcelVBAでのkernel32(64bit)
-
LPSTR型の初期化について
-
参照型で受け取った引数をポイ...
-
C言語でのconstを返す関数
-
ハンドルはポインタか
-
PASCALとFARの意味
-
ハンドル、アドレス、ポインタ...
-
CWnd::EnableWindow()の扱い方
-
デバイスハンドルとは?
-
ポインタについて
-
C言語の文字列?処理 strcpyやl...
-
ポインタのミスでOS壊れるの...
-
C++ vectorのbeginについて
-
どうしてエラーになるかわかり...
おすすめ情報