| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | 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 |  
  |   |   |   
            
        
 
            
         
               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
  
            
             |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |