transmitere tablou 2d ca 1d

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

transmitere tablou 2d ca 1d

Post by viorel2005 » 26 Jan 2011, 11:42

Buna ziua!

Code: Select all

 unsigned char** bmp1;
	 bmp1=new unsigned char*[3];
	 for(int i=0;i<3;i++)
		 bmp1[i]=new unsigned char[2];
	 for(int i=0;i<3;i++)
		 for(int j=0;j<2;j++)
			 bmp1[i][j]=i+j;
si functia afis2

Code: Select all

void afis2(unsigned char* x,int len)
{
	for(int i=0;i<len;i++)
		printf("x[%d]=%d ",i,x[i]);
		
}
Cum transmit bmp1 functiei afis2 astfel incat sa am afisate toate elementele tabloului.

Multumesc anticipat,
Viorel



User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: transmitere tablou 2d ca 1d

Post by Marius Bancila » 26 Jan 2011, 12:33

Code: Select all

void afis2(unsigned char** bmp, int cols, int rows);
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: transmitere tablou 2d ca 1d

Post by viorel2005 » 26 Jan 2011, 12:43

Multumesc Marius. Numai ca eu doresc sa evit partea de copiere a unui tabloud 2D intr-un tablou 1D. Doresc pur si simplu transmiterea tabloului 2D prin referinta ca un tablou 1D.
Ceva de genul: afis2(bmp1); Am incercat afis2(&bmp) , dar fara sucees. Am inteles de ce, deoarece daca apela afis2 astfel: afis2(&(*bmp1)), afisarea era corecta. Totusi, aces lucru ma costa
M-1 apeluri de functie. Eu doresc un singur apel de functie.

User avatar
zlatomir
Membru++
Membru++
Posts: 282
Joined: 04 Jul 2009, 23:59
Location: Arad
Contact:

Re: transmitere tablou 2d ca 1d

Post by zlatomir » 26 Jan 2011, 13:15

viorel2005 wrote:...Numai ca eu doresc sa evit partea de copiere a unui tabloud 2D intr-un tablou 1D...
Pai eviti, pt ca transmiti (copiezi) numai pointer-ul la pointer nu tot ce contine array-ul.

Sau schimbi structura de date si folosesti un array cu o dimensiune.

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: transmitere tablou 2d ca 1d

Post by Andreas » 26 Jan 2011, 13:58

dupa cum ar canta Lenon, varianta nerd: "Imagine all the bytes!"

conceptual un tablou 2d este o structura complet diferita de 1d, chiar daca este compusa din aceleasi parti informationale, adica bytes; insa fara notiunile de rand si coloana ea nu mai exista ca si concept, sau se reduce definitiv la un tablou 1d...
ce este frumos, si posibil, este faptul ca poti sa imaginezi "transportul" de date(transmiterea la functia apelata) a informatiei din tablou ca un singur sir de bytes; prin referinta nu ai nevoie decat de inceputul sirului, adresa de start; prin valoare poti sa il transporti ca un tablou 1d...
problema este la reconstructia din "1d" in 2d, unde ai nevoie de informatiile despre rand si coloana...
de aceea Marius ti-a propus o varianta in acest sens...
daca vrei sa transmiti totul intr-un tablou 1d, este necesar sa impachetezi informatia despre randuri si coloane, in acelasi sir de bytes, sa zicem la inceputul sirului, dupa care sa urmeze informatia "utila" din tablou; ceva asemanator cu formatul unui bmp...

oricum, exemplul tau de a construi un tablou 2d cu pointer dublu e putin aiuritor si trebuie evitat la inceput, fiind dificil de interpretat/imaginat (chiar daca are avantajul optimizarii folosirii memoriei), ca dovada fiind faptul ca spui ca functia afis2(&(*bmp1)) afiseaza corect chiar apelata pentru fiecare element din tablou(ma indoiesc!); un tablou 2d "static" permite macar vizualizare lui ca un sir continuu de adrese, organizate in randuri si coloane....

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: transmitere tablou 2d ca 1d

Post by Silviu Ardelean » 26 Jan 2011, 14:17

Viorel, daca tot vrei sa folosesti bmp1, de ce nu-l folosesti ca membru al unei clase sau membru global (daca nu lucrezi OOP)? Atunci in functia ta de afisare il apelezi direct fara a-l mai pasa la functie.

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: transmitere tablou 2d ca 1d

Post by viorel2005 » 26 Jan 2011, 14:21

Functia care o folosesc din libraria Jbig este urmaoarea:

void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
int encode_planes,
const unsigned char *src, unsigned char **dest,
int use_graycode);
unde *src este imaginea sursa ca tablou 1D. De accea am nevoie sa stiu cum as putea transmite un tablou 2D alocat dinamic ca un tablou 1D cat mai eficient.

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: transmitere tablou 2d ca 1d

Post by Silviu Ardelean » 26 Jan 2011, 14:38

Pai spune asa... nu o lua prin invaluire. :)

User avatar
zlatomir
Membru++
Membru++
Posts: 282
Joined: 04 Jul 2009, 23:59
Location: Arad
Contact:

Re: transmitere tablou 2d ca 1d

Post by zlatomir » 26 Jan 2011, 14:50

Pai cel mai eficient e sa aloci direct array cu o dimensiune.
//In plus e mai eficient si din cauza ca nu o sa mai ai "bucla cu alocari"

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: transmitere tablou 2d ca 1d

Post by viorel2005 » 26 Jan 2011, 15:02

Corect, totusi chiar nu exista o solutie de a evita copierea intr-un array 1D?

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: transmitere tablou 2d ca 1d

Post by Marius Bancila » 26 Jan 2011, 15:39

Pai nu prea. Tabloul 2D e practic un tablou 1D care contine pointeri catre alte tablouri 1D, care se pot afla oriunde in memorie. Nu ai cum altfel, decat sa copiezi tablou cu tablou (sau rand cu rand, cum vrei sa zici) din taboul 2D in cel 1D.

Ce poti face e sa sari de la bun inceput peste tabloul 2D si sa folosesti unul 1D. Adica in loc de

Code: Select all

    unsigned char** bmp1;
    bmp1=new unsigned char*[3];
    for(int i=0;i<3;i++)
       bmp1[i]=new unsigned char[2];
    for(int i=0;i<3;i++)
       for(int j=0;j<2;j++)
          bmp1[i][j]=i+j;
sa ai

Code: Select all

    unsigned char* bmp1;
    bmp1=new unsigned char[rows * cols];
    for(int i=0;i<rows;i++)
       for(int j=0;j<cols;j++)
          bmp1[i * cols + j] = i+j;
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: transmitere tablou 2d ca 1d

Post by viorel2005 » 26 Jan 2011, 16:28

Folosirea functiei memcpy pentru a copia linie cu linie intr-un tablou 1D ar fi mai eficienta?
Am incercat asa ceva:

Code: Select all

#include "stdafx.h"
#include <conio.h>
void afis(int** x,int l1,int l2);
void afis2(int* x,int len);
void afis(int** x,int l1,int l2)
{
	for(int i=0;i<l1;i++)
		{
			for(int j=0;j<l2;j++)
				printf("x[%d][%d]=%d ",i,j,x[i][j]);
			printf("\n");
		}
}
void afis2(int* x,int len)
{
	for(int i=0;i<len;i++)
		{
			 printf("x[%d]=%d ",i,x[i]);
			 if (i%3==2)
				 printf("\n");
		}
		
}

int _tmain(int argc, _TCHAR* argv[])
{
	 int** bmp1;
	 bmp1=new int*[4];
	 for(int i=0;i<4;i++)
		 bmp1[i]=new int[3];
	 for(int i=0;i<4;i++)
		 for(int j=0;j<3;j++)
			 bmp1[i][j]=i+j;
	 int* bmp2;
	 bmp2=new int[12];
     for(int i=0;i<4;i++)
		 memcpy(bmp2+i*3*sizeof(int),&(*bmp1[i]),3);
		 afis2(bmp2,12);
		 afis(bmp1,4,3);
	
 	 _getch();
	return 0;
}
Problema este ca daca schimb int cu char totul merge bine. Cum fac memcpy sa mearga si cu int?
Folosesc Visual C++ 2010.

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: transmitere tablou 2d ca 1d

Post by Silviu Ardelean » 26 Jan 2011, 17:05

Viorel, urmeza sfatul lui Marius de-a folosi array-ul uni-dimensional pentru stocarea imaginii. Cu astfel de buffere se lucreaza in procesarea de imagini.

User avatar
zlatomir
Membru++
Membru++
Posts: 282
Joined: 04 Jul 2009, 23:59
Location: Arad
Contact:

Re: transmitere tablou 2d ca 1d

Post by zlatomir » 26 Jan 2011, 17:36

Daca tot tii neaparat sa faci copie a acelui array in loc sa il faci din start cu o singura dimensiune, cum tot comentam Marius si eu:
Uita-te la apelul acesta:
memcpy(bmp2+i*3*sizeof(int),&(*bmp1), 3 ); //si nu ma leg de operatii inutile cu pointeri
Si la documentatia memcpy, si o sa vezi de ce nu merge bine.

Dar totusi cred ca mai indicat ar fi din start un array cu o singura dimensiune (Marius ti-a dat si cod cum sa-l folosesti "ca si cum" ar avea doua dimensiuni in cazul in care ai nevoie de asta, singurul dezavantaj e ca nu scrii arr[j])

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: transmitere tablou 2d ca 1d

Post by Silviu Ardelean » 26 Jan 2011, 22:59

Am recitit problema ta si ma ia cu ameteli!
viorel2005 wrote: daca apela afis2 astfel: afis2(&(*bmp1)), afisarea era corecta. Totusi, aces lucru ma costa M-1 apeluri de functie.

cu alte cuvinte... tu te gandeai la o solutie de genul

Code: Select all

for (int i = 0; i < M; i++)
   afis2(&(*bmp1[i]))
Sorry, nu am cuvinte...

Regret doar ca, in graba, nu am citit foarte atent ce vrei sa zici tu cu cele M apeluri... si ti-am dat un sfat badaran a.i. sa nu ai nevoie de atatea apeluri.
Silviu Ardelean wrote:Viorel, daca tot vrei sa folosesti bmp1, de ce nu-l folosesti ca membru al unei clase sau membru global (daca nu lucrezi OOP)? Atunci in functia ta de afisare il apelezi direct fara a-l mai pasa la functie.
Last edited by Silviu Ardelean on 27 Jan 2011, 23:38, edited 1 time in total.

Post Reply