2015-10-12 8 views
20

は++私はC.C文字列はCに大文字にすると、私はCで一緒に、大文字の機能を入れていた一方でC++

C++の機能を期待される出力を受信しなかったことに気づいた

#include <iostream> 
#include <cctype> 
#include <cstdio> 

void strupp(char* beg) 
{ 
    while (*beg++ = std::toupper(*beg)); 
} 

int main(int charc, char* argv[]) 
{ 
    char a[] = "foobar"; 
    strupp(a); 
    printf("%s\n", a); 
    return 0; 
} 
予想通り

出力:

FOOBAR 


C関数

#include <ctype.h> 
#include <stdio.h> 
#include <string.h> 

void strupp(char* beg) 
{ 
    while (*beg++ = toupper(*beg)); 
} 

int main(int charc, char* argv[]) 
{ 
    char a[] = "foobar"; 
    strupp(a); 
    printf("%s\n", a); 
    return 0; 
} 

出力は

OOBAR 

を逃す最初の文字と、予想される結果であるCにコンパイル中に結果が切り捨てられます、なぜ誰でも知っていますか?

+5

これを実際に 'C++'で実行したければ: 'std :: transform(a、a + STRLEN(a)は、STD :: TOUPPER);あなたは、これは文字列を大文字に変換することが期待なぜ ' – PaulMcKenzie

+0

あなたは説明できますか?具体的には、なぜあなたは '= 'の右側が左より前に評価されると思いますか? –

+0

私はフィードバックを与えたすべての人々に感謝していと –

答えて

29

問題にはシーケンスポイントは、だから我々は、未定義の動作をしている

while (*beg++ = toupper(*beg)); 

に存在しないことです。どのようなコンパイラは、このケースではやっていることはC++で、それはそれを他の方法をやっているCでtoupper(*beg)beg++を評価しています。

+0

これは、古典的なC文字列をコピーする一方ライナー 'while(* s ++ = * t ++);'は未定義の動作をしているということですか? –

+3

@markhいいえ、それは2つの異なる変数です。これは 'while(* s ++ = * s ++) 'と同義です。 – NathanOliver

+0

@SteveJessop実際には' while(* s ++ = * t ++); 'は' s == t'でも動作を定義しています。 'strcpy'が重複領域で定義されていないのは、' strcpy'が必ずwhile(* s ++ = * t ++);で実装されているわけではないということです。 – immibis

15
while (*beg++ = std::toupper(*beg)); 

は未定義の動作につながります。 std::toupper(*beg)が指定されていない前または後に*beg++を配列決定されているかどうか

簡単な修正を使用することです:

while (*beg = std::toupper(*beg)) 
    ++beg; 
10

ライン

while (*beg++ = toupper(*beg)); 

二回使われているエンティティの副作用が含まれています。 beg ++が* begの前か後に実行されるかはわかりません(toupper内)。あなたは、私はそれがC++のために同じですかなり確信しているとして、両方の実装は、両方の行動を示すことだけでラッキー。 (ただし、私はのかどうか分からないCのためのいくつかのルールの変更++ 11、があった - まだ、それは悪いスタイルだ。)

ただ、条件のうち、BEGを++移動:

while (*beg = toupper(*beg)) beg++; 
3

と'f'は関数の中で決して渡されません:

 while ((*beg = (char) toupper(*beg))) beg++; 
+0

キャストto charは重要です。int型の値が受信側の型charに収まらない場合があります。 – vishal

+1

このキャストは、とにかくそれがなければ起こりえないことは何も実現しません。 – Flexo

関連する問題