• ベストアンサー

UnixでC言語を学習中(初心者です)。

こんにちは。C言語の学習を始めたばかりの社会人です。 下記のソースコードを実行すると、 「009e 10  00a2 35 00a6 25 00aa 67 00ae 88 00b2 29」 というイメージ表示されるはずなのですが、アドレスが別な値になるのは仕方ないとして、アドレスを4桁で表示しようとしても7桁くらいで表示されてしまいます。Unixサーバを使用しています。 どうすればよろしいでしょうか? ご回答頂ければありがたいです。 #include<stdio.h> int main() { static long a[]={10L,35L,25L,67L,88L,29L,-999L}; long *pa; pa=a; while(*pa!=-999L){ printf("%04x %ld\n",pa,*pa); pa++; } printf("\n"); return 0; }

  • DT50
  • お礼率95% (504/530)

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★アドレスをとにかく4桁で表示したいのですか? ・それならば、アドレスを一度 int 型の整数値にキャストしてから 16進 4桁に AND するのが基本です。 ・方法は既に tatsu99 さん、tea_sheep さんが回答を出していますので、printf 関数の書式文字列に  ついて少しアドバイスします。 ・通常アドレスを表示する書式制御は『%p』です。→tea_sheep さんの助言どおりですね。 ・それで、『%X』や『%x』を使って 16進 4桁にするには精度を指定すればよいのです。  つまり、『%04X』を『%04.4X』とピリオドと最大桁数を指定します。  これで、『pa』を unsigned long や unsigned short などにキャストするだけですみます。 方法1: printf( "%04.4x %ld\n", (unsigned int)pa, *pa ); 方法2: printf( "%04x %ld\n", (unsigned short)pa, *pa ); 方法3: printf( "%04x %ld\n", ((unsigned int)pa & 0xFFFF), *pa ); 最後に: ・コンパイラの int 幅が 64 ビット長の場合は (unsigned int) を (__w64) とキャストして下さい。  つまり、  方法1:printf( "%04.4x %ld\n", (__w64)pa, *pa );  方法2:printf( "%04x %ld\n", (unsigned short)(__w64)pa, *pa );  方法3:printf( "%04x %ld\n", ((__w64)pa & 0xFFFF), *pa );  となります。 ・なお、(__w64)は、私の使っているコンパイラの定義でのお話ですのでお使いのコンパイラの 64 ビット  整数のキャスト演算子を指定します。→Windows.h ヘッダを include していると (INT64) でもキャスト  可能ですが、質問者さんは Unix の OS ですか。 ・まぁ、とにかく整数型へキャストしてから桁数を丸め込んで表示するのが基本の考えです。 ・以上。おわり。

DT50
質問者

お礼

ご回答ありがとうございます。 いろいろとお教えいただき、ありがとうございました。

その他の回答 (3)

  • tea_sheep
  • ベストアンサー率53% (8/15)
回答No.3

通常、printf系の関数でアドレスを表示させるときは %p を使います printf("%p %ld\n",pa,*pa); 特定の型で表現可能な範囲まで削るにはキャストすることになります。 printf("%04hX %ld\n", (unsigned short)pa, *pa); printf("%08lX %ld\n", (unsigned long)pa, *pa);

DT50
質問者

お礼

ご回答ありがとうございます。 >通常、printf系の関数でアドレスを表示させるときは %p を使います 勉強してまもないので、知りませんでした。ありがとうございました。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

>ところでアドレスの件ですが、テキストの問題でアドレスを削るようにしているのです。Windowsだと正常に動作するのですが、テキスト通りに実行させるにはどうしたらいいでしょうか? 強引にアドレスをけずるには、以下のようにします。 printf("%04x %ld\n",pa,*pa); を printf("%04x %ld\n",(0xffff & (int)pa),*pa); のようにします。 ポインター paを強引にint型の変数にして、0xffffでアンドをとります。 これで、下位2バイトだけが、そのままで、上位の2バイトが0になります。そして、下位2バイトの値だけが、表示されるようになります。

DT50
質問者

お礼

なるほどぉ。 ご回答ありがとうございました。

  • dekopa-
  • ベストアンサー率42% (161/378)
回答No.1

アドレスの桁数は、そのハードウェアによって異なります。 8bitなら16進数で2桁、以後16bit, 32bit, 64bitと増えるごとに倍になります。 7桁なら、32bitか64bitマシンで、上位の0が削られたのでしょう。 無理やり4桁に削ってもよいのですが、それは正しくないアドレスですよ?「そんなものだ」と納得してください。

DT50
質問者

お礼

ご回答ありがとうございます。 >7桁なら、32bitか64bitマシンで、上位の0が削られたのでしょう。 なるほど。そういう理由なんですね。わかりました。 ところでアドレスの件ですが、テキストの問題でアドレスを削るようにしているのです。Windowsだと正常に動作するのですが、テキスト通りに実行させるにはどうしたらいいでしょうか?

