- ベストアンサー
void*にキャストするのがナンセンス?
以下のような関数シグネチャがあったとして、 void func(void* v); この関数をコールするときに、以下のようにするのは 笑える行為だと書かれた本がありました。 int i = 0; func((void*)i); これは何がまずいのでしょうか? 本にはその説明がありませんでした。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
関連するQ&A
- 「void ( *signal(int sig, void (*func)(int)) ) (int)」の (int)
signal関数の書式についてですが、 void ( *signal(int sig, void (*func)(int)) ) (int); 最後に付く(int)は一体何でしょうか? このような関数の書式ははじめて見ました。 UNIX系の何かでしょうか。 回答よろしくお願いします。
- ベストアンサー
- C・C++・C#
- 関数の引数をvoid*でキャストする
最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。
- ベストアンサー
- C・C++・C#
- (void *)と&の違い
#include<stdio.h> void * func(void *p){ printf("□■□func開始□■□\n"); printf("pのアドレス = %p\n",p); printf("p = %d\n",(int)p); (int)p += 100; printf("p = %d\n",(int)p); printf("□■□func開始□■□\n"); return NULL; } int main(void){ int number = 30; printf("numberのアドレス = %p\n",&number); func((void *)number);★1 return 0; } -------------------------------------------------------------- #include<stdio.h> void * func(int *p){ printf("□■□func開始□■□\n"); printf("pのアドレス = %p\n",p); printf("p = %d\n",*p); *p += 100; printf("p = %d\n",*p); printf("□■□func開始□■□\n"); return NULL; } int main(void){ int number = 30; printf("numberのアドレス = %p\n",&number); func(&number);★2 return 0; } 上記の2つは同じ結果になるのですが★1と★2のそれぞれの違いがわかりません。どなたかご教授をお願いします。
- ベストアンサー
- C・C++・C#
- int main(void)
C言語の問題集をやっているのですが、 本にはmain関数の最初にint main(void)のような書き方が してあります。 学校ではmain() と習ったのですが、本には上のようにかいてあります。 どのように違うのでしょうか? というかmain関数のところに引数が入っている意味がわかりません。 どういうことがというと(void)ってなんですか? またint mainというのはint型の関数だと思うのですが、 なかではdouble型とかも使えます。 お願いします。
- ベストアンサー
- C・C++・C#
- int main()、void main()、void main(void)、int main(void)
今日、大学でC言語の講義の時間、先生が、 #include <stdio.h> void main(void){ } と宣言してプログラムを書くと教えていました。 main関数には、 main() void main() void main( void ) int main() int main( void ) と、人によりいくつかの描き方があったりします。 どれが本当は正しいのでしょうか? void mainはすべきではないとなんかの本で読んだのですが・・。
- ベストアンサー
- C・C++・C#
- 教えてポインタ
例えば、以下のようなソース。 関数の中で、引数のポインタに値を入れてmainに戻す。 とても簡単なものです。 void func(int *N) { *N=0; } main { int *N=1; func(N); printf("%d",*N) } 疑問は、ここからです。 (1)void func(int *N) (2)void func(int* N) (3)void func(int* &N) 上記は、何が違いますか? なお、当方のVS2010で同じソースを作ると、 (1)の場合、エラーになります。(func関数の*N=0のところでダウン) (2)だと、OKになります。 (3)は、なに?
- ベストアンサー
- C・C++・C#
- プログラムがわかりません
C言語の本を読んでいるんですが、詰まってしまいました。プログラム自体は単純なのですが #include<stdio.h> void hello(void) { fprintf(stderr,"hello!\n"); } void func(void) { void *buf[10]; static int i; for(i=0;i<10;i++) { buf[i] = hello; } } int main(void) { int buf[100]; func(); return 0; } のスタックオーバーフローのプログラムです。 1. 要素100のint型配列を宣言 2. 関数funcの呼び出し 3. void *buf[10]; まずここでがわかりません。なぜポインタが でてきたのか?またbufの要素数は100では? 4. buf[i] = hello; のループ これもわかりません。配列に関数を代入しているのでしょうか? 5. fprintf(stderr,"hello!\n"); これもまたわかりません。 fprintfの最初の引数は出力先ですが、なぜ標準エラー出力なの でしょうか? 時間のあるかた解説お願いします。
- ベストアンサー
- C・C++・C#
- signal関数の使い方
標準関数のsignal()関数についてですが void (*signal(int sig, void (*func)(int)))(int); 関数の形式からしてよくわかりません。 僕のイメージでは関数のポインタというと void (*func)(int,int) という感じですが上の場合 void (*func(int,int))(int) /*引数は仮にint型*/ という形式になってますよね。末尾の(int)は引数のはずですがどこの引数になっているのかよくわかりません。 しかも関数の使用例などをみると signal(SIGINT, func); という形で使っており末尾の(int)がどこにいったのかさっぱりわかりません。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- extern指定子の使い方
こんにちは。 現在WindowsVistaでCプログラミングを行っています。 独習Cという本に沿って勉強しているのですが、extern指定子の使い方の所でつまずきました。 まず、サンプルプログラムを参照し、以下のような2つのファイルを作成しました。 (必要なヘッダファイルは全てインクルードしています。) ●main.c ____________________________________________________________ extern int random; void func(void); void main(void) { int i; for(i=1; i<=10; i++){ func(); printf("発生した乱数 : %d\n", random); } } ____________________________________________________________ ●func.c ____________________________________________________________ int random; void func(void) { long ltime; long utime; /*まず、time()関数とsrand()関数を使って乱数列の初期値を 毎回変更できるようにする*/ ltime=time(NULL); utime=(unsigned int)ltime/2; srand(utime); //乱数を発生させてrandomに代入する random=rand(); } ____________________________________________________________ この2つのファイルをコンパイルし、実行した所同じ整数が10個表示されました。 異なる整数を10個表示したいのですが、どうすればよいかが分からず困っています。 何か分かる方がいらっしゃれば、アドバイスをお願い致します。
- ベストアンサー
- C・C++・C#
- 暗黙のキャストを自動検出
C++には暗黙のキャストがあります。 例えば、下記の例のようにint型(4バイト)の引数を取る関数short型(2バイト)の引数を与えて呼び出した場合。 ------------------- void func(int i) { //... } int main() { short s = 1; func(s); // short->intに暗黙のキャスト } このコードは正常にコンパイルすることができ、かついかなる警告レベルでも警告は表示されません。(VS環境) データ欠損やオーバーフローの可能性はなく、安全なキャストであることが保障されているからです。(short型の取り得る値の全てがint型の散り得る範囲に収まる) このような「暗黙のキャスト」を行っている箇所を自動的に検出する方法はあるでしょうか? 暗黙ではない(危険な)キャストはIDEにより警告が出ることは分かっています。 Visual Studiioの機能、または外部ツールを使用する方法でも構いません。あるいは、この目的のためにダミーを作成するようなやり方でも構いません。 funcを使用している箇所は膨大ですがfuncの数は限られていますので、この目的のために仮の関数を定義してコンパイルしてみることは可能です。 一応考えてみた方法は、下記のような検出用の関数を追加することです。 ------ 暗黙のキャスト検出用オーバーロード関数 ------- void func(short i) // 必要に応じてchar型や byte型をとるオーバーロード関数も作成 { // この関数が呼ばれたら暗黙のキャスト! cout << "関数" << __FUNCTION__ << "で暗黙のキャスト(int->short)が行われました。">>"\n"; // 続きの処理を継続するため、本当の関数を呼んでおく func((int)i); // ここは明示的にキャストしないと自分自身を呼んでしまう } ただこの方法ではコンパイル時に検出できず、実際に全ての関数呼び出しが実行されるようにプログラムを動かす必要があります。 また、検出用関数も暗黙のキャストのパターン数分用意する必要があります。目視で全ソースチェックするのとあまりコストが変わらないような気がします。 主に関数の引数として渡されるデータ型が仮引数にコピーされる際にキャストされる場面を検出したいのですが、関数の戻り値を別の変数に代入している場面も検出できればなお良いです。 なぜこのようなことが必要かと思われるかもしれませんが、暗黙のキャストそのものが問題ではなく、そうした箇所に別の問題が潜んでいる可能性があり、それを調べたいのです。 こうした場面がソース中に大量にあると想定されるため、漏れなく機械的に検出する方法があればと思い質問しました。
- ベストアンサー
- C・C++・C#
お礼
詳細な解説ありがとうございます。 とても理解が深まりました。