/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Allokering og initialisering af todimensio~
Fra : Jacob Jensen


Dato : 14-08-06 12:30

Hej gruppe

Jeg har siddet og forsøgt at lave et lille program som kan multiplicere to
matricer. Ideen var kun at bruge de basale typer i C++. Altså ikke vector,
list osv.

Jeg har fået det til at fungere, men kun hvis jeg benytter new[] til at
allokere variabler af typen int**.

Følgende fungerer ikke. Burde "test" ikke have typen int**?
int test[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};

Jeg kan caste den uden problemer til (int**) men det skal jeg gøre
eksplicit, og herefter kan jeg ikke tilgå elementerne med f.eks. test[0][0].

Så bundlinjen må være noget i retning af... Hvad er forskellen på:

1)
int test1[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};

og

2)
int** test = new int*[4];

for(int i=0; i<4; i++)
test[i] = new int[4];

for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
test[i][j] = 0;

--
Jacob Jensen
E-mail: jacob@etlivmedsle.dk
Hjemmeside: www.etlivmedsle.dk



 
 
Jacob Jensen (14-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 14-08-06 13:47

> Så bundlinjen må være noget i retning af... Hvad er forskellen på:
>
> 1)
> int test1[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
>
> og
>
> 2)
> int** test = new int*[4];
>
> for(int i=0; i<4; i++)
> test[i] = new int[4];
>
> for(int i=0; i<4; i++)
> for(int j=0; j<4; j++)
> test[i][j] = 0;

....Altså lige bortset fra at den ene bliver allokeret på hoben og den anden
på stakken.

Jacob



Mogens Hansen (14-08-2006)
Kommentar
Fra : Mogens Hansen


Dato : 14-08-06 20:09


"Jacob Jensen" <omo@adslhome.dk> wrote in message
news:44e05ecf$0$84021$edfadb0f@dtext01.news.tele.dk...

[8<8<8<]
> Så bundlinjen må være noget i retning af... Hvad er forskellen på:
>
> 1)
> int test1[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};

Der allokeres 16 int i et 2 dimensionelt array, og de er initialiseret med
kendte værdier.

>
> og
>
> 2)
> int** test = new int*[4];

Her allokeres der et array af fire pegere til int, og de peger ikke på nogen
integer - de er udefinerede.
Der bliver ikke allokeret nogen plads til de int som pegerne kan pege på.

Venlig hilsen

Mogens Hansen



