2016-04-14 4 views
0

ながら私はブライアン・カーニハンの「Cプログラミング言語 "行使1-19のためのシンプルなソリューションを書いた内部予期したとおりに動作しません文字列。 reverse(char[])の機能は以下の通りです。Postfixの++演算子はそれが逆転しており、条件

void reverse(char src[]) 
{ 
    int len = 0; 
    while(src[len] != '\0') 
     len++; 

    for(int i = 0; i < len/2; i++) 
    { 
     char temp = src[i]; 
     src[i] = src[len - 1 - i]; 
     src[len - 1 - i] = temp; 
    } 
} 

Iは、whileループの内側後置インクリメント(++)演算子を使用する場合は、関数は失敗。

void reverse(char src[]) 
{ 
    int len = 0; 
    while(src[len++] != '\0')  // this fails 
     ; 

    for(int i = 0; i < len/2; i++) 
    { 
     char temp = src[i]; 
     src[i] = src[len - 1 - i]; 
     src[len - 1 - i] = temp; 
    } 
} 

唯一の違いは、代わりに、whileループ内部をlenの可変をインクリメントで、Iは、動作期待が「条件チェックのための古い値を使用して、のようにであるべきである後置++演算子を用い、あります終了後にそれを増やす "。

なぜ期待どおりに動作しないのですか、どこで間違っていますか? Windows 10 Mingw/gccコンパイラでコンパイルしています。ここにテストコード全体があります。

テストコード

#include <stdio.h> 

#define STR_NUM  5 
#define STR_SIZE 20 

void reverse(char[]); // declaration 

int main() 
{ 
    char str[STR_NUM][STR_SIZE] = 
    { 
     { "A"  }, 
     { "AB" }, 
     { "ABC" }, 
     { "ABCD" }, 
     { "ABCDE" } 
    }; 

    for(int i = 0; i < STR_NUM; i++) 
     reverse(str[i]); 

    for(int i = 0; i < STR_NUM; i++) 
     printf("%s\n", str[i]); 

    return 0; 
} 

// this is working 
void reverse(char src[]) 
{ 
    int len = 0; 
    while(src[len] != '\0') 
     len++; 

    for(int i = 0; i < len/2; i++) 
    { 
     char temp = src[i]; 
     src[i] = src[len - 1 - i]; 
     src[len - 1 - i] = temp; 
    } 
} 

// this is failing 
/* 
void reverse(char src[]) 
{ 
    int len = 0; 
    while(src[len++] != '\0')  // this fails 
     ; 

    for(int i = 0; i < len/2; i++) 
    { 
     char temp = src[i]; 
     src[i] = src[len - 1 - i]; 
     src[len - 1 - i] = temp; 
    } 
} 
*/ 
+4

デバッガを使用して、 'len'がどのようなものになるのかを確認してください。それはまだルールに従って動作していますが、あなたのストリングが終わっても*増加します。 – usr2564301

+1

Rad Lexusが正しいです。空文字列の場合、コードは 'while(src [len ++]!= '\ 0');'を実行します。これは 'src [0] == '\ 0''でないためです。その後、 'len'は' len ++ 'のために1になります。長さが0の文字列は長さが1であるとみなされます。 –

+1

は 'len == -1'で始まり、' while(src [++ len]) 'を使います。 – EOF

答えて

5

後置インクリメント演算子はいずれかによって元の値及び増分を返します。作業バージョンで

while(src[len] != '\0') 
    len++; 

src[len]\0である場合、whileループは終了します。 whileループテスト条件が失敗すると、ループ内のステートメントは実行されません。ループlenの後に、src[len] == '\0'のような値が含まれています。最終テストはlenは一つの追加の時間を増加します、予め形成され、あなたの修正版では、

while (src[len++] != '\0'); 

。ループlenの後に、src[len]が配列の末尾を1超えた値を含みます。

ただし、forループでは、lenが文字列長であるとみなしているため、オフラインでエラーが発生しています。