Обратная функция не работает должным образом - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь выяснить программу: «Напишите функцию reverse (s), которая переворачивает строку символов s. Используйте ее, чтобы написать программу, которая переворачивает свой ввод на строку за раз».

Я думал, что псевдокод, подобный следующему, должен работать:

"копировать строку s в tmp, увеличивая итератор. Копировать строку tmp в s, уменьшая начальный итератор, увеличивая новый"

#include <stdio.h>

void reverse(char []);

int main(){
    char string[50]="HelloWorld";
    printf("Consider Given string: %s\n",string);
    reverse(string);
    printf("The same string, reversed: %s\n",string);
}

void reverse(char s[]){
    char tmp[50];
    int i,j;
    for (i=0;(tmp[i]=s[i])!='\0';++i);
    for (j=0;i>0;i--,j++)
        s[j]=tmp[i];
}

В качестве вывода я получаю:

pi@readonly:~/new$ a.out
Consider Given string: HelloWorld
The same string, reversed: 

Когда, отлаживая с помощью gdb, заметил следующее:

Breakpoint 5, reverse (s=0x7efff5a4 "HelloWorld") at 1.c:18
18                              s[j]=tmp[i];
1: j = 0
2: i = 10
3: tmp = "HelloWorld", '\000' <repeats 15 times>, "\360\377v\334\365\377~\340\372\353v\000\000\000\000\224\365\377~,\006\001\000\300\004"
4: s = 0x7efff5a4 "HelloWorld"
(gdb) n
17                      for (j=0;i>0;i--,j++)
1: j = 0
2: i = 10
3: tmp = "HelloWorld", '\000' <repeats 15 times>, "\360\377v\334\365\377~\340\372\353v\000\000\000\000\224\365\377~,\006\001\000\300\004"
4: s = 0x7efff5a4 ""
(gdb) n

Breakpoint 5, reverse (s=0x7efff5a4 "") at 1.c:18
18                              s[j]=tmp[i];
1: j = 1
2: i = 9
3: tmp = "HelloWorld", '\000' <repeats 15 times>, "\360\377v\334\365\377~\340\372\353v\000\000\000\000\224\365\377~,\006\001\000\300\004"
4: s = 0x7efff5a4 ""

Вопросы:

1) Почему строковые элементы, перечисленные в строке tmp, внезапно исчезли из строки s в тот момент, когда i=0, но был там до этого шага?Другими словами, что случилось со строкой s в точке останова 17, for (j=0;i>0;i--,j++)?

2) Можно ли объявлять и назначать различные типы функций в одном и том же цикле for, используя запятую?Другими словами, почему приведенная ниже конструкция дает ошибку при попытке компиляции?Есть ли способ смешивать разные типы идентификаторов в одном цикле?

Конструкция:

void reverse(char s[]){
    for (char tmp[50],int i=j=0;(tmp[i]=s[i])!='\0';++i);
    for (j=0;i>0;i--,j++)
        s[j]=tmp[i];
}

Ошибка:

pi@readonly:~/new$ cc 1.c
1.c: In function ‘reverse’:
1.c:14:21: error: expected identifier or ‘(’ before ‘int’
for (char tmp[50],int i=j=0;(tmp[i]=s[i])!='\0';++i);
                 ^~~
1.c:14:36: error: ‘i’ undeclared (first use in this function)
for (char tmp[50],int i=j=0;(tmp[i]=s[i])!='\0';++i);
                                ^
1.c:14:36: note: each undeclared identifier is reported only once for each function it appears in
1.c:15:8: error: ‘j’ undeclared (first use in this function)
for (j=0;i>0;i--,j++)
    ^
1.c:16:9: error: ‘tmp’ undeclared (first use in this function)
s[j]=tmp[i];

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

C-строка оканчивается символом \0, а ваша функция reverse копирует этот символ завершения строки с конца исходной строки в начало целевой строки.Тогда целевая строка будет «пустой», так как она заканчивается в самом начале.

Вам нужно будет учесть две вещи:

Сначала начните с одной до конца при доступе к tmp:

for (j=0;i>0;i--,j++)
    s[j]=tmp[i-1];

Во-вторых, убедитесь, что целевая строка завершена.Если целевая строка совпадает с исходной строкой, ничего не остается делать, поскольку \0 уже на месте.

Если вы каким-либо образом скопировали в другую цель, вам придется написать s[j]='\0'после цикла.

0 голосов
/ 05 февраля 2019

В начале этого цикла:

for (j=0;i>0;i--,j++)
    s[j]=tmp[i];

tmp[i] содержит завершающий нулевой байт в конце строки.Таким образом, вы копируете этот нулевой байт в начало s, давая вам пустую строку.

Вычтите 1 из значения i при индексации tmp.Таким образом, вы начинаете с последнего обычного символа и заканчиваете первым.

for (j=0;i>0;i--,j++)
    s[j]=tmp[i-1];
...