/ 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
2 dimensionale vektorer i C?
Fra : Kristian Birch Søren~


Dato : 01-10-01 18:16

Hej
Jeg har tilsvarende problem som assassin og Søren, jeg kan ikke oprette
flerdimensionelle dynamiske arrays i C. Ideen med vector fungerer fint i
C++, men jeg kan ikke inkludere <vector> når jeg bruger en C-compiler. Jeg
ønsker at oprette en Matlab funktion vha. mex komandoen i Matlab, hvilket
gøres ved C-programmering. Hvis jeg forsøger at includere vector får jeg
følgende fejl under kompileringen "eh.h is only for C++". Nogle ideer til
hvorledes der kan oprettes flerdimensionelle dynamiske arrays i C?

Mvh
Kristian



 
 
Bertel Lund Hansen (01-10-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 01-10-01 18:48

Kristian Birch Sørensen skrev:

>Nogle ideer til hvorledes der kan oprettes flerdimensionelle dynamiske arrays i C?

Opret et array af pointere som dynamisk allokeres som pointere
til et array. Så kan du endda lave et 'takket' array.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Jesper Winther Larse~ (02-10-2001)
Kommentar
Fra : Jesper Winther Larse~


Dato : 02-10-01 09:26

Hvordan gøres det egentlig i praksis???

Jesper Larsen


"Bertel Lund Hansen" <nospamto@lundhansen.dk> skrev i en meddelelse
news:lvahrtkibrbtq12l7pu5fdofmhbtv7kk3q@news.stofanet.dk...
> Kristian Birch Sørensen skrev:
>
> >Nogle ideer til hvorledes der kan oprettes flerdimensionelle dynamiske
arrays i C?
>
> Opret et array af pointere som dynamisk allokeres som pointere
> til et array. Så kan du endda lave et 'takket' array.
>
> --
> Bertel
> http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/



Bertel Lund Hansen (02-10-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 02-10-01 14:57

Jesper Winther Larsen skrev:

>> Opret et array af pointere som dynamisk allokeres som pointere
>> til et array. Så kan du endda lave et 'takket' array.

>Hvordan gøres det egentlig i praksis???

Her er svar på det og Rasmus' spørgsmål i en mail. Jeg svarer ellers gerne
på spørgsmål i mail, men netop dette her hører (stadig) hjemme i
debatgruppen:

enum { ROWS = 10, COLS = 5};

int **array2d;


int main () {
int nr, n;
// Reserver plads til en pointer for hver række.
array2d=(int**) malloc(sizeof(int*)*ROWS);

// Reserver plads til en stribe integers,
// og lad rækkepointeren pege på hver stribe.
for (nr=0; nr<ROWS; ++nr) {
array2d[nr]=(int*) malloc(sizeof(int)*COLS);
}

// Fyld alle pladserne op med tal som eksempel.
for (nr=0; nr<ROWS; ++nr)
for (n=0; n<COLS; ++n)
array2d[nr][n]=nr*100+n;

// Udskriv en tabel.
for (nr=0; nr<ROWS; ++nr) {
for (n=0; n<COLS; ++n) printf("%2i %2i %5i ",nr,n,array2d[nr][n]);
printf("\n");

}
free(array2d);
return 0;
}

Med "takket array" (eng. "jagged array") mener jeg at man ikke er bundet til
at give alle rækkerne lige mange elementer, men det skal naturligvis styres
lidt anderledes.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Jesper Winther Larse~ (02-10-2001)
Kommentar
Fra : Jesper Winther Larse~


Dato : 02-10-01 15:26

Mange tak for hjælpen. Det virker upåklageligt.


"Bertel Lund Hansen" <skrivtil@lundhansen.dk> skrev i en meddelelse
news:kehjrt8chke7kmbg760uiufc6hmartkc2s@news.stofanet.dk...
> Jesper Winther Larsen skrev:
>
> >> Opret et array af pointere som dynamisk allokeres som pointere
> >> til et array. Så kan du endda lave et 'takket' array.
>
> >Hvordan gøres det egentlig i praksis???
>
> Her er svar på det og Rasmus' spørgsmål i en mail. Jeg svarer ellers gerne
> på spørgsmål i mail, men netop dette her hører (stadig) hjemme i
> debatgruppen:
>
> enum { ROWS = 10, COLS = 5};
>
> int **array2d;
>
>
> int main () {
> int nr, n;
> // Reserver plads til en pointer for hver række.
> array2d=(int**) malloc(sizeof(int*)*ROWS);
>
> // Reserver plads til en stribe integers,
> // og lad rækkepointeren pege på hver stribe.
> for (nr=0; nr<ROWS; ++nr) {
> array2d[nr]=(int*) malloc(sizeof(int)*COLS);
> }
>
> // Fyld alle pladserne op med tal som eksempel.
> for (nr=0; nr<ROWS; ++nr)
> for (n=0; n<COLS; ++n)
> array2d[nr][n]=nr*100+n;
>
> // Udskriv en tabel.
> for (nr=0; nr<ROWS; ++nr) {
> for (n=0; n<COLS; ++n) printf("%2i %2i %5i ",nr,n,array2d[nr][n]);
> printf("\n");
>
> }
> free(array2d);
> return 0;
> }
>
> Med "takket array" (eng. "jagged array") mener jeg at man ikke er bundet
til
> at give alle rækkerne lige mange elementer, men det skal naturligvis
styres
> lidt anderledes.
>
> --
> Bertel
> http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/



Igor V. Rafienko (02-10-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 02-10-01 16:31

[ Bertel Lund Hansen ]

[ snip ]

> enum { ROWS = 10, COLS = 5};
>
> int **array2d;
>
>
> int main () {
> int nr, n;
> // Reserver plads til en pointer for hver række.
> array2d=(int**) malloc(sizeof(int*)*ROWS);
>
> // Reserver plads til en stribe integers,
> // og lad rækkepointeren pege på hver stribe.
> for (nr=0; nr<ROWS; ++nr) {
> array2d[nr]=(int*) malloc(sizeof(int)*COLS);
> }


Alternativt (og iirc likere numerikere denne "teknikken") kan man
gjøre det slik:


typedef int **fvec_t;

fvec_t
make_vector( size_t rows, size_t cols )
{
fvec_t tmp = malloc( rows * sizeof *tmp );
if ( !tmp )
   return NULL;

tmp[ 0 ] = malloc( (rows*cols) * sizeof **tmp );
if ( !tmp[ 0 ] ) {
   free( tmp );
   return NULL;
}

for ( size_t i = 1; i != rows; ++i )
   tmp[ i ] = tmp[ 0 ] + i*cols;

return tmp;
}


void
free_vector( fvec_t tmp )
{
if ( !tmp )
   return ;

free( tmp[ 0 ] );
free( tmp );
}


int
main()
{
const size_t R = 10U, C = 15U;
fvec_t vec = make_vector( R, C );

/* populate */
for ( size_t i = 0; i != R; ++i )
for ( size_t j = 0; j != C; ++j )
    vec[i][j] = i*C + j;

for ( size_t i = 0; i != R; ++i ) {
for ( size_t j = 0; j != C; ++j )
    printf( "%4d", vec[i][j] );
   printf( "\n" );
}

free_vector( vec );
}


Den umiddelbare fordelen er at alle elementene ligger etter hverandre.
Noen biblioteker vil ha det slik.

[ snip ]





ivr
PS: BTW, det er en uting å typecast'e returverdien fra malloc.
Prøv heller #include <stdlib.h>.
--
Simula-konsulent? Simsulent? "I eat Java for breakfast!".
-- thorkild

Bertel Lund Hansen (02-10-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 02-10-01 16:54

Igor V. Rafienko skrev:

[som sædvanlig nogle gode kommentarer]

>Prøv heller #include <stdlib.h>.

Sikke hurtigt man kan glemme.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Thomas Krog (02-10-2001)
Kommentar
Fra : Thomas Krog


Dato : 02-10-01 16:34

> // Reserver plads til en stribe integers,
> // og lad rækkepointeren pege på hver stribe.
> for (nr=0; nr<ROWS; ++nr) {
> array2d[nr]=(int*) malloc(sizeof(int)*COLS);
> }

husk også at frigøre striberne:

for (nr=0; nr<ROWS; ++nr) {
free(array2d[nr]);
}
free(array2d);

Hvis hastigheden er væsentlig er Benny's løsning at foretrække, fordi det
tager relativt lang tid at læse fra 2 forskellige steder i hukommelsen (men
måske er det omvendt om 10 år så det bedste er nok at tilgå arrayet med
nogle inline funktioner så det kan ændres)



Benny Andersen (01-10-2001)
Kommentar
Fra : Benny Andersen


Dato : 01-10-01 18:59

On Mon, 1 Oct 2001 19:15:45 +0200, "Kristian Birch Sørensen"
<birch98@civil.auc.dk> wrote:

>Hej
>Jeg har tilsvarende problem som assassin og Søren, jeg kan ikke oprette
>flerdimensionelle dynamiske arrays i C. Ideen med vector fungerer fint i
>C++, men jeg kan ikke inkludere <vector> når jeg bruger en C-compiler. Jeg
>ønsker at oprette en Matlab funktion vha. mex komandoen i Matlab, hvilket
>gøres ved C-programmering. Hvis jeg forsøger at includere vector får jeg
>følgende fejl under kompileringen "eh.h is only for C++". Nogle ideer til
>hvorledes der kan oprettes flerdimensionelle dynamiske arrays i C?
>
>Mvh
>Kristian
>
>
Opret dem som endimensionelle, med størrelsen produktet af
dimensionernes størrelse.

Per Abrahamsen (02-10-2001)
Kommentar
Fra : Per Abrahamsen


Dato : 02-10-01 17:35

igorr@ifi.uio.no (Igor V. Rafienko) writes:

> PS: BTW, det er en uting å typecast'e returverdien fra malloc.

Hvorfor det? Umiddelbart vil det da være en fordel hvis man en dag
skal bruge koden i et C++ program.

> Prøv heller #include <stdlib.h>.

Det ene behøver vel ikke udelukke det andet.


Igor V. Rafienko (02-10-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 02-10-01 17:43

[ Per Abrahamsen ]

> > PS: BTW, det er en uting å typecast'e returverdien fra malloc.
>
> Hvorfor det? Umiddelbart vil det da være en fordel hvis man en dag
> skal bruge koden i et C++ program.


Det kanoniske svaret på dette er at kompilatoren skal oppdage
implisitt konvertering int -> T*, men ikke konverteringen void* -> T*
(den kan protestere i det siste tilfellet, men trenger ikke det (og en
rekke kompilatorer ikke gjør det heller)).

Bruker man malloc(), skal kompilatoren se den riktige typen (dog, jeg
er ikke helt sikker på hvorvidt dette kravet er det rent stilmessige
eller om det er begrunnet i språkets definisjon.)

Og bruker man først C++, burde man kanskje holde seg til new/delete
heller enn malloc/free (om ikke annet så pga. konsistens).


> > Prøv heller #include <stdlib.h>.
>
> Det ene behøver vel ikke udelukke det andet.


Nei, naturligvis ikke.





ivr
--
Ehh... I'll have a McRudolf menu, please.

Soeren Sandmann (02-10-2001)
Kommentar
Fra : Soeren Sandmann


Dato : 02-10-01 17:55

Per Abrahamsen <abraham@dina.kvl.dk> writes:

> igorr@ifi.uio.no (Igor V. Rafienko) writes:
>
> > PS: BTW, det er en uting å typecast'e returverdien fra malloc.
>
> Hvorfor det? Umiddelbart vil det da være en fordel hvis man en dag
> skal bruge koden i et C++ program.

Argumentet er at hvis man glemmer at inkludere stdlib.h, bliver
malloc() opfattet som en funktion der returnerer int. Der sker altså
et cast fra pointer til int og derefter en konvertering tilbage til
pointer - det går ikke nødvendigvis godt, især ikke hvis pointere er
længere end heltal. Med et eksplicit typecast har compileren ingen
mulighed for at advare om det.

Det bedste er formentlig at definere en makro i stil med (utestet):

#include <stdio.h>

#define allocate(t) ((t *)malloc (sizeof (t)))

for det betyder at compileren i den sidste allokering i

struct Whatever {
...
};

struct Blah {
...
};

...
Whatever *w = allocate (Whatever);
Blah *b = allocate (Blah);
Whatever *ww = allocate (Blah);

kan advare om at man misbruger Blah-pointeren; det ville den ikke
kunne hvis man havde indsat et Whatever-cast eller hvis man ikke havde
indsat noget cast.

Ulempen: at hvis man glemmer at inkludere stdio.h, risikerer man at
det går galt, eksisterer stadig, men det er nu kun ét sted man skal
huske at inkludere stdio.h.

Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408522
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste