• 締切済み

a=a+1;mysub(a);とmysub(a+1);の違いは。

こんにちは。 MikroCというコンパイラで C言語のプログラムを組んでいます。 ここで、 ある関数に引数を渡すのですが、 a=Adc_Read(0); a=a+10; Delay_Cyc(a); では、期待した動作を しないのですが、 a=Adc_Read(0); Delay_Cyc(a+10); では、期待した動作となります。 また、 a=Adc_Read(0)+10; Delay_Cyc(a); でも、期待した動作となります。 まったく同じのように 思うのですが、 何が違うのでしょうか。 コンパイラが、a=a+xという 書き方を許していない ということでしょうか。 何か分かる人がいましたら、 よろしくお願いします。

  • rheda
  • お礼率69% (257/372)

みんなの回答

  • kkk1024
  • ベストアンサー率33% (42/127)
回答No.4

こんばんは。 質問者様の期待する動作がどのようなものか分かりませんがタイトルにある「a=a+1;mysub(a);とmysub(a+1);」は少なくとも違う動きになりますね。 1つめの「a=a+1;mysub(a);」は (1).a=a+1; ここで"a"は加算されて"a"に代入されるため、"a"自体が変化 (2).mysub(a); 変化した"a"を関数"mysub"に引き渡し 2つめの「mysub(a+1);」は (1).<mysub実行前の>a+1 "a+1"自体は評価されるが"a"自体は変化しない (2).mysub(a+1); "a+1"の結果が関数"mysub"に引き渡される 前者は"a"の値が変化しますが、後者は"a"の値は変化しません。 質問本文にある"Delay_Cyc"関数に渡す値は変化しませんが、その後の"a"は変化しますよ。 質問者様が指しているのが本文の"a"の結果であれば、 1つめと3つめは同一の結果、2つめは他より10少ない結果です。 ただ、質問者様が期待している動作は2つめと3つめなので、少なくとも"a"の結果を期待しているのではないのですよね? 質問本文に間違いがなければですが… 他には"Adc_Read"関数実行、"a+10"の評価、"Delay_Cyc"関数実行のタイミングは若干異なるのかな? バイナリレベルの想像がつかないし、どんな実行方式かも分からないので何とも言えませんが。 MikroCというコンパイラがどのようなものか分かりませんので、実行コードに落ちた段階でどうなるかは分かりません。 後は質問者様はデバッグ中だと思いますが、その注視する範囲が間違っているとか、問題を見誤っているとか? 参考になれば幸いです。

  • eroermine
  • ベストアンサー率18% (83/444)
回答No.3

次でタイミング取ってるようなので変えたら駄目だね。 オプチマイザーも使えなそうだね。

回答No.2

>期待した動作をしないのですが、 と書かれても、回答者にはどのように動作していないのかは判断するすべがありません。 Adc_Read(); Delay_Cyc(); に関連するソース(呼び出し元も含めて)をすべて開示してください。 最低でも上記二つの関数のソースの内容と >a=a+10; のaの宣言文は必須です。 >コンパイラが、a=a+xという書き方を許していないということでしょうか。 ならば、普通はコンパイル時にワーニングもしくはエラーとなります。

noname#81401
noname#81401
回答No.1

期待した動作というのが、この部分だけでは判断できません。 もう少し他の部分も見せてもらわないと何とも言えませんね。

