Macでのポインタの扱いについて

このQ&Aのポイント
  • Macでのポインタの扱いについて質問があります。C言語の勉強をしている中で、ポインタの扱いで問題が発生しています。
  • 具体的には、変数のアドレスを表示するプログラムを書いた際にMacでコンパイルするとエラーが発生します。
  • Windows環境では問題なく動作するのですが、Mac環境との違いが原因なのかわかりません。ポインタの表記方法について教えていただけないでしょうか?
回答を見る
  • ベストアンサー

macでのポインタの扱いについて

最近macを使ってc言語の勉強をしています。 ポインタの所でどうしてもつまづいて解決できないことがあるため質問させていただきました。 ある変数のアドレスを表示するのに main(){ int d=5; printf("dのアドレス:%d 値:%d\n",&d,d); return 0; } のようなプログラムを書いたときにMacでコンパイルすると なぜか以下のようなエラーがでてしまいます $ gcc test.c -o test.out test.c: In function ‘main’: test.c:8: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’ まったく同じソースをWindows上でBorlandを使ってコンパイルしてみると 問題ありません。 Mac環境とWindows環境ではポインタ指定の表記が違うのかと思ったのですが 調べてみてもよくわかりません。 もしわかる方がいらっしゃいましたらご教授願えないでしょうか?

  • dfret
  • お礼率13% (2/15)

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「Mac か Windows か」ではなく, コンパイラだけの話. gcc は printf や scanf などの関数で書式文字列が文字列リテラルで与えられた場合, その他の引数と比較して書式が適切かどうかをチェックします. 「gcc なら」チェックするので, gcc を使いさえすれば Windows 上でも同じように突っ込まれます.

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

long long に対する書式は %qi ではなく %lli としてほしかった>#3.

  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.3

No.1の方の回答にしたがって、ポインタ値を取得し、かつ「sizeof(int)」で、int型のサイズを調べてください。 そうすると、ポインタ値のサイズが、int型のサイズより大きいことがわかります。64ビットOS上では、かならずしもポインタ値がintではなく、long longなのかもしれません。 もうひとつ、ポインタ値を出力するには、代入するのは「%p」でなければいけません。まあ、そういうきまりですね。16進数でなく、10進数で出力したいのでしたら、ポインタ値をlong longにキャストしてやればいいでしょう。 printf("dのアドレス:%d 値:%d\n",&d,d); → printf("dのアドレス:%qi 値:%d\n",(long long)&d,d);

回答No.1

> printf("dのアドレス:%d 値:%d\n",&d,d); ポインタの値を%dで表示しようとすると、intとサイズが違う場合に問題が出ます。 %pを使うべきでしょう。 そういった意味で、warningが出ているものと考えます。 > まったく同じソースをWindows上でBorlandを使ってコンパイルしてみると > 問題ありません。 コンパイラが書式指定文字列と引数の型をチェックしていないだけでしょう。

