Funkcja zwracająca napis nie działa

0

Witam chciałbym żeby funkcja char* rev(char *str) odwróciła mi napis. (funkcja musi mieć dokładnie taką postać ) ale w moim programie

#include <iostream>
using namespace std;
char* rev(char *str){
      char napis [10] = 'jakis tam napis';
      return napis;
      }
int main(){
  char str1[] = "Witaj", *str2;

 cout << str1 << endl;    // Witaj cpp

 str2 = rev(str1);
cout << str2 << endl; 
 system("PAUSE");   
} 

funkcja nie zwraca jakis tam napis tylko Witaj.
Dlaczego tak się dzieje i jak mogę temu zaradzić?

3

Dzieje się tak, dlatego że robisz dwatrzy przerażające (hm) błędy:

'jakis tam napis'

To że to działa to jeden z cudów języka C/C++, który przydaje się czasami, ale ma też efekt uboczny którym jest wprowadzanie w błąd tych którzy o tym nie wiedzą ;)
W każdym razie prawdopodobnie kompilator rzucił czymś w rodzaju warning: character constant too long for its type [enabled by default] .

Powinno być oczywiście

"jakis tam napis"

Po drugie, zwracasz wskaźnik do lokalnej tablicy. Nigdy tak nie rób, czasami zadziała przez przypadek ale to zawsze błąd (ogólnie, zwracanie wskaźnika do lokalnej zmiennej to błąd) - musisz to zrobić inaczej. W Twoim przypadku, najlepiej odwracać napis w miejscu (bez użycia dodatkowej pamięci).

i po trzecie, ten napis jakby nie patrzeć jest dłuższy niż 10 znaków...

3
#include <iostream>
using namespace std;

char *rev(char *str)
  {
   char *p=str,*q=p;
   while(*q) ++q;
   while(p<--q) { char ch(*p); *p++=*q; *q=ch; }
   return str;
  }

int main()
  {
   char str[]="Witaj"; 
   cout<<str<<endl;
   cout<<rev(str)<<endl; 
   cin.get();
   return 0;
  }
4
_13th_Dragon napisał(a):
#include <iostream>
using namespace std;

char *rev(char *str)
  {
   char *p=str,*q=p;
   while(*q) ++q;
   while(p<--q) { char ch(*p); *p--=*q; *q=ch; }
   return str;
  }

int main()
  {
   char str[]="Witaj"; 
   cout<<str<<endl;
   cout<<rev(str)<<endl; 
   cin.get();
   return 0;
  }

Ten kod jest nie tylko źle, za takie coś powinien być zakaz zbliżania się do kompilatora.

To jest nieczytelne i całkowicie bez sensu. Jednoznakowe nazwy zmiennych, masa gwiazdek, minusów, wiele instrukcji w jednej linii. Gorszego kodu chyba nie można sobie wyobrazić.

Gdy tym czasem wprost napisana funkcja:

char *rev(char *str) {
  const std::size_t length = std::strlen(str);
  for (std::size_t i = 0; i < length / 2; ++i) {
    std::swap(str[i], str[length - i - 1]);
  } 
  return str;
}

Po co to. Co daje maksymalnie nieczytelny kod? Myślisz, że ktoś się czegoś z tego nauczy? Chyba tylko tego, jak nie programować. Ile szybkości na tym zyskujesz? Większość Twoich rozwiązań jakie widzę na tym forum tak wygląda. Dlaczego? Nie potrafię tego zrozumieć.

Jeżeli ktoś liczy cykle, bo musi, to może jest to uzasadnienie, żeby używać takiego kodu. Ale nawet wtedy da się napisać to czytelnie! Czy ten wątek jest jednak o tym?

Co do rzekomej wydajności. Ja wyniki mam takie:

rev1: h4xi0r
3404 ms
rev2: plain c++
2012 ms

(GCC 4.7.2, -O2 -march=native, Phenom II 3.2 GHz)

Króciutki opis testu i kod: Który kod jest bardziej czytelny

1
 
char *rev(char *str)
  {
   char *p=str,*q=p;
   while(*q) ++q;
   while(p<--q) { char ch(*p); *p++=*q; *q=ch; }
   return str;
  }

Nawet jeśli to działa to jest okropność. Nawet jeśli wiesz za co odpowiadają konkretne zmienne w tym momencie, spróbuj przeanalizować ten program za rok. Poczujesz się jak my.

0

A mógłbyś mi wytłumaczyć co dzieje się w tym programie bo nie jestem w stanie chodzi mi o tą część

while(p<--q) { char ch=*p; 
*p++=*q; 
*q=ch; } 
0

q to wskaźnik ostatniego elementu, a p pierwszego. p++ przesuwa wskaźnik na następny element --q na poprzedni. ch jest zmienną pomocniczą, która pozwala zamienić wartości ukryte pod adresami p i q;

1 użytkowników online, w tym zalogowanych: 0, gości: 1