• ベストアンサー

関数宣言で引数に(void)というのと()の違い

今、Atmega88をAVR Studio4 + WINAVRでC言語プログラミングを行っているのですが、 void bridge_master_oper() { ----(中略)------------- } このように宣言された関数があります。 void bridge_master_oper(void) { ----(中略)------------- } このような引数に”void”として宣言している場合と何か違いはあるのでしょうか?

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

> この”gClient”というのはグローバルの構造体変数として宣言している者なのですが、特に引数で渡す必要はないと思うのですが、なぜこのようにしているのかわかりましたら教えて頂けませんでしょうか? いくつか思いつくものはありますが、正確にはわかりません。 グローバル変数と言えど、名前がグローバルに使える、というだけの変数なので、引数で渡しても問題ありません。 ・bridge_master_operがもともと引数で構造体を受け取るように実装されている。 グローバル変数を直接操作するように作られていない ・なんらかの理由でローカル変数として宣言できないのでグローバル変数にしている。 組込み系では、いろいろ制限があるので、こちらの理由かもしれません。

diy_sunny
質問者

お礼

回答頂きありがとうございます。ここら辺の内容とか、”C:\WinAVR-20100110\doc” このパスにあるWINAVRとかのマニュアルとかに載ってたりしますでしょうか? もし詳しかったら教えて頂けますでしょうか?

diy_sunny
質問者

補足

お世話になっております。 現在Atmega88で作っているプログラムで、プログラム動作中に勝手に意図しないウォッチドックタイムアウトが発生するような暴走のような症状が出ていていろいろとプログラムを変えてみたりして改善してみたのですが、最初は今回のプログラムの書き方の問題かなと思っていたのですが、別のところを変更して改善されました。 今回は助かりました。ありがとうございます。 http://sourceforge.jp/projects/cc1101driver/svn/view/branches/C1101_source_ATmega88_bridge_ver0x17/?root=cc1101driver

その他の回答 (2)

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

「定義 (自動的に宣言でもある)」と「(定義でない) 宣言」とでは状況が異なるのですが, どちらを意図していますか? 宣言なら #1 の通り, 定義ならどちらでも同じ.

diy_sunny
質問者

お礼

回答頂きありがとうございます。すみません、プログラム初心者なもので、言葉の使い方がなっていなくて誠に申し訳ありません。 たぶん#1の意味です。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

純粋にC言語の場合。 引数voidの場合は「引数を一つもとらない」という宣言になります。 void bridge_master_oper(void) と宣言されたら、使うときは bridge_master_oper() だけがOKです。 bridge_master_oper(10) 等とするとエラーになります。 引数無しの場合は「任意の引数を取る」という宣言になります。 void bridge_master_oper() と宣言されたら、使うときは bridge_master_oper() bridge_master_oper(10) どちらも文法上はエラーではありません。(期待された動きをするかどうか、は別の問題) void bridge_master_oper(...) と同義になります。 C++だとこの違いはなく、どちらも「引数無し」の意味です。

diy_sunny
質問者

お礼

回答頂きありがとうございます。詳細も説明して頂きありがとうございました。

diy_sunny
質問者

補足

現在解析を行っているプログラムで”void bridge_master_oper()”というようにこの関数が宣言されています。 その際に、この関数を呼び出す際に bridge_master_oper((cc1101_client *)&gClient); このようなプログラムの書き方をしています。 この”gClient”というのはグローバルの構造体変数として宣言している者なのですが、特に引数で渡す必要はないと思うのですが、なぜこのようにしているのかわかりましたら教えて頂けませんでしょうか?

