2016-12-07 9 views
1

は、だから、私はreverse機能がstr1を返す一部を除いて、コードを理解してからstr1main機能で印刷されたC.別の関数によって返されたときのmain関数の変数アクセス?

に再帰を使用して文字列を反転させるために、インターネット上でこのコードを見ました。 str1は参照渡しではなく、アドレスによってのみ渡されました。だから、mainの機能を使って印刷すると、元の文字列ではなく、逆の文字列がどのように出力されるのでしょうか?

void reverse(char str1[], int index, int size); 

int main() { 
    char str1[20]; 
    int size; 

    printf("Enter a string to reverse: "); 
    scanf("%s", str1); 
    size = strlen(str1); 
    reverse(str1, 0, size - 1); 
    printf("The string after reversing is: %s\n", str1); 
    return 0; 
} 

void reverse(char str1[], int index, int size) { 
    char temp; 
    temp = str1[index]; 
    str1[index] = str1[size - index]; 
    str1[size - index] = temp; 
    if (index == size/2) { 
     return str1; 
    } else { 
     reverse(str1, index + 1, size); 
    } 
} 

答えて

0

最初に、あなたが示した機能が間違っています。空の文字列がこの

reverse(str1, 0, size - 1); 

のような関数に渡された場合、その後の式size - 1-1に等しくなります。結果として、これらのステートメントで配列を超えてメモリにアクセスしようとすると、関数は未定義の動作をします。

str1[index] = str1[size - index]; 
str1[size - index] = temp; 

この関数には2つの多くのパラメータがあります。文字列関数は通常、宛先文字列へのポインタを返します。したがって、関数reverseも文字列へのポインタを返す方が良いでしょう。

より簡単に定義できます。あなたは、この宣言

void reverse(char str1[], int index, int size); 

は、次の宣言

void reverse(char *str1, int index, int size); 
      ^^^^^^^^^^ 

と等価である質問については例

char * reverse(char *s, size_t n) 
{ 
    if (!(n < 2)) 
    { 
     char c = s[0]; 
     s[0] = s[n - 1]; 
     s[n - 1] = c; 

     reverse(s + 1, n - 2); 
    } 

    return s; 
} 

とするために、あなたは

printf("The string after reversing is: %s\n", reverse(str1, strlen(str1))); 

のようにそれを呼び出すことができます配列はこのような関数を渡した

reverse(str1, 0, size - 1); 

次に、配列指定子がその最初の要素へのポインタに変換されます。関数内では、配列はあるメモリ領域から別のメモリ領域に移動されません。それは同じアドレスにとどまります。配列の要素のみが変更されます。したがって、関数を終了した後、配列の要素は変更されますが、関数を呼び出す前に、配列内のものと同じアドレスをメモリ内に持ちます。実際、配列の要素は、配列の最初の要素へのポインタによる参照によって関数に渡されます。

0

この関数は何も返しません。最初の要素へのポインタとして配列を受け取ります(配列は、最初の要素へのポインタにを崩壊させます)。 void reverse(char str1[], int index, int size)という宣言はvoid reverse(char *str1, int index, int size)に相当します。

コードは複数の問題があります。

  • それもの長さの文字列に対して機能しません。それは空の文字列で未定義の振る舞いを呼び出します。

  • まともな理由で再帰を使用します。シンプルなループアプローチは簡単で、バグも少なくなりました。

  • voidと定義しても、return str1;という文があります。

この関数は何も返さず、最初の要素へのポインタとして配列を受け取り、その位置で転置を実行します。ここで

は単純代替です:

#include <stdio.h> 

char *reverse(char *str) { 
    for (size_t i = 0, length = strlen(str); i < length/2; i++) { 
     char temp; 
     temp = str[i]; 
     str1[i] = str1[length - i - 1]; 
     str1[length - i - 1] = temp; 
    } 
    return str; 
} 

int main(void) { 
    char buf[100]; 

    printf("Enter a string to reverse: "); 
    if (scanf("%s", buf) == 1) { 
     printf("The string after reversing is: %s\n", reverse(buf)); 
    } 
    return 0; 
} 
0

変数の参照は、それがアドレスまたはより正確にアドレスを保持する変数ですです。

refでオブジェクト/変数を渡すと、実際にはそのアドレスを渡します。Cの中で変数のポインタを渡すことで行います。たとえば、引数を渡すときに "ref"を宣言する必要があります。関数。

関連する問題