Sida 1 av 2

Hur gör man en pekare till tvådimensionell array?

Postat: 29 november 2006, 19:57:34
av bearing

Kod: Markera allt

char varden[y][x];

char **vp=varden;  //Funkar inte (vp är en pekare till pekare)

Postat: 29 november 2006, 20:45:25
av bearing
Hade sen tänkt att använda pekaren som en tvådimensionell array, t.ex:

varde=vp[5][2];

Men det går nog inte, får tänka om.

Postat: 29 november 2006, 21:07:22
av thepirateboy
Minns inte riktigt, hade själv probs med detta. Array är väl från början en slags pekare till första elementet i varje rad. Jag gjorde så här:

char varden[10][20];
strcpy(varden[aktuellRad],nyttVarde);

Re: Hur gör man en pekare till tvådimensionell array?

Postat: 29 november 2006, 21:25:43
av gvs
bearing skrev:

Kod: Markera allt

char varden[y][x];

char **vp=varden;  //Funkar inte (vp är en pekare till pekare)
det där funkar väl inte för att du har en pekare till en pekare på ena sidan och en pekare på andra.... teta **vp = &varden

(Total nybörjare på C men vad jag har lyckats läsa mig till....)

Postat: 29 november 2006, 21:48:52
av bearing
Fast det får inte tänkt effekt. Då får jag en pekare som pekar på arraypekarvariabelns adress.


Jag hade tänkt använda det för att kunna växla mellan flera arrayer. Det funkar finfint med endimensionella arrayer.

char varden[y][x];
char varden2[y][x];

char *aktuellaVarden=varden;

varde=[2][3];

och sedan byta

aktuellaVarden=varden2;

varde=[2][3];


Jag löste det genom att lägg all data i en array och sedan växla genom att titta senare i datan.

char varden[y*2][x];
char tabellnr;

varde=[2+y*tabellnr][3]

(Bara principiell kod. x och y är konstaner)

Så istället för att lagra andra värden i pekaren lägger jag olika värden i tabellnr.

Postat: 29 november 2006, 21:57:07
av Icecap
char Varden[x][y], *Pointer, x;
Pointer = Varden; // Pekar på Varden[0][0]
Pointer = Varden[3][0]; // Pekar numera på Varden[3][0]
x = *(Pointer + sizeof(char)); // x = Varden[3][1]

Postat: 29 november 2006, 22:04:50
av bearing
Grejen är/var den att "varden" används överallt i koden, och jag ville (utan att skriva om koden på varje ställe den används) slänga in ett sätta att växla array, i testsyfte.

Postat: 29 november 2006, 22:07:31
av Icecap
#if TEST
char Varden[][] = {någonting};
#else
char Varden[][] = {någonting annat};
#endif

Edit:
Om det är så att du vill testa att byta mellan 2 tabeller som samlas ihop brukar jag att använda 'define'

#if TEST
#define DataIn1 Varden
#define DataOut1 Varden
#define DataIn2 AndraVarden
#define DataOut2 AndraVarden
#else
#define DataIn1 Varden
#define DataOut2 Varden
#define DataIn2 AndraVarden
#define DataOut1 AndraVarden
#endif

Kan kombineras långt o länge.

Postat: 29 november 2006, 22:20:22
av bearing
Det är bra tips, som jag ska hålla i minnet. Ifsatser som preprocessorkommandon har jag nog inte använt tror jag.

Tyvärr går det inte här eftersom jag växlar under runtime, för att observera vad som händer.

Postat: 29 november 2006, 22:31:46
av strombom
Alternativ 1

Kod: Markera allt

	int x = 2;
	int y = 2;

	char **varden1;
	char **varden2;
	char **varde;

	//Allokera minne för matriserna:
	varden1 = (char**) calloc(x, sizeof(char *));
	varden2 = (char**) calloc(x, sizeof(char *));
	for (int i=0; i<x;i++)
	{
	   varden1[i] = (char*) calloc(y, sizeof(char));
	   varden2[i] = (char*) calloc(y, sizeof(char));
	}

	//Spara lite data i varden1
	varde = varden1;
	for (int i=0; i<x; i++)
		for (int j=0; j<x; j++)
			varde[i][j] = j + i*x;

	//Spara lite data i varden2
	varde = varden2;
	for (int i=0; i<x; i++)
		for (int j=0; j<x; j++)
			varde[i][j] = 100 + j + i*x;


	//Skriv ut värden1
	varde = varden1;
	printf("\n\nvarden1\n---------------\n");   
	for (int i=0; i<x; i++)
	{
		for (int j=0; j<x; j++)
			printf("  %d ", varde[i][j]); 
		printf("\n");
	}

	
	//Skriv ut värden2
	varde = varden2;
	printf("\n\nvarden2\n---------------\n");   
	for (int i=0; i<x; i++)
	{
		for (int j=0; j<x; j++)
			printf("%d ", varde[i][j]); 
		printf("\n");
	}


	//Rensa upp efter dig
	for (int i=0; i<x;i++)
	{
		free(varden1[i]);
		free(varden2[i]);
	}
	free(varden1);
	free(varden2);