関連するQ&A

  • RTCで読み取った時刻がある時間になったときに,ある関数を読み込みたい

    RTCで読み取った時刻がある時間になったときに,ある関数を読み込みたいのですが, どのようにプログラムを書けばいいのでしょうか? ご回答をよろしくお願いいたします. プログラム言語はC言語で,PICは16F876を使用しています. 下記のようにrtc_data_read()関数で使用しているminが0分または05分のときにadc_solar()関数を読み出したいのですが, 下記のプログラムでは初期時刻を59分に設定しているのに,05分となり,時刻が変化してもずっと05分のままになってしまいます. また,ポインタを使用してみましたが,コンパイルエラーが出てしまいます. void Normal(void) { while(flg==0){ rtc_data_read(); if((min=0) || (min=5)){ adc_solar(); } } }

  • PICのA/D変換の入力が何故か0Vになってしまいます・・・

    現在、PIC12f675を用いて下記のようなことをしたいと検討しているのですが、 中々思った通りに動いてくれません。 どなたか分かる方がいらっっしゃいましたらアドバイスお願い出来ないでしょうか? 「開発環境」 ・CCSのCコンパイラを使用 ・PICは12f675 「内容」 アナログ入力端子に任意の電圧を加えて、RS232CでPC上にその電圧を表示する。 現在、アナログ入力端子(AN0)に電源電圧から分圧して0.5Vや1Vなどの電圧を加えているのですが、 何故か入力端子の電圧をテスターで測定すると0Vとなり、PC上でもやはり0Vと表示されてしまいます。 何故、任意の電圧を加えても全て0Vとなってしまうのかが分かりません。 おそらくプログラム上でのミスがあると思うのですが・・・ 検討中のプログラムを下記に書きます。 ***************************************************** ///// 初期設定 ///// #include <12f675.h> #device ADC=10 #fuses INTRC_IO, NOWDT, PUT, NOPROTECT, BROWNOUT /////RS232C使用宣言///// #use delay(CLOCK = 4000000) #use rs232(BAUD = 9600, XMIT = PIN_A2, RCV = PIN_A1) //GP1=受信 GP2=送信 //// メイン関数 void main() { // A/D初期設定 float data; setup_adc_ports(AN0_ANALOG); //AN0をアナログ設定 setup_adc(ADC_CLOCK_INTERNAL); //ADCのクロック設定(内部発振) set_tris_a(0); output_A(0); while(1) { set_adc_channel(0); delay_us(50); data = read_adc(); data = (data * 3.0) / 1024; printf("電圧 = %1.3fV\r\n",data); } } ***************************************************** 申し訳ありませんが、アドバイスお願いします。

  • PICのプログラミングについて

    16F88をC言語でプログラムしています。 HI-TECH cでコンパイルしたところ、delay関数がうまく動作しません。 delay関数の直前までは動作するのですが、そこでストップしてしまいます。 どうもincludeの設定のところに問題があると思うのですが、 初心者なもので原因がいまひとつ掴めません。 とりあえず、delayが動作しているか確かめるために作った下記のプログラムでいろいろと試しているのですが、おかしいところがあればご指摘お願いします。 **************************** //RB0~RB4にはLEDを接続 #include <pic.h> #include <htc.h> #define _XTAL_FREQ 8000000 // 8Mhz __CONFIG(0x3F22); void main(){ TRISA = 0b00000100; TRISB = 0b00000000; PORTB = 0b00000101; __delay_ms(500); PORTB = 0b00000111; }

  • マイクロチップ社PIC用の Cコンパイラについて

    今までPICのプログラムを作るのにマイクロチップ社のアッセンブル言語を使っていましたが、今後もう少し複雑なプログラミングをしようと思っているのでC言語のコンパイラを購入しようと思っています。 ここで結構迷いまして、どのメーカーのコンパイラがいいか色々な意見を聞きたいために書き込みをしました。 コストパフォーマンスで考えていた候補が CCS-CかMikroCです。 試しにMikroCを使ってみたところ確かにあっという間にちょっとしたプログラムが作れるので快適なのですが、ソフト上のシミュレーション機能で変数の変化を見ると時々挙動が変だったりするのが気になります。 (知っておくべき知識があるのかバグなのかはわかりません)。 また、CCS-Cは若干値段が高く癖のあるC言語ということを聞きますが、人気があるように思えます。私は癖があってもそれを覚えればいいと楽観的なのですが・・。 PIC用のCコンパイラに見識がある方がおられれば意見をお聞かせいただければと思います。 こういうところはかなり問題だとか、こういう機能はすごく便利だとか、こっちの方がこうだから絶対お勧めだとか、なんでもいいので教えていただければ幸いです。 よろしくお願いします。  

  • PIC16F88のA/D変換の時間設定について質問です。最近PICを始

    PIC16F88のA/D変換の時間設定について質問です。最近PICを始めたばかりの素人です、色々な書籍を読みあさりC言語でプログラミングしていますが、PIC16F88のA/D変換を利用しステッピングモータの回転数を制御するプログラムを作りました。そこでアナログからデジタルに変換する待ち時間が必要とわかりとりあえず仕様書に19.72μSの待ち時間らしき時間がありましたので使用しましたがこれが正しいのかわかりません。どうぞアドバイスお願いします。 以下プログラムの抜粋です。コンパイラはCCS社のPCMを使用しています。 #include<16f88.h> #fuses HS,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT, #device ADC=10 #usedelay(clock=10000000) 途中省略 void DEGVR() { ///////////////////////VR→デジタル計算/////////////////////// set_adc_channel(2);//A/D変換チャンネル設定 delay_us(20);//変換にかかる時間19.72μs vr = read_adc();//A/D変換レジスタリードしvrへ 途中省略 main() { ////////////////////////vr設定/////////////////// setup_adc_ports(sAN2); //アナログポート設定 setup_adc(ADC_CLOCK_DIV_32);//アナログ変換クロック設定 途中省略

  • 分割ファイルのコンパイルができない

    こんにちは。 mikroCというコンパイラを使い、 以下の2つのファイルをコンパイル 使用と思っていますが、 「init12f683が宣言されていない」、という エラーが出てしまいます。 プログラム的に問題あるでしょうか( コンパイラでは、ひとつのプロジェクト を作成し、両方そこに加えてあります)。 ----init12f683.c(自作関数) void init12f683(){ GPIO=0; CMCON0=0b00000111; ANSEL=0b01110000; TRISIO=0b00010000; } ----picc1.c(main) extern void init12f683(void);*宣言はここと、 void main(){ extern void init12f683(void);*ここで両方試しました。 init12f683(); Delay_ms(1000); while(1){ GPIO.F0=1 ; Delay_ms(1000) ; GPIO.F0=0 ; Delay_ms(1000) ; } } externでの関数の宣言は、mainの外に置く場合と、 中に入れる場合、両方試しています。 問題が、プロジェクトファイルの設定にあるのか、 プログラム的におかしいのか(どこがおかしいのか)、 知りたいです。 何か分かる人がいましたら、 よろしくお願いします。

  • 関数の引数を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++ではありません。

  • PIC16F874Aについて

    16F874Aを使用して回路をつくっているのですが、I/Oピンの出力(LEDを接続)はちゃんと動作してくれるのに、入力(スイッチを接続)が全く動作してくれません。動作確認のために、 void main(){ PORTB=0x01; TRISB=0x01; while(1){ if(PORTB.F0==0){ PORTB.F1=1;     } }        } という簡単なプログラムでも動作しません。 また、AN0~AN7をデジタルで使用したいため、A/D変換のプログラムとして、 setup_adc_ports(0b00000000); をプログラム中に入れてビルドすると、エラーが出てしまいます。 PIC素人のため初歩的な質問かとは思いますが、回答よろしくお願いします。

  • C言語のread関数に関するファイルディスクリプタ

    C言語のread関数に関するファイルディスクリプタについて質問です。 open関数から得られたファイルディスクリプタを、一般的には変数(例:fd)に代入して、fdをread関数や、write関数の第1引数として用いるんですが、ファイルディスクリプタは数値のはずなので、それを引数として用いてもどうやってそこからパス情報を得ることが出きるのかが分かりません。 例えば以下のような場合です。 ****** 省略 fd = open("/home/XXX/YYY", O_RDONLY); read(fd, buf, 10); 省略 ****** 誰か詳しい方がおりましたら、どうかご教授よろしくお願い致します。

  • 期待する文字列

    フリーウェアのBorland c++compiler 5.5で 動的メモリーを確保して、期待する文字列(実数文字)が入力されるまで 繰り返すというプログラムを作っています。 以下のプログラムだけだと正常に動作しますが、その関数をループさせて 期待する文字列までループさせると数字のみなら実効可能ですが、 数字以外の文字が混じって15文字以上になると「不正な処理~~~」と強制終了させられます。 以下が そのプログラムの考え方です。 1 関数 A() 動的メモリーの確保   2へ 2 関数 B() 文字の読み込み(必要に応じてメモリー拡張) 3へ 3 関数 C() '.'個数チェック 2=エラー表示            1=小数点の書き換え(数字) 4へ            0=             4へ 4 関数 D() 関数isdigitで各メモリーをチェック 無限ループを使って int i=1; while(i) { 関数 A() }iのアドレス(ポインタ)を4まで引数にして iの値を0に書き換えループから脱出させています c言語を勉強して2週間の初心者です。どこがいけないのか 分かりません。 どなたか教えてください。          

専門家に質問してみよう