関連するQ&A

  • c言語超初心者です。2

    #include <stdio.h> int main(void) { int na,nb, nc; int sum; double ave; puts("三つの整数を入力してください."); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); printf("整数C:"); scanf("%d", &nc); sum=na+nb+nc; ave=(double)sum/3; printf("それらの合計は%5dです。\n", sum); printf("それらの平均は%5.1fです。\n",ave); return(0); } とういうのを作ったんですが、最後のそれらの合計は%5dとやりその5の意味は整数を10進法で少なくても5桁で表示とありますが、例えば1,2,3と入力しても合計は6とでて5桁ででないんですけど。そういう意味ではありませんか?あとave=(double)sum/3;のところをave=sum/3.0としても問題なくできるのですが、どっちでやったほうがいいとかはありますか?もしあったらその理由も教えてください。

  • C言語

    【プログラム】 #include<stdio.h> int main (void) { int i,n; long a; scanf("%d",&n); a=1; for(i=1;i<=n;i++){ printf("%3d回目 %12ld\n",i,a); a=a*2; } return 0; 【実行結果】("33"と入力) 33 1回目      1 2回目      2 3回目      4 4回目      8  :        :  :        : 31回目 1073741824 32回目 -2147483648 33回目      0 【質問】 2倍していくと、32回目に負の数になり さらに33回目には0になりました。 こうなる理由を教えてください。 私は高2です。 出来ればわかりやすくお願いします。

  • C言語初心者です。

    #include <stdio.h> int main() { int b[100]; int i, n; int a, r, data; int count=0; printf("Please input two integers:"); fflush(0); scanf("%d %d", &a, &r); if(a<=0 || r<=1){ printf("Error\n"); } else{ for(n=0; b[n]<=80.0; n++){ if(n==0){ b[0]=0; count++; } else { for(i=0; i<=n-1; i++){ data*=r; } b[n]=a*data; printf("%d ", b[n]); count++; } } printf("\n"); for(; count>0; count--){ printf("%d ", b[count]); } } return 0; } windows8でeclipseを使ってC言語を書いてます。 eclipse上だと何もエラーが表示されてないのですが、実行し、 Please input two integers: と表示された後、適当な数字2つを入力しても何も反応しません。 稚拙な質問ですいません。どなたか原因を教えてください。

  • C言語の初心者です。これを実行してみてください。

    「a」って打ち込んだら「a」ってでましたか? #include<stdio.h> int main(void){ char a; printf("aaa\n"); scanf_s("%c", &a); printf("%c", a); return 0; }

  • c言語で

    c言語で /*a==bのとき商と余を求めるそれ以外は積を求める*/ # include<stdio.h> main () { int a,b,seki,sho,joyo; printf("aとbを入力してください\n"); scanf("%d %d", &a,&b); if(a==b) printf("sho=%d\n",(a/b)); printf("joyo=%d\n",(a%b)); else printf("seki=%d\n",(a*b)); return(0); } はどこがおかしいでしょうか? あと /*小数点*/ # include<stdio,h> main () { float a,b,seki,sho,joyo; printf("%f %f",&a,&b); if(a>b) printf("sho=%f4.3\n",(a/b)); printf("joyo=%f4.3\n",(a%b)); else printf("seki=%f4.3\n",(a*b)); return (0) にいたってはエラーの嵐なのですがどうすればいいでしょうか

  • C言語

    #include <stdio.h> int main(void) { int a=0,ans1,ans2,ans3,ans4; printf("整数を入力してください。\n"); scanf("%d",a); ans1 = a+7; ans2 = a*;8 ans3 = a%3; ans4 = a*(-1); printf("%d\n",ans1); printf("%d\n",ans2); printf("%d\n",ans3); if(a==15){ prntf("true\n",a); } else{ printf("false\n",a); } if(a != 8){ printf("true\n",a); } else{ printf("false\n",a); } if(a <= 3){ printf("true\n",a); } else{ printf("false\n",a); } printf("%d\n",ans4); if(a<2||7<a){ printf("true\n",a); } else{ printf("false\n",a); } return 0; } これを実行しようとしてもexeファイルになりません。 教えていただけませんか?

  • C言語の質問です。

    #include"stdio.h" int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = a+b; printf("add=%d\n", add); return 0; } と、------------------------------------------------------------------------------ #include"stdio.h" int tasizan(int x, int y); int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = tasizan(a, b); printf("add=%d\n", add); return 0; } int tasizan(int x, int y){ int aa; aa = x + y; return aa; } の違いを教えてください。

  • C言語の初心者です。

    ポインタについて教えてください。 #include <stdio.h> int main() { int *p,a[2],i=0; p=a; scanf("%d",p); printf("%d\n",*p); i++; scanf("%d",p+i); printf("%d\n",*(p+i)); return 0; } これは整数を入力して出力といった簡単なプログラムなのですが、こういうポインタの使いかたって普通はしないでしょうか・・?。ポインタは使わずにこういう場合は2次元配列とかで出すのが普通なのでしょうか? また、下のプログラムなのですが、上記のプログラムをただ単にキャラ型で試しただけなのですが、どうして実行時エラーがおこってしまうのでしょうか? printfのところの*nameの、*を抜くと実行時エラーはおこりません。しかし、上記の整数では*はつけたままでも エラーしません。 整数とキャラ型では何かちがうのでしょうか?? #include <stdio.h> int main() { char *name,a[10]; name=a; printf("入力---"); gets(name); printf("%s\n",*name); return 0; } 初心者特有の質問をしてしまって申しわけございません。でも、ずっと悩んでて、すこしずつでもポインタの本当の使いかたを知りたいとおもいまして、初期段階ではありますがどうしても解らなかったので質問させていただきました。 そういうものだから!以外でご説明いただける方がいらっしゃいましたら宜しくお願いいたします。

  • c言語なのですが

    c言語なのですが #include<stdio.h> main() { int a; printf("整数を5回足し算する\n"); scanf("%d %d",&a); printf("a*5=%d\n",a*5); return(0); } でエラーが起こります どこを修正すればいいのでしょうか

  • 素数表

    #include<stdio.h> void main(void) {long i,a; void primeout(long); printf("月 火 水 木 金 土 日\n何日まで?"); scanf("%ld",&a); primeout(1); for(i=2;i<=N;i++) {primeout(i) } } void primeout(long p) {static long t=1 printf("%6ld",p); if((t%7)==0)printf("\n"); t++;} primeout関数を利用して、7月のカレンダーを出力するプログラムを作成するのですが、間違っているところを訂正お願します(TへT)ノ

専門家に質問してみよう