2016-06-16 18 views
-1

私はカウンター(私はCでプログラム)を必要としているとしましょう、一度だけ。カウンタを宣言するのではなく、もはや不要になった変数を再利用するだけでいいですか?例えば変数を再利用する必要がありますか?

int main() { 
    int in; 

    //code goes here 

    for(in=0; in<10; in++) //do something 
    //instead of using i, I reuse in and use it as a counter 

    return 0; 
} 
+0

新しいオブジェクトに新しい名前を使用すると、名前を付けた人のように便利です。 – chux

+2

@chux死者の名前を再利用することはできませんか? :) –

+2

"カウンター"という名前の変数を使っていくつかの場所でカウントするのが理にかなっています。しかし、それはリンゴのポンドのコストを保存するためにそれを使用することは理にかなっていません。 –

答えて

3

などその用途に変数のスコープと寿命を制限するようにコーディングスタイルのルールがあります。もう1つは、その使用法に最も近い変数を宣言することです。

forループの最も慣用形態は次のようになります

for (int i = 0; i < 10; i++) // do something 

が使用:

for(in=0; in<10; in++) // do something 

潜在inの値が後をreadedされていることを、保守プログラマに誤解を与えることができますforループのスコープ。

+0

きれいでよく書かれた答えをありがとう! – doubfdb

+0

低電力と低RAM(スタック)の組み込みシステムでは、おそらくローカル変数の宣言を制限する必要があります。誰かが明示的に変数共有の名前を付けるためにマクロを使用します。 – rom1nux

+0

@ rom1nux:OTOHは、オブジェクトが占有する領域がスコープの終了後すぐに解放されるため、スタック配置変数のスコープを狭めることで、メモリを効果的に節約できます。 –

0

本当にしたいが、単純な変数のためにあまり保存しない場合(スタックに同じスペースを保存する)、再利用できます。

メンテナンスの目的で、すべての変数(関数や構造体としての井戸)に意味のある名前を付ける必要があります。

1

私はあなたがこれをやりたい理由が効率のためであると仮定しています。変数を再利用することにより、不要なメモリ割り当てを避け、技術的に正しいと考えるかもしれません。あなたが提供した上記のコードは正常に動作しますが、無関係のデータを格納するために宣言された変数を再利用するのは、一般的にはコーディングが苦手で不要です。

コードを理解して維持するのが難しくなり、コードを他の誰かに提供して維持すると、これは二重になります。また、スタック上にあるスペースを節約している間は、コードを読むことができないようにする価値はないと主張します。与えた例で

int main() { 
    int in; 

    //code goes here 

    for(in=0; in<10; in++) //do something 
    //instead of using i, I reuse in and use it as a counter 

    return 0; 
} 

int inは、プログラムスタック上に存在する整数です。整数は通常、Cプログラムでは4バイトです。現代のオペレーティングシステムのsize of the stackは、平均的なCプログラムを心配する必要はありません。したがって、コードを自分自身と他者の両方で維持することを困難にすることと引き換えに、唯一の利点は、プログラムスタックに4バイトを節約することです。具体的な開発上の制約によって、これは適切なトレードオフになる場合もありますが、これはまれであり、完全に必要でない限りは行わないでください。

0

これは変数名によって異なります。両方のコードが同様の操作を行い、変数名がまだ良好であれば、(コードが正しいことを確認している限り)再利用することができます。しかし、変数がまったく異なる目的のために使用された場合、これはコードを読みにくくするでしょう。したがって、たとえば、これは許容可能である:

int n; 
for (n = 0; n < 10; ++n) 
    do_something(n); 
for (n = 5; n < 100; ++n) 
    do_something_else(n * 2); 

この使い方が悪い:

int timeout = get_timeout(); 
start_timer(timeout); 

for (timeout = 0; timeout < 5; ++timeout) 
    status[timeout] = SUCCESS; 

後者の例では、それを読みやすくするために、このように書き直すことが必要です。

int timeout = get_timeout(); 
start_timer(timeout); 

int n; 
for (n = 0; n < 5; ++n) 
    status[n] = SUCCESS; 
0

これが依存しますコードのパフォーマンス、サイズ、メンテナンス性/可読性など、いつものように。 ほとんどの場合、保守と可読性が必要なため、明示的な変数名でコードをクリアし、混乱を避けるためにコードを再利用しないでください。 タイムクリティカルなコードや低リソースシステムでは、スタックをあまりにも多くロードすることを避けたいので、おそらく多くを再利用したいと思うでしょう。

