ポインタと型のサイズに関する初歩的な疑問

このQ&Aのポイント
  • int型のポインタのサイズに関する疑問
  • プログラム実行時のポインタ表示とint型のサイズの相関
  • なぜポインタの間隔は16ビットなのにint型のサイズは4バイトなのか
回答を見る
  • ベストアンサー

ポインタと型のサイズに関する、初歩的な質問

ポインタと型のサイズについて、実験しています。 以下のプログラムを実行したときに、さらに下の 画面表示になるのですが、ここで疑問があります。 int型の配列を作ってそのポインタを表示しています。 i[0]のポインタ=0012FF38 i[1]のポインタ=0012FF3C 0012FF38 と 0012FF3C の間は16ビットなのに、 int型のサイズは4バイトとなってしまいます。 なぜでしょうか。 -------------プログラムここから-------------- #include <iostream> using namespace std; int main(){ int i[20]; for(int j = 0;j<20;j++){ printf("i[%d]のポインタ=%p\n",j, &i[j]); } printf("\n\nsizeof(int) = %d\n\n", sizeof(int)); return 0; } -------------プログラムここまで-------------- -------------画面出力ここから-------------- i[0]のポインタ=0012FF38 i[1]のポインタ=0012FF3C i[2]のポインタ=0012FF40 i[3]のポインタ=0012FF44 i[4]のポインタ=0012FF48 i[5]のポインタ=0012FF4C i[6]のポインタ=0012FF50 i[7]のポインタ=0012FF54 i[8]のポインタ=0012FF58 i[9]のポインタ=0012FF5C i[10]のポインタ=0012FF60 i[11]のポインタ=0012FF64 i[12]のポインタ=0012FF68 i[13]のポインタ=0012FF6C i[14]のポインタ=0012FF70 i[15]のポインタ=0012FF74 i[16]のポインタ=0012FF78 i[17]のポインタ=0012FF7C i[18]のポインタ=0012FF80 i[19]のポインタ=0012FF84 sizeof(int) = 4 -------------画面出力ここまで--------------

  • otaks
  • お礼率53% (270/507)

質問者が選んだベストアンサー

  • ベストアンサー
noname#77845
noname#77845
回答No.1

i[0]のポインタ=0012FF38 i[1]のポインタ=0012FF3C 0012FF38 と 0012FF3C の間は16ビットなのに、 int型のサイズは4バイトとなってしまいます。 「0012FF38 と 0012FF3C の間は16ビットなのに、」 0012FF38 と 0012FF3C の間は32ビットです。 どこから16ビットの計算が出てきたのでしょう? 0012FF3C-0012FF38=4 で4バイトになっています。

otaks
質問者

補足

0012FF38 と 0012FF3C の間には 0012FF38 0012FF39 0012FF3A 0012FF3Bの4つがあり、 それぞれの末尾の8 9 A B を表現するためには、1つに ついて、4ビットいるから4 * 4 = 16と計算していました。 今考えると、これは何を計算しているのだろうと 思います。。 0012FF3C-0012FF38=4で4バイトですね、 ご回答ありがとうございました。