Alternativ 2

Kod: Markera allt

char varden[i][y][x]
:roll:

Postat: 29 november 2006, 22:41:03
av bearing
I det här fallet behövdes det inte allokeras något minne eftersom pekaren skulle peka på data som redan finns.

Tredimensionell skulle man kunnat använda, men jag var osäker på om kompilatorn skulle hantera dem på ett effektivt sätt jämfört med min lösning men tvådimensionell.

Postat: 29 november 2006, 23:02:58
av strombom
Jupp, och i mitt exempel finns denna data "redan" (efter allokeringen som man på något sätt måste göra någongång ändå) i varden1 och varden2 :wink:

Så här då?

Kod: Markera allt

#define x 2
#define y 2

	char varden1[x][y];
	char varden2[x][y];
	char* varde;

	//Spara lite data i varden1
	varde = (char*)varden1;
	for (int i=0; i<x; i++)
		for (int j=0; j<x; j++)
			*(varde + i*x + j) = j + i*x;

	//Spara lite data i varden2
	varde = (char*)varden2;
	for (int i=0; i<x; i++)
		for (int j=0; j<x; j++)
			*(varde + i*x + j) = 100 + j + i*x;

	//Skriv ut värden1
	varde = (char*)varden1;
	printf("\n\nvarden1\n---------------\n");   
	for (int i=0; i<x; i++)
	{
		for (int j=0; j<x; j++)
			printf("  %d ", *(varde + i*x + j)); 
		printf("\n");
	}

	//Skriv ut värden2
	varde = (char*)varden2;
	printf("\n\nvarden2\n---------------\n");   
	for (int i=0; i<x; i++)
	{
		for (int j=0; j<x; j++)
			printf("%d ", *(varde + i*x + j)); 
		printf("\n");
	}
edit: ok det hade du redan gjort...

Faktum är ju att en tvådimensionell statisk matris sparas som en endimensionell matris...

Om du vill slippa multiplikationerna kan man lösa det så här:

Kod: Markera allt

#define x 2
#define y 2

	char varden1[x][y];
	char varden2[x][y];
	char *varde;

	//Spara lite data i varden1
	varde = (char*)varden1;
	for (int i=0; i<x; i++)
		for (int j=0; j<x; j++)
			*(varde++) = j + i*x;

	//Spara lite data i varden2
	varde = (char*)varden2;
	for (int i=0; i<x; i++)
		for (int j=0; j<x; j++)
			*(varde++) = 100 + j + i*x;

	//Skriv ut värden1
	varde = (char*)varden1;
	printf("\n\nvarden1\n---------------\n");   
	for (int i=0; i<x; i++)
	{
		for (int j=0; j<x; j++)
			printf("  %d ", *(varde++)); 
		printf("\n");
	}

	//Skriv ut värden2
	varde = (char*)varden2;
	printf("\n\nvarden2\n---------------\n");   
	for (int i=0; i<x; i++)
	{
		for (int j=0; j<x; j++)
			printf("%d ", *(varde++)); 
		printf("\n");
	}

Postat: 29 november 2006, 23:21:24
av bearing
Jag fattar inte vad som gör att varde kan användas som en tvådimensionell array i ditt första exempel, men inte de andra.
"Problemet" för kompilatorn är väl att den inte vet hur långa raderna är. Men hur kan den veta det i ex.1 men inte i ex.2 och ex.3?

Postat: 29 november 2006, 23:23:23
av strombom
För att ex.1 använder en dubbelpekare men jag är osäker på om det är riktigt tillåtet att addressera dem med variabel[j] så eller om det är ren tur att minnet allokeras på en enda rad.

Postat: 29 november 2006, 23:29:20
av bearing
Jo, jag ser att den använder dubbelpekare. Men hur vet den att när du skriver varde[a] att adressen ska bli varde + a*radlängd*sizeof(variabeltyp) + b*sizeof(variabeltyp) ?

Den vet väl inte hur långa raderna är? och särskilt inte när de dimensionerats dynamisk?