マイコンプログラムの変数代入によるメモリ劣化への懸念
- マイコンでのプログラム内での変数代入によるメモリ劣化への懸念があります。質問者は、ループ内での変数代入がマイコン内部のメモリを劣化させるのではないか心配しています。
- 質問者は、マイコン内部のメモリには書き込み回数の限度が存在し、それを超えてしまわないか心配しています。特に、次のようなプログラムが問題視されています。
- 質問者は、もっと効率的な方法があるか、あるいはシンプルな処理が無駄なのかについてアドバイスを求めています。
- ベストアンサー
代入によるメモリ劣化について
マイコンでのプログラムについて、一点疑問があります。 プログラム内でループしている個所の変数代入についてですが、これでマイコン内部のメモリを劣化させてしまわないのか心配です。 マイコン内部のメモリに書込み回数限度があり、それを食いつぶさないのか心配なのです。 以下のプログラムがその例です。 uint8_t i = 0; int main(void) { while(1) { i = 0xff; } } この処理は内部メモリにダメージを与えてしまうのでしょうか? たとえば、 uint8_t i = 0; int main(void) { while(1) { if(i != 0xff) i = 0xff; } } このような書き方にすべきなのでしょうか? できる限りシンプルにプログラムしたいので、このような処理が無駄であれば教えてください。 もしくは、もっと効率的な方法があれば教えてください。 よろしくお願いいたします。
- zero-spica
- お礼率71% (41/57)
- その他([技術者向] コンピューター)
- 回答数1
- ありがとう数2
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
一言でメモリと言っても多様です。 一般に言われるメモリはCMOSと呼ばれるもので、メモリ保持に電力を 必要としませんが、速度が遅く、書き込みによって少しずつ劣化するものもあります。 しかし、演算に使われるCPU内のメモリーはメモリー保持に電力を必要としますが、 動作が速く、その寿命は半永久的(CPUが型落ちになるくらいまでは保ちます)です。 ですから、代入などによるレジスタの使用に対しては寿命は考慮しなくてもいいです。 ただし、ループ内の無駄な処理は動作が遅い原因となります。
その他の回答 (1)
- osamuy
- ベストアンサー率42% (1231/2878)
たいていの場合、レジスタやスクラッチパッドメモリへの操作に展開されるだろうから、書き込み制限があるような領域への負担は無いのでは。 書き込み制限があるというのでしたら、レジスタ等を積極的に利用するようなコードを記述するとか。 もちろん個々のシステムの仕様に依存する話なので、具体的なところはハードウェアベンダやソフトウェアのサポートに照会したほうがよいかと。
お礼
負荷のあるメモリへの書込みでないことがわかり安心しました。 一応確認のためにデータシートを参照しておきたいと思います。 ご回答ありがとうございました。
関連するQ&A
- C言語の代入についての質問です
C言語の代入についての質問です 下のプログラムを見て下さい #include<stdio.h> int x[2]; x[0] = x[1] = 1; int main(void) { for(int i = 0 ; i < 2 ; i++) printf("%d",x[i]); putchar('\n'); return 0 ; } このプログラムをコンパイラすると3行目の代入にエラーが出されます (当たり前ですがmainの中に3行目の代入文を入れると上手くいきます) まぁそれがなぜかというのが知りたいのですが、 それはC言語をつくった人が決めたことなのでしょうか? ちなみに異なる実行環境でやってみたらどれも駄目だったので これが上手くいくことはない?のだと思います そういうもんなのだったら、そういうものだと理解しますが もし理由を知っている方がいらっしゃったら教えて下さい
- ベストアンサー
- C・C++・C#
- 警告「代入される前に使われている」を出す方法
bccで以下のコードをコンパイルすると。 「'i' は、おそらく値が代入される前に使われている」 と警告が出ますが、 「'h' は、おそらく値が代入される前に使われている」 とは警告を出してくれません。 警告を出す方法ってないでしょうか? Hogeメンバに bool 型の初期化フラグでも実装しようかな・・・。 #include <iostream> class Hoge { public: Hoge(){ } Hoge( int i ){ t = i; } operator int(){ return t; } int t; }; int main() { int i; Hoge h; std::cout << i << std::endl; std::cout << h << std::endl; return 0; }
- 締切済み
- C・C++・C#
- メモリ開放の質問ですが
#include<iostream> using namespace std; void main(void) { int i; char *s,*t; s=new char[9];t=s; for(i=0;i<9;i++)*(s+i)=i; for(i=0;i<9;i++)cout<<(int)s[i]<<endl; delete s; delete t; //error } において2回目のdelete tでエラーになりますが #include<iostream> using namespace std; void main(void) { int i; char *s,*t; s=new char[9];t=s+2; for(i=0;i<9;i++)*(s+i)=i; for(i=0;i<9;i++)cout<<(int)s[i]<<endl; delete t; delete s; } はエラーになりません (s=t+2をs=t+1に変更するとエラーになる) 実際にdeleteは何を行いエラーを引き起こすのでしょうか? エラーになるメカニズムを教えてください
- ベストアンサー
- C・C++・C#
- c言語についてです。
文字の順番を逆さまにするプログラムなのですが実行してenterキーを押しても何もおこりません。原因がわかる方がいたら教えてほしいです。 初歩的な質問ですみません。 使っているパソコンはMacBookProです。 #include<stdio.h> void reverse(char[],char[]); void divide(char[],char[]); int main(void) { char s[100],t[100]; gets(s); reverse(s,t); divide(t,s); printf("%s %s\n",s,t); return 0; } void reverse(char s[],char t[]) { int i=0,j=0; while(s[i]!=0){ i++; } i--; while(i>=0){ t[j]=s[i]; i--; j++; } t[j]=0; return ; } void divide(char t[],char s[]){ int i=0,j=0; while(t[j]!=' '){ i++; } t[i]=0; i++; while(t[i]!=0){ s[j]=t[i]; j++; i++; } s[j]=0; return ; }
- 締切済み
- C・C++・C#
- int rev_int(int num)文 関数の入門
#include<stdio.h> /*---非負の整数を読み込んでます*/ int scan_uint(void) //関数scan_uintは、キーボードから非負の整数値を読み込んでその値を返す関数です。 { //この関数には受け取るべき仮引数がありません。仮引数がないことを示すためには()の中をvoidとします。 int tmp;//テンプの箱作成 do { printf("非負の整数を入力してください:"); scanf("%d", &tmp); if (tmp < 0) printf("\a負の数を入力しないでください"); } while (tmp < 0); return (tmp); } /* 非負の整数を逆転した値を返す */ int rev_int(int num) { int tmp = 0; if (num > 0){ do { tmp = tmp * 10 + num % 10; num /= 10; }while (num > 0); } return (tmp); } int main(void) { int nx = scan_uint(); printf("反転した値は%dです。\n", rev_int(nx)); return 0; } 教えてください!参考書に書いてあることをまとめて プログラムを読んでるのですが、わからない部分があります。 (1)まずint scan_uint(void)からこのプログラムは読み込んでるのでしょうか? どこかのサイトを調べたら、最初にint mainからプログラムは 読み込むというのを観たのですが、コンパイルして実行した動きをみるかぎり一番最初はint scan_uint(void)から読んでるように見えます。。。 (2)int scan_uint(void)の文は理解できました。私なりに解釈したのは ここでは正の数を入力しないと次に進まないことと 負の数を入力した場合、負の数を入力しないでくださいと注意がずっと でるという文です。 質問ですが、このあとint rev_int(int num)文に移ると思うのですが ここの int tmp = 0; これはこのint rev_int(int num)文のみの tmpの箱と参考書に記載がありました。つまり int scan_uint(void)で 出てきたtmpとは別個と解釈しました。 そうなると、int rev_int(int num)文を読んでみると tmpの箱を作成。そこは0を代入。 if文で num>0の時、 do文に入る (ここでいうnumは int numと宣言してないですけど、またscanfとか作って値はまだいれてないですけど??) do文は tmp = tmp*10 + num %10 num /=10 wile(num>0) これを見る限り、numという箱が見えません。全体を見渡しても どこかでnumに値が代入されたのち、このint rev_int(int num) という文を読みこんでいき if num>0のときと宣言されていますが もっと前の段階でnumの値が入力されていない限り このif文は適用されないと思ったのですが、プログラムは動いてます 三つ目の質問です tmp = tmp *10 + num % 10 num /=10 の部分がわかりませんでした。 tmpはまず、int scan_uint(void)で作成したtmpと int rev_intで登場してきたtmpとは別個と参考書に書いてあるのが 正しいのであれば tmpの値はここでは初のはずです。 一体いつ値を入力したのでしょうか? もしも一番最初のscanfの時に入力した例えば12345が此処でも適用されるなら tmp = 12345 ×10 + num % 10を tmpに代入するって文になりますが どうしてtmpを10かけるのですか?123450になり、 そのあとnumの値が此処でもまだ不明なのですがnum/10したものと 足すみたいですが、わかりませんでした。。。 まとめると、tmp = tmp*10+num%10がわかりません。 また、numとは何かわかりません、値もどの値がどこで代入されていて while(num>0)が引っかかるのか不明です。 tmpはint scan_uint文内で入力した値(scanfの部分で) 12345と仮に入力したら、それは次のint rev_int(int num)でも続いて活用されてるのですか? 参考書はなぜ別個と書いてるのかわかりません。 ごめんなさい>_< とても長くなりました。 どなたか解る方、教えてください、よろしくおねがいします。
- ベストアンサー
- C・C++・C#
- インクリメント演算子をprintf文で使うことについて
◎1-------------------------------------- #include<stdio.h> int main(void) { int i=0; while(i<=20){ printf("%d\t%d\t%d\t%d\t%d\n",++i,++i,++i,++i,++i); } return 0; } ------------------------------------------ ◎2-------------------------------------- #include<stdio.h> int main(void) { int i=0; while(i<=20){ printf("%d\t%d\t%d\t%d\t%d\n",i++,i++,i++,i++,i++); } return 0; } ------------------------------------------ 以上2つのプログラムについて疑問があるのですが、まず◎1についてですが、実行結果は、 5 4 3 2 1 10 9 8 7 6 15 14 13 12 11 20 19 18 17 16 25 24 23 22 21 以上のようになるのですが、自分の考えでは、「printf("%d\t%d\t%d\t%d\t%d\n",i++,i++,i++,i++,i++);」部分の、一番最初の「++i」から処理が始まり、 1 2 3 4 5 ・ ・ ・ のようになる事を期待したのですが、一番最後の「++i」から処理が始まってしまいました。 次に、◎2についてですが実行結果は、 0 0 0 0 0 5 5 5 5 5 10 10 10 10 10 15 15 15 15 15 20 20 20 20 20 以上のようになりました。「printf("%d\t%d\t%d\t%d\t%d\n",i++,i++,i++,i++,i++);」部分で、iをいったん表示してから、iに1を加算するということで、次のiは1になっており、 4 3 2 1 0 ・ ・ ・ のようにまた一番最後の「i++」から処理され以上のようになると思ったのですが、そうはなりませんでした。 以上、◎1と◎2について何故こうなるのかご回答いただければ嬉しいです。
- ベストアンサー
- C・C++・C#
- Aki-h8/3052マイコンについて
今Aki-h8/3052マイコンを勉強しているのですが、初心者のためうまくいかず質問をしました。知識がないと思われるような質問をしてしまいますが、よろしくお願いします。 次のようなプログラムを書き込んで、LEDを点滅させたいのですが点滅しません。原因がわからないので、教えていただける方がいたらよろしくお願いします。 #define P5DDR (*(volatile unsigned char*)0xffffc8) #define P5DR (*(volatile unsigned char*)0xffffca) void wait (long loop){ while(loop--); } int main(void){ P5DDR = 0xff; while(1){ P5DR = 0xff; wait(200000); P5DR = 0; wait(200000); } } ポートBを使用した場合うまくいくのですが、ポート5を使用するとうまくいきません。 コンパイラにはGDLを、書き込みにはH8Write Turboを使用しています。
- 締切済み
- C・C++・C#
- printf()で出力したいんですが?
#include <stdio.h> int main( void ) { int air[4]; int i; i = 0; printf( "データ入力\n" ); do{ scanf( "%d\t", &air[ i++ ]); } while(air[ i - 1 ] > 0 ); printf( "%d\n", i ); return 0; } このプログラムはコンパイル出来ますが、期待していたprintf関数での出力ができません。 その理由として何がありますか?関数の使い方が間違っているのか、DO~WHILE文が使えない場所 なのか、もし直すとすればどう直せばいいのですか。
- ベストアンサー
- C・C++・C#
お礼
わかりやすいご説明ありがとうございます。 安心してプログラミングできそうです。 的確なご回答ありがとうございました。