関連するQ&A

  • ポインタに ~0を入れること

    見かけたCのプログラムで、 ポインタに~0を代入するものを見ました。 そのプログラムをそのまま載せるのはわかりにくいので、 代わりに以下のプログラムを作って実行しました。 #include <stdio.h> int main(void) { char *pa[3]; int i; pa[0]=0; pa[1]=~0; pa[2]="Hello"; printf("sizeof(char*)=%d\n", sizeof(char*)); for(i=0; i<=2; i++) { if(pa[i]==NULL) printf("pa[%d] はNULLです。\n", i); if(pa[i]==(char*)0xFFFFFFFF) printf("pa[%d]は全ビット1です。\n", i); if(pa[i]==~0) printf("pa[%d]は~0です。\n", i); } return 0; } 結果 sizeof(char*)=4 pa[0] はNULLです。 pa[1]は全ビット1です。 pa[1]は~0です。 このプログラムはコンパイル時にエラーも警告も出ず、 動作も意図したとおりです。 pa[1]に入っている ~0 は、int型の定数なのでしょうか。 それならば、 pa[1]=~0; という代入や if(pa[i]==~0) という比較は 左辺はchar*型で右辺はconst int型であって型が異なりますが、 問題ないのでしょうか。 ~0は0の否定なので、全ビットは1なのでしょうけど、 int型(の定数)だと思います。 ~0というのは何か特別な値なのでしょうか。 ポインタに~0を入れるというのは、意味があるのでしょうか。 (例えば、「ポインタに0を入れるということは、ヌルポインタであって、ポインタとして無効なんですよ」のようなこと。)

  • ポインタのsizeofについて

    C初心者です。 ポインタ宣言させた変数をsizeof()で値を取得させて 表示させてみました。 char *cp; short int *sp; int *ip; i = sizeof(cp); printf("%d\n",i); i = sizeof(sp); printf("%d\n",i); i = sizeof(ip); printf("%d\n",i); 結果は全て4となりました。 これはなぜですか? (ただの変数として宣言すれば1、2、4となります。この理由も理解できています。)

  • ポインタ変数のサイズ

     いろいろC言語のことを知りたくて、次のソースを作って動かしてみました。 ★ソース(□はタブ) ◆◆◆◆◆ #include <stdio.h> #include <stdlib.h> int main(void) { □char *s1; □int *s2; □ □s1 = (char *)malloc(1000); □s2 = (int *)malloc(1000); □ □printf("sizeof s1 = %d\n", sizeof s1); □printf("sizeof s2 = %d\n", sizeof s2); □ □printf("sizeof *s1 = %d\n", sizeof *s1); □printf("sizeof *s2 = %d\n", sizeof *s2); □ □printf("s1 = %d\n", s1); □printf("s2 = %d\n", s2); □ □printf("*s1 = %d\n", *s1); □printf("*s2 = %d\n", *s2); □ □return EXIT_SUCCESS; } ◆◆◆◆◆ ★実行結果1 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 1323000 s2 = 1324008 *s1 = -60 *s2 = 1310916 ◆◆◆◆◆ ★実行結果2 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 11087864 s2 = 11088872 *s1 = -60 *s2 = 11075780 ◆◆◆◆◆ ★実行結果3 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 1519608 s2 = 1520616 *s1 = -60 *s2 = 1507524 ◆◆◆◆◆  OSはWindows Vista、コンパイラはMS Visual Studio 2010 コマンドプロンプトです。次の疑問についてご教授頂きたく、お願い致します。 (1)“sizeof s1”、“sizeof s2”の値が共に4となるのはなぜか。  char型へのポインタ、int型へのポインタとして宣言したs1、s2のサイズが同じ4になる理由が、どうしても分かりません。 (動かす前の予想は、でたらめな値になるかと思っていましたが) (2)“s1”、“s2”、“*s2”の値が毎回でたらめな値になったのに対して、“*s1”の値が毎回“-60”になったのはなぜか。  ポインタでつまずいており、いろいろ実験して体で理解したいと思っています。どうぞよしくお願い致します。

  • ポインタのサイズ

    ポインタのサイズがintと同じになるのは知っているのですが、 以下のコードの場合、 typedef struct hoge{ char buf1[8]; char buf2[16]; }HOGE; void test_func(HOGE *pHoge) { printf("型[%d],実際[%d]\r\n", sizeof(HOGE), sizeof(*pHoge)); memset(pHoge, 0x00, sizeof(*pHoge)); } 正しくサイズが取得できるのですが、 この使い方はC99の仕様的には正しいのでしょうか? よろしくお願いします。

  • ポインタ配列について

    下のプログラムは、ポインタ変数の配列のプログラムです。 このプログラムを、月の順番を入れ替えて出力するプログラムに変更するにはどのようにすれば良いか分かる方いましたら、是非教えてください。例えば、JANUARYとMARCHを入れ替えて出力するプログラムなどです。 #include<stdio.h> void main() { char *p[] = {"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE", "JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"}; int i,j; *p[0]=*p[2]; *p[0]=*p[2]; for(i = 0;i < 12; ++i){ printf("%2d 月:%s\n",i+1,p[i]); } for(i = 0;i < 12; ++i){ j = -1; do{ ++j; printf("%4x ",p[i]+j); } while (*(p[i]+j) != '\0'); printf("\n"); j = -1; do{ ++j; printf(" %c ",*(p[i]+j)); }while (*(p[i]+j) != '\0'); printf("\n"); } }

  • C言語のポインタ

    あまり意識せずにポインタを使っているせいか,次のプログラムではまってしまいました. #include<stdio.h> #include<stdlib.h> int main(void) {  int *p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  printf("%d\n", *p);  return 0; } コンパイルエラーで実行ファイルが出力されません. このプログラムで変数qはなぜポインタじゃないのでしょうか? 次にtypedefでptr_intという型を定義したプログラムは, 上のようなエラーが出力されず,期待とおりの結果になりました. #include<stdio.h> #include<stdlib.h> typedef int* ptr_int; int main(void) {  ptr_int p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  *q = 3;  printf("%d\n", *p);  printf("%d\n", *q); return 0; } typedefすることでなぜエラーを回避することができるのでしょうか? よろしくおねがいします.

  • ポインタの文法

    現在自分が勉強している中で、ポインタを宣言値を出力するときの文法は「pa」がポインタだとすると、 int *pa , printf("%p\n",pa) , printf("%d\n",*pa) などですが、sizeof(pa*)は後ろに「*」がついており後ろに「*」がつくときの意味が分かりません。 是非ご教示願います。

  • ポインタのポインタ

    こんにちは。 C言語の「ポインタのポインタ」の学習中なのですが、以下のプラグラムがエラーが出てしまします。 if文が間違っていると思うのですが、具体的に何がどう間違っているのがわかりません。 ご教示お願いいたします! #include<stdio.h> int main(void) { int date = 300; int *pdate = NULL; int **ppdate = NULL; printf("dateの値は%d<\n", date); pdate = &date; printf("*pdateの値は%d<\n", *pdate); if(**ppdate = NULL){ printf("**ppdateには何も与えられていません。\n"); } else{ return 0; } ppdate = &pdate; if(**ppdate == 300){ printf("**ppdateの値は%dになりました。正常です。\n", **ppdate); } /*強制終了を避けるためのプログラム*/ int i; scanf("%d", &i); return 0; }

  • 構造体へのポインタについて

    初心者です。 C入門書の著者のサポートページには正誤表とダウンロードしかないためこちらで質問させていただきます。 下記のコードの下から二行目の構造体へのポインタ (Car *) について、中学生に説明するように基本的な考え方、目的、書式、参考URLなどを教えて下さい。 ポインタについては、該当の章を読み直し基本事項については理解しておりますが、突然あるページから(Void *)や(Char *)など括弧で閉じるものが説明なしに出てきてちょっと混乱してます。(汗 どうぞ宜しくお願い致します。 #include<stdio.h> /* 構造体型struct Carの宣言 */ typedef struct Car{ int num; double gas; }Car; int main(void) { printf("int型のサイズは%dバイトです。¥n", sizeof(int)); printf("double型サイズは%dバイトです。¥n", sizeof(double)); printf("構造体structCar型のサイズは%dバイトです。¥n", sizeof(Car)); printf("構造体struct Car型へのポインタのサイズは%dバイトです。¥n", sizeof(Car *)); return 0; }

  • ポインタの勉強中なのですが

    C言語の勉強中なのですが、ポインタのところで苦労しています。 次のような関数を作成し、main関数で実行したところ、sizeof(array)は4になりました。 main関数内で同じようにsizeof(array)を表させると配列全体のサイズが表示されますよね。 関数の仮引数として配列を書いても、実際には配列の先頭要素を指すポインタとして扱われるので 関数には&array[0]が渡され、関数は配列ひとつあたりのサイズを基に他の配列の要素のアドレスを 受け取るで合ってますよね? でもmain関数内ではsizeof(array)は配列全体のサイズを返すのに、関数内では配列ひとつあたりのサイズしか返さないのはどうしてなのでしょうか? int sum_array( int array[], int num ){ int i; int sum = 0; for( i = 0; i < num; i++ ){ sum += *(array+i); } printf("sum = %d\nsizeof(array)=%d\n",sum,sizeof(array)); return sum; }

専門家に質問してみよう