関連するQ&A

  • printf()関数の括弧を二重にして、printf((~~~))とし

    printf()関数の括弧を二重にして、printf((~~~))として コンパイル/実行すると、実行時セグメンテーション違反が発生します。 コンパイル時には警告も発生しますが、このセグメンテーション違反が なぜ起こるのか理由がよくわかりません。ご回答いただけるとありがたいです。 以下、サンプルコードと実行例です。よろしくお願いいたします。 ---mytest.c---- 1 #include <stdio.h> 2 3 int main(void){ 4 5 //printf("test:%d", 1)ではもちろんコンパイル/実行に成功する。 6 printf(("test:%d", 1)); 7 return 0; 8 } 【コンパイル/実行結果/gccバージョン】 #gcc main.c main.c:6:警告:passing argument 1 of printf makes pointer from integer without a cast #./a.out セグメンテーション違反です # gcc --version gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27) ・ ・

  • プログラミングについてです。

    単純なかけ算を利用したプログラムなんですが、エラーコードが出てきてしまって、全然デバックできません。 わかる方、どこがどういうふうに間違っているか、ご教授お願いします。 使っているPCはMacBook Proです。 #include <stdio.h> int main( void ) { int go, hachi, goukei, azukari, otsuri ; printf("五十円切手の枚数と八十円切手の枚数を入力してください。(例 10,4):") ; scanf("%d,%d", go, hachi) ; goukei = go * 50 + hachi * 80 ; printf("合計金額は%dです、いくら支払いますか?:",goukei) ; scanf("%d 円",azukari) ; otsuri = azukari - goukei ; printf("ありがとうございました、おつりは %d 円です。",otsuri) ; return 0 ; } エラー内容 q2_5.c: In function ‘main’: q2_5.c:8: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’ q2_5.c:8: warning: format ‘%d’ expects type ‘int *’, but argument 3 has type ‘int’ q2_5.c:8: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’ q2_5.c:8: warning: format ‘%d’ expects type ‘int *’, but argument 3 has type ‘int’ q2_5.c:11: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’ q2_5.c:11: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’ です。お願いします。

  • (Mac) sizeof演算子のコンパイル

    現在MacBookAirにて入門書を参考にC言語を学んでいます。 その中で、 #include <stdio.h> int main(void) { int a = 1; printf("short int型のサイズは%dバイトです。\n", sizeof(short int)); printf("変数aのサイズは%dバイトです。\n", sizeof(a)); return 0; } と入力しコンパイルすると sample21.c:7: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’ sample21.c:8: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’ と表示されコンパイルすることができません。 なんども見直してコードに間違いはないと思いますが、原因が解りません。 他のコードは問題なくコンパイルできます。 この先、sizeof演算子を使って値を求めなければならない章があり、非常に困っています。 どなたか解決策を教えてください。お願いします。

  • incompatible pointer type

    incompatible pointer type への対応方法を教えてください。 環境はMicrochipのXC16 Compiler V1.24です。 エラーの出る行は putsUART1("UART1 Test"); エラーは main.c:76:9: warning: passing argument 1 of 'putsUART1' from incompatible pointer type c:\program files (x86)\microchip\xc16\v1.24\bin\bin\../..\support\peripheral_24F/uart.h:396:45: note: expected 'unsigned int *' but argument is of type 'char *' となっています。 uart.hを見ると void __attribute__ ((section (".libperi"))) putsUART1(unsigned int *buffer); とあるので、求められているものと違う形のものを渡してしまっていることは分かります。 ところが、具体的にどう変更すればいいのかわかりません。 プログラムをどのように書き直したらエラーを無くすことが出来ますか? よろしくお願いします。

  • cygwinのgccで正常にコンパイルできない。

    cygwinのgccで正常にコンパイルできない。 cygwinのvimで、以下のプログラムを書きました。 ------------------------------------------------------------- #include <stdio.h> int main(void) { int no; printf("Please input something:"); scanf("%d", &no); printf("It is %d that you input it:\n", no); return (0); } ------------------------------------------------------------- それからgccでコンパイルしました。 コマンドは以下の通りです。 $ gcc test.c すると以下のエラーが出ました。 test.c:10:9: warning: unknown escape sequence: '\033' このようにコンパイルできない状態です。 どのようにすると正常にコンパイルできるようになるでしょうか?

  • 2次元配列とポインタの引数受け渡しについて

    2次元配列を関数に渡すときは、引数に渡す2次元配列と同じサイズを指定、もしくは2次元目のサイズのみ合わせて渡す方法がありますが、両方とも違うサイズで同じ関数を使いたいです。 最初は中身が同じで引数で受け取る2次元配列のサイズだけ、それぞれに合わせた引数を持つ関数を2つ作っていたのですが、なんだか冗長な気がしました。 そこで、2次元配列の先頭ポインタとサイズを受け取るようにすればいいのかと思い、テストとして次のプログラムを作成してみました。 #include <stdio.h> void func(unsigned char *a, int y, int x); int main(void) { unsigned char a[10][10]; func(a, 10, 10); printf("%d\n", a[7][4]); return 0; } void func(unsigned char *a, int y, int x) { int i, j; for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { *(a + i*y + j) = i * j; } } } もちろんこれでも動くのですが、やはりこういう書き方はルールにはないので、コンパイルで警告が出ます。 a.c: In function ‘main’: a.c:10: warning: passing argument 1 of ‘func’ from incompatible pointer type a.c:4: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[10]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • C言語のポインタについて教えてください。

    C言語のポインタについて教えてください。 ・pointer1.c  int main(){   int a;   int *p;   p = &a;     a = 123;   printf("%d", *p);   return 0;  } ・pointer2.c   int main(){ int a[100]; int *p; p = &a[0]; int i; for(i = 0; i < 100; i++) a[i] = i; for(i = 0; i < 100; i++) printf("%d", *p++); return 0; } と二つのソースコードがあるとき、pointer2.cの「p = &a[0]」をpointer1.cのように「p = &a」と書けないのはなぜですか?  また、「&a」は動かすことのできなく、「aを指し示す*p」は動かすことができる変数のようなもの、という認識に誤りはないでしょうか?  宜しくお願いします。

  • 警告をださずにポインタにnullを渡す方法は?

    こんにちは。 ポインタ型の引数にNULLを渡してやりたいのですが 以下のような警告がでてしまいます。 test.c: In function 'test_': test.c:14: 警告: passing argument 2 of 'test' makes pointer from integer without a cast 問題の箇所は以下のように書いてます。 【test.c】 ~省略~ /** プロトタイプ **/ 7 void aaa(int,int*,int*); ~省略~ 14 aaa(0,NULL,&tv); NULLを渡したい場合、警告をださないように スマートに記述するにはどうしたらいいでしょうか? よろしくお願いします。

  • ポインタ定義は必要なんですか?

    #include <stdio.h> int main( void ) { int x; int *p; p = &x; printf("Address = %p\t\n", p ); return 0; } を #include <stdio.h> int main( void ) { int x; int p;←ここを上とはかえた p = &x; printf("Address = %p\t\n", p ); return 0; } にしたところコンパイル時に p = &x に関して 移植性のないポインタ変換と表記されますが 結果は同じだったのでポインタ定義というのは結局必要なんですか? 移植性のないポインタ変換とはなんなんですか? よければ詳しく教えてください

  • NSString文字列をprintfで出力するには

    Objective-CでNSStringクラスの文字列をprintf関数で出力しようとするとコンパイルエラーになります。 どうすればprintfで出力できるようになるでしょうか。 実行環境はMacOSX。Xcodeをインストールしています。 ソースコードとエラーメッセージは以下です。 #import <Foundation/NSObject.h> #import <stdio.h> int main(void){ NSString *str01 = @"test"; printf("%s\n", [str01 UTF8String]); return 0; } <コンパイルエラーメッセージ> warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘id’

専門家に質問してみよう