関連するQ&A

  • AVR Studio 5へ移行可能?

    今まで、ATmega88のC言語プログラムをAVR Studio4.18 + WINAVRで書いていたのですが、AVR Studio5が登場してきて、今まで作った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++ではありません。

  • 関数の仮引数は宣言か式か

    ”関数の仮引数の宣言”は”変数の宣言・定義”と同じように”宣言”と明確に考えるべきなのか”関数の仮引数”を”式”と考えて良いのかという問題です。 私が迷ってしまったのは"配列を仮引数"にとった例です。 規則として ”int a[ ] が int *a と同じ意味になるのは、唯一、関数の仮引数の宣言のばあいだけである”という規則がありますが、これは”関数の仮引数の宣言”は変数の宣言・定義”と同じように”宣言”と明確に考えている例だとおもいます。 int a[ ] が int *a と型名 変数名(引数名)と宣言の形をとっているので当然だと思いますが、一方 配列は、式の中で「先頭へのポインタ」によみかえられる。               ↓ 関数の引数は式なので、配列は「先頭へのポインタ」に読み変えられる←引数部分を”宣言”ではなく”式”と捉えてる←ここが私の迷っているところ               ↓ よって、関数に渡ってくるのは、結局はつねにポインタだ。 という説明もあります。 私の今までの理解ではc言語では”宣言の部分”と”式”の部分は明確に区別されるものと考えていました。”宣言部分の初期化の="と”代入の=”とは明確に区別されていました。 それと同じように”関数の仮引数の宣言”は”宣言部分”と捕らえるのか”式”ととらえるのか ”宣言”と”式”が私の頭の中混乱しています。 宜しくお願いします。

  • プロトタイプ宣言について

    C言語で関数を作成しプロトタイプ宣言するときの質問です。 関数実体の引数に構造体のポインタを宣言します。 プロトタイプ宣言には,構造体のポインタを宣言したのと同じ位置にvoid *を宣言します。 関数実体とプロトタイプ宣言は,異なるファイルです。 このように作成した関数は,VC++2008では,コンパイルできるのですが, なぜ関数実体の宣言とプロトタイプ宣言の型が異なるのにコンパイルできるのでしょうか? また,この関数を別ファイルの関数から呼び出した場合,正しく引数を理解し,正しく処理されます。 これは,言語仕様として正しい書き方なのでしょうか? それとも環境依存の書き方なのでしょうか? ご存知の方がいましたらお答えお待ちしています。

  • スイッチでサーボ制御

    AVRのATmega168とサーボモータの GWServo S03T 2BBMG を買ってWinAVRでプログラミングしようと思っています。とりあえず動かしたいと思っているので、スイッチを押したら90度曲がり、スイッチを離したら90度戻るというプログラムを書きたいです。どなたか簡単で良いので教えてください。よろしくお願いします。

  • 関数の実引数と仮引数の扱いがわかりません

    プログラミング初学のものです。 関数の実引数と仮引数の扱いが、 今一つわかりません。 どっちにどう表記するのか、はっきり理解しておりません。 どうやって理解すればよいのでしょうか。 ちなみに、扱っているはC言語です。 ご経験者の方、どうぞよろしくお願いします。

  • 関数と引数の関係とは?

    只今ゼロからプログラミングの勉強をしています。 言語はC言語を習得したいと思ってます。 (将来的にはJavaも!) す~っごく初歩的な質問で申し訳ないんですが 関数とは何でしょうか? 引数とは何でしょうか? またその関係について、非常にわかりやすく 簡単に教えていただけないでしょうか? よろしくお願いします。

  • 関数と命令の違いについて

    プログラミング言語の関数と命令の違いについてなのですが、 関数は返り値があるもの、命令は返り値が無いもの。 とどこかで読んだ覚えがあるのですが、 いくつかのプログラミング言語を使っているとそうは思わないときがあります。 (voidの関数のように、何も返さない関数もあると思います。) 検索して調べてみると、例えば、 HSPなどでは命令と関数が明確に区別されていますが、 なでしこでは曖昧のように思います。 (なでしこの場合、標準の機能は、どれも命令と呼ばれていますが、命令のくせに普通に値を返します。) しかし、もし、先述の通りだとすると、 何故、わざわざ区別する必要があるのでしょうか? すべて、関数にしてしまっても良いと思うのですが? また先述の、命令と関数の違いがそもそも間違っているのであれば、 正しい違いを教えていただけるとありがたいです。

  • ポインター引数の関数でコンパイルエラーが出る。

    現在ATmega88というアトメル社製のマイコンのプログラミングを行っています。コンパイラはwin_avrを使用しています。 現在void tx_test(cc1101_client * client)というcc1101_clientポインターを引数とした関数を作成したのですが、この関数内でu16 tx_fifo_set(txfifo_data * txfifo)という txfifo_dataポインターを引数とする関数を呼び出したいと思っているのですが、これをコンパイルすると error: incompatible type for argument 1 of 'tx_fifo_set'というエラーが出力されコンパイルできない状態になります。なぜこのようなエラーになるのでしょうか? u16 tx_fifo_set(txfifo_data * txfifo) { -------------------(中略)------------------------------------------------------------- } void tx_test(cc1101_client * client) { u8 i=0; u8 new_input_data=0; -------------------(中略)------------------------------------------------------------- while(1) { switch(status) { -------------------(中略)------------------------------------------------------------- case FIFO_SETUP: if(cnt_sent_packet > 100) { status = DATA_WAVEOUT_QUIT; break; } //alert_data_get(&client); cc1100_cmd_flush_tx(); cc1100_cmd_idle(); cc1100_cmd_calibrate(); cc1100_cfg_gdo0(CC1100_GDOx_SYNC_WORD); mdelay(5); client->status.sessionflag = 0x02; //SYN flag set client->status.ivent_flag = 0xa5; //tx_length = tx_fifo_set(client); //tx_fifo_set(&client); tx_fifo_set(client->txfifo); udelay(10); #if 1 cc1100_read_reg_uartout((CC1100_REG_TXBYTES | CC1100_ACCESS_STATUS)); #endif status = DATA_WAVEOUT; break; -------------------(中略)------------------------------------------------------------- }

  • 関数原型宣言について

    関数原型宣言について 下記のプログラムのfunc関数は、関数原型宣言 <func(int a, long b, char *c);>が述されていないのにfunc関数の仮引数の型longは、関数原型宣言が与えられるといると本に書かれていたのですが、何故でしょうか教えて頂きたい。 ******************************************** #include <stdio.h> /*--- 三つの引数を受け取る関数 ---*/ void func(int a, long b, char *c) { int x; long y; /* … */ } int main(int argc, char *argv[]) { int a = 1; char s[] = "abc"; func(a + 3, 2, s); return (0); } *************************************************************

専門家に質問してみよう