コンパイラがC99に準拠している場合は、変数の有効範囲を制限して使用することはできますが、コンパイラがこれをうまく処理せず、場合によってスタックをロードし続けることがあります。関数フレームの例restrict.cスタックの使用は次の は、GCC 4.8.2に

reuse.cより高い例:restrict.c

int main(int argc, char** argv) 
{ 
    int a=0; 
    for(int i1=0;i1<10;i1++){ 
     a++; 
    } 
    for(int i2=0;i2<10;i2++){ 
     a++; 
    } 
    for(int i3=0;i3<10;i3++){ 
     a++; 
    } 
    for(int i4=0;i4<10;i4++){ 
     a++; 
    } 
    return 0; 
} 

例:reuse.c

int main(int argc, char** argv) 
{ 
    int i, a=0; 
    for(i=0;i<10;i++){ 
     a++; 
    } 
    for(i=0;i<10;i++){ 
     a++; 
    } 
    for(i=0;i<10;i++){ 
     a++; 
    } 
    for(i=0;i<10;i++){ 
     a++; 
    } 
    return 0; 
} 

例:restrict.disasm

main: 
    pushq %rbp 
    .seh_pushreg %rbp 
    movq %rsp, %rbp 
    .seh_setframe %rbp, 0 
    subq $64, %rsp 
    .seh_stackalloc 64 
    .seh_endprologue 
    movl %ecx, 16(%rbp) 
    movq %rdx, 24(%rbp) 
    call __main 
    movl $0, -4(%rbp) 
    movl $0, -8(%rbp) 
    jmp .L2 
.L3: 
    addl $1, -4(%rbp) 
    addl $1, -8(%rbp) 
.L2: 
    cmpl $9, -8(%rbp) 
    jle .L3 
    movl $0, -12(%rbp) 
    jmp .L4 
.L5: 
    addl $1, -4(%rbp) 
    addl $1, -12(%rbp) 
.L4: 
    cmpl $9, -12(%rbp) 
    jle .L5 
    movl $0, -16(%rbp) 
    jmp .L6 
.L7: 
    addl $1, -4(%rbp) 
    addl $1, -16(%rbp) 
.L6: 
    cmpl $9, -16(%rbp) 
    jle .L7 
    movl $0, -20(%rbp) 
    jmp .L8 
.L9: 
    addl $1, -4(%rbp) 
    addl $1, -20(%rbp) 
.L8: 
    cmpl $9, -20(%rbp) 
    jle .L9 
    movl $0, %eax 
    addq $64, %rsp 
    popq %rbp 
    ret 

例:reuse.disasmあなたは、両方の文を混ぜて使用すると、関数内で再利用される一般的なループカウンタ(i、j、k)を宣言して、明示的に重要な意味変数を維持することができます実際には

main: 
    pushq %rbp 
    .seh_pushreg %rbp 
    movq %rsp, %rbp 
    .seh_setframe %rbp, 0 
    subq $48, %rsp 
    .seh_stackalloc 48 
    .seh_endprologue 
    movl %ecx, 16(%rbp) 
    movq %rdx, 24(%rbp) 
    call __main 
    movl $0, -8(%rbp) 
    movl $0, -4(%rbp) 
    jmp .L2 
.L3: 
    addl $1, -8(%rbp) 
    addl $1, -4(%rbp) 
.L2: 
    cmpl $9, -4(%rbp) 
    jle .L3 
    movl $0, -4(%rbp) 
    jmp .L4 
.L5: 
    addl $1, -8(%rbp) 
    addl $1, -4(%rbp) 
.L4: 
    cmpl $9, -4(%rbp) 
    jle .L5 
    movl $0, -4(%rbp) 
    jmp .L6 
.L7: 
    addl $1, -8(%rbp) 
    addl $1, -4(%rbp) 
.L6: 
    cmpl $9, -4(%rbp) 
    jle .L7 
    movl $0, -4(%rbp) 
    jmp .L8 
.L9: 
    addl $1, -8(%rbp) 
    addl $1, -4(%rbp) 
.L8: 
    cmpl $9, -4(%rbp) 
    jle .L9 
    movl $0, %eax 
    addq $48, %rsp 
    popq %rbp 
    ret 

名前がついた。

関連する問題