2017-01-09 14 views
3

:私は文字列を変更したい場合は文字列変更関数:return voidまたはchar *?例えば

void foo1(char *buffer) { 
    buffer[0] = 'a'; 
} 

char *foo2(char *buffer) { 
    buffer[0] = 'a'; 
    return buffer; 
} 

私が行うことができます:

mystr[] = "foobar"; 
foo1(mystr); 
printf("%s",mystr); 

または戻り値使用:

mystr[] = "foobar"; 
char *mystr2; 
mystr2 = foo2(mystr); 
printf("%s",mystr2); 

私は少し混乱していますが2番目の方法:mystrとmystr2は別の場所を指していますが、同じ文字列を保持しています。私はfoo2が変更されたmystrのアドレスをmystr2にコピーすると思います。代わりに何が起こるのですか?

2番目の質問は、文字列を変更する方が標準ですか?

+1

2番目の例では、 'mystr'が変更され、' mystr2'が 'mystr'を指しています。2番目の例でも 'mystr'を印刷してみてください。 –

+0

明確ではなく、広範囲に広がっています。質問ごとに1つの質問。 – Olaf

+1

あなたの2番目の質問については、答えは「両方」と「なし」です。どちらが "最高"(非常に主観的)かは、ユースケースによって異なります。 2番目の方法では、たとえば次のことができます。 'printf("%s "、foo2(mystr))'は*いくつかの状況では役に立ちますが、他の状況では役に立たないでしょう。 –

答えて

4

より規格である文字列を変更する方法はありますか?

ヘッダで宣言された標準のC文字列関数は、通常、ターゲット文字列へのポインタを返します。これにより、文字列関数を連鎖させることができます。たとえば、2番目の関数定義に対して、

printf("%s", foo2(mystr)); 

が出力され、変更されたソース文字列が出力されます。このコードで

引数が暗黙的にその最初の文字へのポインタに変換される関数に渡された文字列

char mystr[] = "foobar"; 
char *mystr2; 
mystr2 = foo2(mystr); 
printf("%s",mystr2); 

をスニペット。そして配列の最初の文字へのポインタである呼び出された関数から同じアドレスが返されます。従って、この文

mystr2 = foo2(mystr); 

ポインタmysstr2後も、文字配列mystrの最初の文字を指します。

printfを呼び出すことができる機能のいずれかのような

printf("%s",mystr); 

など

printf("%s",mystr2); 

同じアドレスは、関数に渡された場合の両方で機能して、再度文字列に渡されるため、最初のケースのprintfは暗黙のうちにその最初の文字へのポインタに変換されます。

1

私はあなたが常に返された値を無視することができ、そしてそれはより柔軟だ

char *foo(char *str); 

をお勧めします。あなたは、関数のパラメータとして

void foo(char *str); 

を使用することはできません。

int someFunc(char *val); 
... 
int rc = someFunc(foo(data)); 
+0

ポインタを関数のパラメータとして返す関数の結果を使うと、本当に悪いことがあります。そしてあまりにも醜いです、コードを読むのが難しくなり、他のものも。私は、何人かのプログラマーが何のためにもコードを読むことができないように気をつけている理由を理解していません。 「*より少ない変数」と言っているように、その利点は何ですか? –

+2

'strcat'を考えてみましょう。読みやすさの観点からは、 'print(a + b)'というより、むしろそれを全く持たないでしょう。しかしCでは選択肢がないので、 'strcat(a、b)'と書く必要があります。 'strcat'がvoid関数であった場合、' strcat(a、b);と書く必要があります。 print(a) '問題を見ますか?ここでの意図はあまり明確ではありません。私たちは何をしているのか正確に書いていますが、私たちが何をしているのかを再構築しなければなりません。 'print(strcat(a、b))'は、私たちがやろうとしていることを表現するのに非常に近くなります。 – Arkadiy

+1

これは、あまりにも多くの単語なしで、何が尋ねられたのかを正確に返答しました。 – linuxfan

関連する問題