program z CSTRINGami
Ostatnio zmodyfikowano 2011-10-31 13:41
Kaniorek Temat założony przez niniejszego użytkownika |
program z CSTRINGami » 2011-10-31 10:50:53 Cześć,napisałem sobie taką oto funkcję: void strcpy( char cel[], char zrodlo[] ) { for( int i = 0;; i++ ) { cel[ i ] = zrodlo[ i ]; if( cel[ i ] == 0 ) break; } } Ma ona za zadanie przekopiować tekst z tablicy pierwszej do tablicy drugiej. No i to działa. Jednak ja bym chciał aby przekopiowała ona jedynie co drugi znak. Próbowałem w ten sposób: void strcpy( char cel[], char zrodlo[] ) { for( int i = 0;; i += 2 ) { cel[ i ] = zrodlo[ i ]; if( cel[ i ] == 0 ) break; } } Jednak rezultatem działania tego są jakieś dziwne znaczki. Prosiłbym o nakierowanie mnie jak to zrobić poprawnie. Druga sprawa, mam taki program: #include <iostream> using namespace std;
int main() { int tab[ 5 ]; int * wsk; for( int i = 0; i < 5; i++ ) { tab[ i ] = i; } cout << "Wyswietlenie wartosci tablicy: " << endl; for( int i = 0; i < 5; i++ ) { cout << "tab[" << i << "] " << tab[ i ] << endl; } wsk = & tab[ 0 ]; cout << "A teraz wyswietlam co drugi element tablicy: " << endl; for( int i = * wsk; i < 5; i += 2 ) { cout << "tab[" << i << "] " << tab[ i ] << endl; } } Ma on za zadanie wyświetlić co drugi element tablicy (za pomocą wskaźników) moje pytanie brzmi czy jest on poprawnie napisany. Owszem działa tak jak ma ale czy ogólnie kod jest poprawny czy można zrobić to jeszcze szybciej? |
|
akwes |
» 2011-10-31 11:11:49 void strcpy( char cel[], char zrodlo[] ) { for( int i = 0;; i += 2 ) { cel[ i ] = zrodlo[ i ]; if( cel[ i ] == 0 ) break; } }
Prześledź jak działa. Dokładnie prześledź. // SPOJLER Bo popatrz i skacze co 2 tak? czyli cel[0] cel[2] cel[4] a co z cel[1] cel[3] ? One zostają pominięte i mają losowe śmieci z pamięci. Potrzebujesz dwóch zmiennych, jedna idąca co jeden w celu, a druga idąca co dwa (masz już ją) w źródle :) Pamiętaj aby uważać czy nie przeskoczysz znaku 0 (czyli w warunku ta zmienna idąca co 1 a nie co 2) Co do programu to zrobiłeś tam bajkę z innego wymiaru : ) Przede wszystkim źle używasz wskaźnika. Jest niepotrzebne, for( int i = * wsk; i < 5; i += 2 )
a to działa tylko dlatego że *wsk pokazuje na pierwszy element tablicy o wartości 0. Jeżeli tablica by miała elementy np. wszystkie po 20 to już by nie działało. Nazwa tablicy jest wskaźnikiem na jej pierwszy element |
Wyrażenie tab[3] jest równoważne *(tab+3). Przy czym pierwsze to odwołanie się przez indeks a drugie przez wskaźnik. Wiedząc o tym, spróbuj przepisać tę pętlę na wskaźniki: for( int i = 0; i < 5; i++ ) { cout << tab[ i ] << '\n'; }
|
|
Kaniorek Temat założony przez niniejszego użytkownika |
» 2011-10-31 12:01:50 Nie bardzo rozumiem o co Ci chodzi. To znaczy owszem, mam pojęcie o tym co mówisz ale nie mam pojęcia jak mam to teraz przełożyć na c++ :) Mógłbyś pokazać i dzięki analizie takiego przykładu się czegoś nauczę:)
Piszesz, że program działa tylko dlatego, iż wskaźnik ustawiłem na zerowy element (adres) tablicy i, że w wielowymiarowych by nie działało. Ale to wtedy bym innego sposobu szukał a mnie teraz chodziło o tablice jednowymiarowe... |
|
akwes |
» 2011-10-31 12:15:05 Ale ja nawet nie użyłem słowa wielowymiarowe :P Wczytaj się dokładnie. Co do strcpy masz dwie możliwości, osobna zmienna, albo zmienna w pętli for czyli : void strcpy( char cel[], char zrodlo[] ) { int j = 0; for( int i = 0;; i += 2 ) { cel[ j ] = zrodlo[ i ]; if( cel[ j ] == 0 ) break; j++; } }
albo void strcpy( char cel[], char zrodlo[] ) { for( int i = 0, j = 0;; i += 2, j++ ) { cel[ j ] = zrodlo[ i ]; if( cel[ j ] == 0 ) break; } }
Rozwijając wypisywanie tablicy. Tablicę uzupełniasz wartościami tak: for( int i = 0; i < 5; i++ ) { tab[ i ] = i; }
Czyli w tablicy kolejne elementy tab[0] jest równe 0 tab[1] jest równe 1 tab[2] jest równe 2 tab[3] jest równe 3 tab[4] jest równe 4 Potem robisz Czyli wsk pokazuje na tab[0] for( int i = * wsk; i < 5; i += 2 )
Tu używasz instrukcji int i = *wsk Czyli faktycznie napisałeś coś takiego int i = *( & tab[ 0 ] ); czyli int i = tab[ 0 ]; a tab[0] jest równe ile :P? (patrz wyżej) jest równe 0. Czyli napisałeś w taką pętlę for( int i = 0; i < 5; i += 2 )
Sprawdź co się stanie jak będzie inna tablica np. jak zamiast tab[ i ] = i , dasz taką tablicę: for( int i = 0; i < 5; i++ ) { tab[ i ] = 20; }
Mówiąc że nie będzie działać na innej tablicy nie mam na myśli wielowymiarowej :P Ale każdej takiej której element tab[0] ma wartość inną niż 0 :P Wyżej to opisałem dokładnie. //edit Tak sobie pomyślałem że może w tym strcpy co dwa nie potrzeba dodatkowej zmiennej i być może działało by to void strcpy( char cel[], char zrodlo[] ) { for( int i = 0;; i += 2 ) { cel[ i / 2 ] = zrodlo[ i ]; if( cel[ i / 2 ] == 0 ) break; } }
Więc są dwie wersje :) Jedna wymaga więcej pamięci, mniej procesora a druga więcej procesora ale mniej pamięci :) |
|
Kaniorek Temat założony przez niniejszego użytkownika |
» 2011-10-31 13:41:23 Okej, dzięki za pomoc :) Ale to w takim razie jak mam te pętle z tym wyświetlaniem co drugi element tablicy edytować? Jak mam pokazać wskaźnikowi, że chce wskazać po prostu na dowolny element nie zakładając, że w nim jest wpisana jakaś liczba np. 0 tak jak mówisz... Zrobiłem to w taki sposob: int main() { int * wsk; int tab[ 10 ]; for( int i = 0; i < 10; i++ ) { *( wsk += 2 ) = 20; } for( int k = 0; k < 10; k += 2 ) { cout << * wsk << endl; } }
I wyświetla nawet jak pierwszy element to 20...gorzej teraz jak zamiast tego 20 wpiszę po prostu 'i'. Bo wtedy cała tablica zapełnia się 9ątkami. Nie wspomnę już o tym, co się dzieje jak *(wsk+=2) zmienię na *(wsk++) i tam przypiszę 'i'. Wtedy po prostu tablica zapełnia mi się adresami komórek w pamięci. |
|
« 1 » |