Jacob Jensen (14-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 14-08-06 20:46

>> int test1[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
>
> Der allokeres 16 int i et 2 dimensionelt array, og de er initialiseret med
> kendte værdier.

Ja, jeg er kommet lidt videre selv i de sidste timer :) Det viser sig at
(korriger mig endelig):

- test slet ikke er en variabel men blot et "navn" (en adresse) på det
første element.
- *test er samme adresse, da den er et "navn" på det første element i den
første "undertabel"

Stadigvæk forvirrer det mig dog at jeg kan caste til int** men ikke bruge
som argument til en funktion hvis argument er af typen int**.

Jacob



Mogens Hansen (14-08-2006)
Kommentar
Fra : Mogens Hansen


Dato : 14-08-06 21:02


"Jacob Jensen" <omo@adslhome.dk> wrote in message
news:44e0d313$0$84029$edfadb0f@dtext01.news.tele.dk...
>>> int test1[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
>>
>> Der allokeres 16 int i et 2 dimensionelt array, og de er initialiseret
>> med kendte værdier.
>
> Ja, jeg er kommet lidt videre selv i de sidste timer :) Det viser sig at
> (korriger mig endelig):
>
> - test slet ikke er en variabel men blot et "navn" (en adresse) på det
> første element.

"test" er bestemt en variabel.
Mere præcist så er det en variabel der indeholder adressen på den første
"peger til int" i det array med 4 "peger til int" der blev allokeret på
heapen.

> - *test er samme adresse, da den er et "navn" på det første element i den
> første "undertabel"

Jeg forstår ikke hvad du mener.
"*test" giver dig tilgang til første "peger til int" i det array der blev
allokeret på heapen.
Det er iøvrigt det samme som "test[0]"

>
> Stadigvæk forvirrer det mig dog at jeg kan caste til int** men ikke bruge
> som argument til en funktion hvis argument er af typen int**.

Det lyder forkert.
Prøv at vis os en stump kode.

Venlig hilsen

Mogens Hansen



Jacob Jensen (14-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 14-08-06 21:15

> "test" er bestemt en variabel.

Jeg har det fra en bog om C (ANSI C). Er du sikker? Kan test stå på
venstresiden af et tildelingsudtryk? "Fylder" tekst noget i hukommelsen? Jeg
tror det ikke.

> Det lyder forkert.
> Prøv at vis os en stump kode.

Følgende virker hvis jeg erklærer test af typen int** og bruger new, som
tidligere beskrevet. Men som koden fremstår her vil den ikke oversætte.

#include <iostream>
using namespace std;

int index(int** a, int index1, int index2)
{
return a[index1][index2];
}

int main()
{
int test[3][3] = {{5,3,2},{1,2,3},{4,5,6}};

// Cast error
cout << index(test, 1, 2);

return 0;
}


Jacob



Jacob Jensen (14-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 14-08-06 22:50

> Jeg har det fra en bog om C (ANSI C). Er du sikker? Kan test stå på
> venstresiden af et tildelingsudtryk? "Fylder" tekst noget i hukommelsen?
> Jeg tror det ikke.

Jeg er faktisk efterhånden ret sikker. Det lader til at et "tabelnavn"
(array name), blot er en const int hvis værdi er adressen på det første
element.

Her er lidt fra rundt omkring:

"The name of the array, in this case my_array, is a constant pointer that
points to the first element, or element 0, of my_array."
http://www.chips.navy.mil/archives/99_apr/c++arrays.htm

"The address of operator (&) does nothing when applied to array names (see
discussion below), but does with pointers.. "
"Array names are essentially const. "
http://www.fredosaurus.com/notes-cpp/arrayptr/arraysaspointers2.html

"array names are not lvalues"
http://www.phptr.com/articles/article.asp?p=31783&seqNum=2&rl=1

"Array names are really addresses of the data"
http://courses.washington.edu/cppcert/begincpp/Lectures/Lecture3.ppt#279,18,Array
Parameters

"In C++ an array name is a constant pointer to the first element of the
array. "
http://newdata.box.sk/bx/c/htm/ch11.htm#Heading33

Jacob



Mogens Hansen (15-08-2006)
Kommentar
Fra : Mogens Hansen


Dato : 15-08-06 05:16


"Jacob Jensen" <omo@adslhome.dk> wrote in message
news:44e0eff3$0$84026$edfadb0f@dtext01.news.tele.dk...
>> Jeg har det fra en bog om C (ANSI C). Er du sikker? Kan test stå på
>> venstresiden af et tildelingsudtryk? "Fylder" tekst noget i hukommelsen?
>> Jeg tror det ikke.
>
> Jeg er faktisk efterhånden ret sikker.

Det har du ret i - jeg snakkede om den "test" der blev brugt ved dynamisk
allokering
int** test = new int*[4];
men det var ikke den du nævnte.

Venlig hilsen

Mogens Hansen



Jacob Jensen (15-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 15-08-06 08:47

> Det har du ret i - jeg snakkede om den "test" der blev brugt ved dynamisk
> allokering
> int** test = new int*[4];
> men det var ikke den du nævnte.

Ahh, ok. Nej det var denne:

int test[4][4] = ....

Jacob



Ivan Johansen (15-08-2006)
Kommentar
Fra : Ivan Johansen


Dato : 15-08-06 08:15

Jacob Jensen wrote:
> Jeg har siddet og forsøgt at lave et lille program som kan multiplicere to
> matricer. Ideen var kun at bruge de basale typer i C++. Altså ikke vector,
> list osv.

Hvorfor ikke? For øvelsens skyld? Ellers gør du det meget mere
besværligt for dig selv.

> Følgende fungerer ikke. Burde "test" ikke have typen int**?
> int test[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};

Nej test har typen int[4][4]. Prøv at udskrive sizeof(test) og
sizeof(int**). Men test kan implicit konverteres til int(*)[4], dvs. en
pointer til 4 int.

> Jeg kan caste den uden problemer til (int**) men det skal jeg gøre
> eksplicit, og herefter kan jeg ikke tilgå elementerne med f.eks. test[0][0].

Jeg tillader mig at tvivle på "uden problemer". Et static_cast vil helt
sikkert fejle så jeg antager at du har brugt et C-cast hvor du tvinger
det til at compile selv om resultatet er ubrugeligt.

Hvis du vil have pointer til pointer er du nødt til at lave nogle pointere:
int test1[4] = {1,2,3,4};
int test2[4] = {1,2,3,4};
int test3[4] = {1,2,3,4};
int test4[4] = {1,2,3,4};
int *test[4] = {test1, test2, test3, test4};


> Så bundlinjen må være noget i retning af... Hvad er forskellen på:
> 1)
> int test1[4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};

Her har du 16 int efter hinanden og ingen pointer involveret, men du kan
lave en pointer til det første element.

> 2)
> int** test = new int*[4];

Her laver du en pointer til 4 pointere.

> for(int i=0; i<4; i++)
> test[i] = new int[4];

Hver af de 4 pointere vil nu pege på 4 int.

Ivan Johansen

Jacob Jensen (15-08-2006)
Kommentar
Fra : Jacob Jensen


Dato : 15-08-06 09:03

> Hvorfor ikke? For øvelsens skyld? Ellers gør du det meget mere besværligt
> for dig selv.

Ja, det var for øvelsens skyld. Og det førte, som du kan læse, også til
noget... forvirring.

> Nej test har typen int[4][4]. Prøv at udskrive sizeof(test) og
> sizeof(int**). Men test kan implicit konverteres til int(*)[4], dvs. en
> pointer til 4 int.

Ja, og det skal gøres hvis den skal bruges som argument i en funktion ikke?

>> Jeg kan caste den uden problemer til (int**) men det skal jeg gøre
>> eksplicit, og herefter kan jeg ikke tilgå elementerne med f.eks.
>> test[0][0].
>
> Jeg tillader mig at tvivle på "uden problemer". Et static_cast vil helt
> sikkert fejle så jeg antager at du har brugt et C-cast hvor du tvinger det
> til at compile selv om resultatet er ubrugeligt.

Det er muligt. Jeg skrev
(int**) test;

....så det er vel en C-type cast. Jeg har lige prøvet:
int** a = static_cast<int**> (test);

....og det giver en fejl fra oversætteren.

<klip>

Tak for svaret.

Jacob



Ivan Johansen (15-08-2006)
Kommentar
Fra : Ivan Johansen


Dato : 15-08-06 12:32

Jacob Jensen wrote:
>> Nej test har typen int[4][4]. Prøv at udskrive sizeof(test) og
>> sizeof(int**). Men test kan implicit konverteres til int(*)[4], dvs. en
>> pointer til 4 int.
>
> Ja, og det skal gøres hvis den skal bruges som argument i en funktion ikke?

Jo, for du kan kun overføre en pointer og ikke et helt array til en
funktion. Men der er stor forskel på om funktionen tager en int** eller
int(*)[4].

Ivan Johansen

Søg
Reklame
Statistik
Spørgsmål : 177577
Tips : 31968
Nyheder : 719565
Indlæg : 6409071
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste