Почему есть мусор, значение которого идет после strrev в C? - PullRequest
0 голосов
/ 12 апреля 2020

Есть код моего друга, и я смотрю на это. Это простой пример использования функции string, и я чувствую, что это не просто. Проблема в части (5).

Это код.

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

void reverse(char *str1, char *str2) {
     str1 = strrev(str2);
     printf("%s\n\n", str1);    //**It's a test.**
}

int main() {
    char str1[100];
    char str2[100];
    char str3[100];
    char str4[100];
    char temp[100];
    int len1, len2, len3, len4;

    //(1) use scanf()
    printf("(1) str1 : ");
    scanf("%s", &str1);
    printf("    str2 : ");
    scanf("%s", &str2);

    //(2) exchange, print()
    strcpy(temp, str1);
    strcpy(str1, str2);
    strcpy(str2, temp);
    printf("(2) str1=%s str2=%s\n", str1, str2);
    printf("len1=%d len2=%d\n", strlen(str1), strlen(str2));

    //(3) copy, print()
    strcpy(str3, str2);
    printf("(3) str3=%s\n", str3);

    //(4) strcat()
    strcat(str3, " ");
    strcat(str3, str1);
    strcat(str3, " My name is Elsa");
    printf("(4) str3=%s\n", str3);
    printf("len3=%d\n", strlen(str3));

    //(5) reverse(str4,  str3), print str4
    reverse(str4, str3);
    printf("(5) str4=%s\n", str4);    //**I don't know here**
    printf("len4=%d\n", strlen(str4));

    return 0;
}

и это результат.

enter image description here

Почему существует значение мусора?

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

В этом вызове

reverse(str4, str3);

массив str4 передается по значению. Таким образом, выражение str4, используемое в качестве аргумента, преобразуется во временный указатель на первый элемент массива.

Таким образом, функция reverse имеет дело с этим временным объектом, который используется в качестве инициализатора параметра. функции.

Изменение этого параметра (локальной переменной функции) не влияет на содержимое исходного массива. Оно остается неизменным.

То есть в этом выражении внутри функции

str1 = strrev(str2);

фактически указатель str2 назначен указателю str1. Строка, на которую указывает указатель str2, будет изменена. Что касается указателя str1, то теперь он указывает на ту же строку, что и указатель str1, и он не будет активен после выхода из функции.

Функция может быть определена, например, следующим образом, если вы хотите изменить строку, на которую указывает первый параметр функции

void reverse(char *str1, char *str2) {
     strcpy( str1, strrev(str2) );
     printf("%s\n\n", str1);    //**It's a test.**
}

Однако функция не имеет большого смысла, потому что она инвертирует две строки одновременно.

Если вы хотите скопировать содержимое строки, на которую указывает второй параметр функции, в массив, на который указывает первый параметр функции, тогда определение функции может выглядеть следующим образом:

void reverse( char *str1, const char *str2 ) 
{
     strcpy( str1, str2 );

     strrev( s1 );

     printf("%s\n\n", str1);    //**It's a test.**
}

В этом случае строка, на которую указывает указатель str2 не изменится, а массив, на который указывает указатель str1, получит обратную строку, на которую указывает указатель str2.

0 голосов
/ 12 апреля 2020

Вместо этого ваше объявление функции должно выглядеть следующим образом:

void reverse(char **str1, char *str2)

, поэтому не нужно выполнять операцию только локально.

...