C: Matrisfråga

Här diskuteras programmering och utveckling
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

C: Matrisfråga

Inlägg av Johnny Rosenberg »

Ett enkelt exempel:

Kod: Markera allt

#include "stdio.h"

int main ()
{
	int x;
	double f[20];
	for (x=0; x<30; x++){
		f[x]=x*x-5.7*x+1.0/13.0+3.0/x;
		printf("f(%d)=%f\n", x, f[x]);
	}
	return 0;
}
Resultat:
f(0)=inf
f(1)=-1.623077
f(2)=-5.823077
f(3)=-7.023077
f(4)=-5.973077
f(5)=-2.823077
f(6)=2.376923
f(7)=9.605495
f(8)=18.851923
f(9)=30.110256
f(10)=43.376923
f(11)=58.649650
f(12)=75.926923
f(13)=95.207692
f(14)=116.491209
f(15)=139.776923
f(16)=165.064423
f(17)=192.353394
f(18)=221.643590
f(19)=252.934818
Segmenteringsfel
Helt väntat, inga konstigheter. Efter 20 varv i loopen hamnar vi utanför det definierade intervallet och får då följaktligen ett felmeddelande. Så långt allt väl.

Modifiering:

Kod: Markera allt

#include "stdio.h"

int main ()
{
/*	int x;		*/
	int r=20, x;
/*	double f[20];	*/
	double f[r];
	for (x=0; x<30; x++){ // Inga ändringar i resten av koden.
		f[x]=x*x-5.7*x+1.0/13.0+3.0/x;
		printf("f(%d)=%f\n", x, f[x]);
	}
	return 0;
}
Resultat:
f(0)=inf
f(1)=-1.623077
f(2)=-5.823077
f(3)=-7.023077
f(4)=-5.973077
f(5)=-2.823077
f(6)=2.376923
f(7)=9.605495
f(8)=18.851923
f(9)=30.110256
f(10)=43.376923
f(11)=58.649650
f(12)=75.926923
f(13)=95.207692
f(14)=116.491209
f(15)=139.776923
f(16)=165.064423
f(17)=192.353394
f(18)=221.643590
f(19)=252.934818
f(20)=286.226923
f(21)=321.519780
f(22)=358.813287
f(23)=398.107358
f(24)=439.401923
f(25)=482.696923
f(26)=527.992308
Segmenteringsfel
Kan någon förklara varför f plötsligt kunde ha 27 element (0-26)?
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
mcNisse
Inlägg: 5211
Blev medlem: 06 feb 2007, 20:51
OS: Debian
Utgåva: Vet inte/ingen utgåva passar

Re: C: Matrisfråga

Inlägg av mcNisse »

Därför att du hade tur. Du kunde läsa 7 extra minnespositioner innan du kom till något olämpligt.
Det finns mao inga begränsningar i c hur långt du kan addressera i en array. Till slut kommer du till ett felaktigt värde.

jag är lite förvåndad att koden under fungerar. Det gjorde det inte när jag kodade c.

Kod: Markera allt

double f[r]
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: C: Matrisfråga

Inlägg av Johnny Rosenberg »

mcNisse skrev:Därför att du hade tur. Du kunde läsa 7 extra minnespositioner innan du kom till något olämpligt.
Jag inte bara läste dem, jag tilldelade dem värden först.
Jag ska också tillägga att jag körde samma program tidigare men med r=10 och fick även då 7 extra minnespositioner, men när jag angav 10 direkt (utan att blanda in r), blev det 10 och inte ett öre extra, så jag vet inte riktigt om jag kan köpa resonemanget helt och fullt. Får nog testa några gånger till med olika värden för att se om det alltid blir just 7 positioner extra.
mcNisse skrev:Det finns mao inga begränsningar i c hur långt du kan addressera i en array. Till slut kommer du till ett felaktigt värde.
Fast det är ju jag själv som tilldelar värdena, eller menar du att jag förr eller senare försöker tilldela ett värde till en adress som är upptagen av något annat och att operativsystemet därför protesterar?
mcNisse skrev:jag är lite förvåndad att koden under fungerar. Det gjorde det inte när jag kodade c.

Kod: Markera allt

double f[r]
Kanske en ny ”feature”…
Fast varför skulle det egentligen inte fungera? Hur ofta vet man i förväg hur många element man behöver?
Men det är väl tänkt att man ska använda pekare och malloc() (dynamiska matriser), ett område som jag inte varit inne och känt på så mycket än. Känns som att det är upplagt för skapande av buggar, men man får väl försöka vara lite systematisk när man sitter där och försöker låta bli att klanta sig.

