Kopiowanie jednej tablicy do drugiej


(marcinkk) #1

chciałbym skopiować wyraz o długości a z tablicy_1 o i indeksie x do tablicy_2 jak mam to zrobić?? czytałem ze niemożna kopiować tablic przez przypisanie ale sposób musi być jakiś na takie skopiowanie.


(adpawl) #2

A może tak łąskawie napiszesz jakiego języka dotyczy to pytanie?


(marcinkk) #3

programuje w javie ale zadowolę sie tez odpowiedzią w c++


(Komputerowiec21w) #4

Rozwiązanie w C++.

Przez przypisanie typu

int tablica_1[10];

int tablica_2[10];

// ... wypelniamy w jakis sposob tablice_1

tablica_2 = tablica_1;

rzeczywiście się nie da.

Owszem, jest. Wystarczy napisać odpowiednią funkcję. Funkcję tę najlepiej zrealizować w postaci szablonu, by działała dla wszystkich typów (zarówno wbudowanych, jak i zdefiniowanych przez użytkownika).

template 

void kopiuj(typ* tabl_1, typ* tabl_2, int indeks)

{

for (int i = 0 ; i < indeks ; i++) tabl_2[i] = tabl_1[i];

}

Jak widać funkcja jest bardzo prosta, znajduje się w niej tylko pętla for przypisująca kolejnym elementom tabl_2 wartości odpowiednich elementów tabl_1. Jako argumenty funkcja przyjmuje wskaźniki do tych dwóch tablic oraz indeks graniczny (skopiowane zostaną wartości o indeksach od 0 do indeks). Po bardzo prostej przeróbce funkcji można umożliwić jej kopiowanie wartości o indeksach od a do indeks.

void kopiuj(typ* tabl_1, typ* tabl_2, int a, int indeks)

{

for (int i = a // ... itd.

Jak widać, wystarczy tylko dodać jeden argument funkcji i zmienić definicję wewnętrznej zmiennej i.

Edit: poprawiony błąd zauważony w poście niżej.


(Marcin Obala) #5

Do postu wyżej, jak 'a' będzie większe od "indeks" nic się nie stanie bo na wejściu warunek i


(Fiołek) #6

gallez , tylko po co pisać taką funkcje, jeśli już jest? memcpy(obojętnie jaki typ), strcpy(dla ciągów znaków).


(Komputerowiec21w) #7

Fiołek , chociażby po to, żeby zrozumieć mechanizm (który jest notabene wyjątkowo prosty). Poza tym nie wiedziałem o istnieniu funkcji memcpy (strcpy znam, ale ona działa tylko dla tablic znakowych). Pomijam już sam fakt, że memcpy nie umożliwia kopiowania elementów o określonych indeksach ze środka tablicy.


(Fiołek) #8

gallez , umożliwia, np. tak:

int tab1[3] = {0, 1, 2};

int tab2[4] = {5};

memcpy(((int *)tab1) + 1, ((int *)tab2) + 2, sizeof(int));

Powyższy kod skopiuje element o indeksie 1 z tablicy tab1 do elementu tablicy tab2 o indeksie 2.


(Marcin Obala) #9

To najgłupsza metoda jaką widziałem. Nie ma to jak sobie utrudnianie życia. Jakby ktoś chciał tak robić to może sobie napisać tab2[2]=tab1[1];

zamiast tego co na górze wypisałeś. A co do galleza to on miał na myśli to żeby skopiować z tablicy1 elemetny np. od 4 do 9 do drugiej tablicy.


(Gina Gina) #10

Niestety tym co napisałeś okreśłiłes Swój poziom wiedzy i umiejętności, ;/

"metoda" wskazana przes Fiołka to podstawa wszelkich przemieszczeń - podstawowa jej cecha to szybkość wykonania,

istotna gdy chodzi o czas, :spoko:

gdy tymczasem "Twoja metoda" to zastosowanie prostych pomysłów rodem z Basica ;/

Opanuj operacje blokowe - bez tego nie da się sprawnie pracować :wink:


(Marcin Obala) #11
#include

int main()

{

	int tab1[3] = {0, 1, 2};

	int tab2[4] = {5};

	for(int i=0;i<5000000;i++)

	{

		memcpy(((int *)tab1) + 1, ((int *)tab2) + 2, sizeof(int));

	}

}

real 0m0.283s user 0m0.248s sys 0m0.004s

#include

int main()

{

	int tab1[3] = {0, 1, 2};

	int tab2[4] = {5};

	for(int i=0;i<5000000;i++)

	{

		tab2[2]=tab1[1];

	}

}

real 0m0.054s

user 0m0.016s

sys 0m0.000s

Nie wiem o jakiej prędkości wykonania mówisz ale na pewno nie o takiej prędkości. I jaka tu logika mówić o czymś takim osobie która zaczyna zabawę z c++ ? Tak jakby dziecku tłumaczyć fizykę kwantową. A czy Ty wiedziałaś (nick i avatar sugeruje, że dziewczyna/kobieta) na początku swojej drogi z programowaniem co to są operacje blokowe ? Co to listy, co to grafy albo nawet proste drzewo binarne ? Nie, i autor tego tematu patrząc na to o co pyta też tego nie wie więc nie ma sensu mówić mu takich rzeczy. Nauczy się tego wszystkiego w odpowiednim czasie.

:edit:

I pewnie za chwile dostanę odpowiedź że funkcją memcpy nie trzeba używać pętli która będzie kopiowała kolejne elementy tylko wystarczy dać

memcpy(xxx,xxx,w tym miejscu)

odpowiednią warość żeby skopiować całą tablicę. Ja o tym wiem ale on o tym nie wie. Znacznie łatwiej jest poczatkującemu zapamiętać że wystarczy napisać pętlę która będzie po kolei kopiowała elementy. I na pewno nie pisze żadnego programu dla firmy czy gdzieś tylko po to żeby załapać o co w tym chodzi, a jak takie mądre głowy jak wy (bo przyznaje że wiecie więcej ode mnie) zaczną mieszać w głowach to można kogoś zniechęcić.


(Gina Gina) #12

Przykłady przedstawionego porównania zawierają oczywisty błąd co do sposobu użycia memcpy,

stąd uzyskane kuriozalne czasy ;/

Powinno się - stosując Twoją metodę - porównać - czas kopiowanie tablicy 5 000 000 elementów, w pętli, element po elemencie, z pojedyńczym wywołaniem memcpy dla liczby elementów 5 000 000.

Wywołanie memcpy w pętli, w Twoim wykonaniu to kuriozum :PPP i kompletny antyprzykład użycia,

coś jak wożenie pojedyńczych źdźbeł trawy z sterty siana, każde z osobna, z użyciem cięzarówki :rotfl2:

PS

I wcale nie tłumaczy Cię to że na końcu postu ujmujesz to prawidłowo, skoro przykład jest jednoznacznie skopany ;/

i mniej zorientowani odniosą całkowicie fałszywe wrażenie :roll:

PS2

:rotfl2:

gina to imię mojego psa -bardzo miłej suczki rasy bokser :PPP , a avatar wybrałem taki, by przy skrolowaniu

strony łatwo zauważyć swoje posty :smiley:


(system) #13
memcpy(tablica_1,tablica_2,sizeof(tablica_1));

w niektórych kompilatorach koniecznie:

memcpy((void*)tablica_1,(void*)tablica_2,sizeof(tablica_1));

... pod warunkiem, że tablice są zdefiniowane w tym samym zakresie w którym robimy to kopiowanie, oraz ich rozmiar jest taki sam.

Typ może być dowolny.


(Komputerowiec21w) #14
int tab1[3] = {0, 1, 2};

int tab2[4] = {5};

memcpy(((int *)tab1) + 1, ((int *)tab2) + 2, sizeof(int));

Wszystko pięknie, ale zawarte w wywołaniu funkcji rzutowania i wyrażenia typu ((int*)tab2)+2 powodują, że funkcja jest wykonywana jeszcze dłużej. Różnica niby nieznaczna, ale przy kilku tysiącach wywołań staje się widoczna.


(adpawl) #15

Podczepka z prosbą o pomoc w odrobieniu zadania wraz z odpowiedziami, została przeniesiona do śmietnika.

Przypominam, nie pomagamy w odrabianiu zadań, prac domowych, dyplomowych, magisterskich etc. -czytać regulamin.


(somekind) #16

Uściślając - pomagamy, ale nie robimy gotowców. Na podstawie sensownie zadanego pytania nie da się stwierdzić, czy jest zadane z ciekawości, czy dotyczy ono pracy domowej.

Oczywiście zdarzają się tacy, który ciągle dają gotowce i nie boją się moderacji, która tego punktu regulaminu nie egzekwuje, ale to już nie moja broszka.