(Redigerat två gånger 2012-03-08 – hade klantat mig med taggarna, så ingen ny information är tillagd)
Senast redigerad av 2 Johnny Rosenberg, redigerad totalt 8 gång.
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: C: Matrisfråga

Inlägg av Johnny Rosenberg »

Okej, nu har jag testat lite till med lite olika värden (200 och 2000 bland annat). Samma resultat varje gång: 7 extra om jag skriver ”double f[r]” jämfört med om jag använder en konstant istället för r. Provade även följande:

Kod: Markera allt

#include "stdio.h"

#define VAL 2000

int main ()
{
	int r=VAL, x;
	double f[VAL];
	for (x=0; x<r+50; x++){
		f[x]=x*x-5.7*x+1.0/13.0+3.0/x;
		printf("f(%d)=%f\t%d\n", x, f[x], r);
	}
	return 0;
}
Resultatet blev detsamma som när jag angav 2000 direkt, föga förvånande, men jag ville testa ändå.

Nåja, oavsett vad det beror på, så är det ju ingen begränsning som hindrar mig på något sätt, möjligen skulle nackdelen kunna vara att kod som funkar ena dagen kanske inte funkar nästa dag om man slarvat med dimensioneringen och om det är som du säger.
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
mcNisse
Inlägg: 5211
Blev medlem: 06 feb 2007, 20:51
OS: Debian
Utgåva: Vet inte/ingen utgåva passar

Re: C: Matrisfråga

Inlägg av mcNisse »

Johnny Rosenberg skrev:Fast det är ju jag själv som tilldelar värdena, eller menar du att jag förr eller senare försöker tilldela ett värde till en adress som är upptagen av något annat och att operativsystemet därför protesterar?
Du tilldelar värden utanför den addressrymd som du har allokerat, du allokerar en array med 20 float. När du skriver bakom ditt allokerade utrymme är inte definierat vad som händer. Segmentaion violation, Bus error, wathever. Håll dig innanför det allokerade utrymmet. C hjälper inte till med att kontrollera vart du skriver.
Bowmore
Inlägg: 6212
Blev medlem: 28 mar 2007, 23:01
OS: Ubuntu
Ort: Stockholm

Re: C: Matrisfråga

Inlägg av Bowmore »

Märkligt att kompilatorn (gcc?) accepterar

Kod: Markera allt

int r=20;
double f[r];
då en array har en fix storlek som sätts vid kompileringen.
Koden är knappast portabel mellan kompilatorer.

Alltså, storleken ska anges som en konstant och inte med en värdesatt variabel.

Kod: Markera allt

const int r=20;
double f[r];
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: C: Matrisfråga

Inlägg av Johnny Rosenberg »

Bowmore skrev:Märkligt att kompilatorn (gcc?) accepterar

Kod: Markera allt

int r=20;
double f[r];
då en array har en fix storlek som sätts vid kompileringen.
Koden är knappast portabel mellan kompilatorer.

Alltså, storleken ska anges som en konstant och inte med en värdesatt variabel.

Kod: Markera allt

const int r=20;
double f[r];
Så i mitt fall, när jag vill kunna ändra matrisens storlek, så är detta alltså inte en framkomlig väg?
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
HakanS
Global Moderator
Inlägg: 4289
Blev medlem: 30 mar 2006, 10:34
OS: Kubuntu
Utgåva: 23.04 Lunar Lobster
Ort: Trollhättan

Re: C: Matrisfråga

Inlägg av HakanS »

Johnny Rosenberg skrev:Så i mitt fall, när jag vill kunna ändra matrisens storlek, så är detta alltså inte en framkomlig väg?
Nej, arrayens storlek bestäms vid deklareringen och kan sedan inte ändras.
Bowmore
Inlägg: 6212
Blev medlem: 28 mar 2007, 23:01
OS: Ubuntu
Ort: Stockholm

Re: C: Matrisfråga

Inlägg av Bowmore »

Behöver du en "dynamisk" array så skapar du den (allokerar minne) i runtime med malloc, ändrar storleken med realloc och sen frigör minnet med free innan du avslutar programmet, så du inte skapar minnesläckor.
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: C: Matrisfråga

Inlägg av Johnny Rosenberg »

Bowmore skrev:Behöver du en "dynamisk" array så skapar du den (allokerar minne) i runtime med malloc, ändrar storleken med realloc och sen frigör minnet med free innan du avslutar programmet, så du inte skapar minnesläckor.
Det var det jag misstänkte… Tackar för informationen!

Har lite följdfrågor på detta, men jag ska inte ställa dem innan jag letat efter svaren själv först och inte lyckats hitta dem…
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Skriv svar

Återgå till "Programmering och webbdesign"