/ 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
Pointer som alias til et pointerarray?
Fra : Bertel Lund Hansen


Dato : 19-06-09 22:43

Hej alle

Jeg ved ikke om jeg har glemt for meget C, eller det er umuligt.

Jeg har to arrays af pointere. Jeg vil gerne have at begge kan
behandles af de samme rutiner. Det kan jeg godt opnå ved hjælp af
en parameter.

Uddrag af forkortet kode:

struct filter{
   bool global;
   char *groupname;
};

struct filter
   *usenetfilters[FILTERMAX],
   *mailfilters[FILTERMAX]
;

void read_filters (struct filter *filters[], bool usefilter) {
   filtrene læses ...    
}

I main() prøvede jeg at gøre forskelligt. Jeg ville have en 'tom'
pointer til at udpege et af filtrene så det blev let at skifte
imellem dem. Men ligegyldigt hvad jeg gjorde, kunne jeg ikke få
det til at blive accepteret.

1   struct filter *filterpointer;
   filterpointer=usenetfilters;
   (suspicious pointer conversion)

2   struct filter *filterpointer[];
   filterpointer=usenetfilters;
   (size of filterpointer unknown)

3   void *filterpointer;
   filterpointer=usenetfilters;
   (size of type void unknown)

Kan man ikke få en pointer til at blive et alias til et
pointerarray?

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

 
 
Kent Friis (19-06-2009)
Kommentar
Fra : Kent Friis


Dato : 19-06-09 23:32

Den Fri, 19 Jun 2009 23:42:47 +0200 skrev Bertel Lund Hansen:
> Hej alle
>
> Jeg ved ikke om jeg har glemt for meget C, eller det er umuligt.
>
> Jeg har to arrays af pointere. Jeg vil gerne have at begge kan
> behandles af de samme rutiner. Det kan jeg godt opnå ved hjælp af
> en parameter.
>
> Uddrag af forkortet kode:
>
> struct filter{
>    bool global;
>    char *groupname;
> };
>
> struct filter
>    *usenetfilters[FILTERMAX],
>    *mailfilters[FILTERMAX]
> ;
>
> void read_filters (struct filter *filters[], bool usefilter) {
>    filtrene læses ...    
> }
>
> I main() prøvede jeg at gøre forskelligt. Jeg ville have en 'tom'
> pointer til at udpege et af filtrene så det blev let at skifte
> imellem dem. Men ligegyldigt hvad jeg gjorde, kunne jeg ikke få
> det til at blive accepteret.
>
> 1   struct filter *filterpointer;
>    filterpointer=usenetfilters;
>    (suspicious pointer conversion)
>
> 2   struct filter *filterpointer[];
>    filterpointer=usenetfilters;
>    (size of filterpointer unknown)
>
> 3   void *filterpointer;
>    filterpointer=usenetfilters;
>    (size of type void unknown)
>
> Kan man ikke få en pointer til at blive et alias til et
> pointerarray?

Du skal helt tilbage til det grundlæggende. Et array og en pointer
opfattes som "det samme". Fx:

char line[80];
char *p = line;

Så tilsvarende:

struct filter *usenetfilters[FILTERMAX];
struct filter **filterpointer = usenetfilters;

Fejlene ovenfor:

1) Compileren forsøger at fortælle der ikke er lige mange *'er.
filterpointer er *filter, usenetfilter er **filter.

2) Du erklærer filter som et array af pointere. Et array af ukendt
størrelse. Hvor meget memory skal compileren allokere?

3) Den fejl ser underlig ud. Som sådan er der ikke noget i vejen med en
void *p; Fejlbeskeden ligner nærmere at du er kommet til at skrive
void filterpointer;

Mvh
Kent
--
"The Brothers are History"

Michael Rasmussen (20-06-2009)
Kommentar
Fra : Michael Rasmussen


Dato : 20-06-09 00:45

On Fri, 19 Jun 2009 23:42:47 +0200
Bertel Lund Hansen <unospamo@lundhansen.dk> wrote:

>
> struct filter{
>    bool global;
>    char *groupname;
> };
>
Havde dette ikke være nemmere:

enum FilterType { FILTERTYPE_USENET, FILTERTYPE_MAIL };
struct filter{
   enum FilterType filter_type;
   bool global;
   char *groupname;
};

void read_filters (struct filter *filters[], bool usefilter) {
   int i;
   for (i = 0; *filters[i]; i++) {
      switch (filters[i]->filter_type) {
         case FILTERTYPE_USENET:
            ......
            break;
         case FILTERTYPE_MAIL:
            ......
            break;
         default:
            "unknown filter type";
      }
   }
}
--
Hilsen/Regards
Michael Rasmussen
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xE3E80917
A computer is like air conditioning: it becomes useless when you open
windows.


Kent Friis (20-06-2009)
Kommentar
Fra : Kent Friis


Dato : 20-06-09 07:29

Den Sat, 20 Jun 2009 01:45:28 +0200 skrev Michael Rasmussen:
> On Fri, 19 Jun 2009 23:42:47 +0200
> Bertel Lund Hansen <unospamo@lundhansen.dk> wrote:
>
>>
>> struct filter{
>>    bool global;
>>    char *groupname;
>> };
>>
> Havde dette ikke være nemmere:
>
> enum FilterType { FILTERTYPE_USENET, FILTERTYPE_MAIL };
> struct filter{
>    enum FilterType filter_type;
>    bool global;
>    char *groupname;
> };
>
> void read_filters (struct filter *filters[], bool usefilter) {
>    int i;
>    for (i = 0; *filters[i]; i++) {
>       switch (filters[i]->filter_type) {
>          case FILTERTYPE_USENET:
>             ......
>             break;
>          case FILTERTYPE_MAIL:
>             ......
>             break;
>          default:
>             "unknown filter type";
>       }
>    }
> }

Hvis du skal have noget der svarer til det oprindelige, skal du have
en ekstra parameter der fortæller hvilken filtertype man er
interesseret i, og skifte switchen ud med
if(filters[i]->filter_type == filter_type).

Ud over at introducere et ekstra check, vil det også gøre at den skal
læse alle filtre igennem, uanset om det er mails eller usenet man
filtrerer.

Mvh
Kent
--
"The Brothers are History"

Bertel Lund Hansen (20-06-2009)
Kommentar
Fra : Bertel Lund Hansen


Dato : 20-06-09 09:19

Michael Rasmussen skrev:

> Havde dette ikke være nemmere:

[klip]

> void read_filters (struct filter *filters[], bool usefilter) {
>    int i;
>    for (i = 0; *filters[i]; i++) {
>       switch (filters[i]->filter_type) {
>          case FILTERTYPE_USENET:

Pointen ved at lave et alias er at alle rutiner så er uvidende om
hvilken filtetype der er tale om, og det betyder at de kan
behandle alle ens uden at tjekke på typen - med forøget hastighed
til følge.

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

Michael Rasmussen (20-06-2009)
Kommentar
Fra : Michael Rasmussen


Dato : 20-06-09 14:08

On Sat, 20 Jun 2009 10:18:36 +0200
Bertel Lund Hansen <unospamo@lundhansen.dk> wrote:

>
> Pointen ved at lave et alias er at alle rutiner så er uvidende om
> hvilken filtetype der er tale om, og det betyder at de kan
> behandle alle ens uden at tjekke på typen - med forøget hastighed
> til følge.
>
Du kunne også overveje i stedet for at medsende den konkrete function
som parameter til dine rutiner. Nedenfor er en template for en sådan
løsning:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define FILTERMAX 100

typedef enum {
FALSE,
TRUE
} Bool;

typedef struct _Filter Filter;
struct _Filter {
Bool use_filter;
char* groupname;
};

static void handle_usenet(Filter* filter[], Bool usefilter) {
}

static void handle_mail(Filter* filter[], Bool usefilter) {
}

static void handle_filters(
void (*handler) (Filter**, Bool), Filter** filter, Bool usefilter) {
handler(filter, usefilter);
}

int main() {
Filter* usenet[FILTERMAX];
Filter* mail[FILTERMAX];

handle_filters(handle_usenet, usenet, TRUE);
handle_filters(handle_mail, mail, FALSE);
return EXIT_SUCCESS;
}

--
Hilsen/Regards
Michael Rasmussen
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xE3E80917
A computer is like air conditioning: it becomes useless when you open
windows.


Soeren Sandmann (21-06-2009)
Kommentar
Fra : Soeren Sandmann


Dato : 21-06-09 22:21

Bertel Lund Hansen <unospamo@lundhansen.dk> writes:

> 1   struct filter *filterpointer;
>    filterpointer=usenetfilters;
>    (suspicious pointer conversion)

Man kan ofte taenke paa arrays af type T som om de er pointere til
elementer af type T. I dette tilfaelde er T 'pointer til filter', saa
naar man konverterer et array til en pointer, bliver det til en
pointer til pointer til filter. Altsaa:

struct filter **filterpointer;

filterpointer = usenetfilters;

boer virke.

I laeserutinerne kan du derefter skrive noget i retning af

void process_filters (struct filter **filters)
{
for (i = 0; i < FILTERMAX; ++i)
{
struct filter *f = filters[i];

/* behandl f */
}
}



Soren

Bertel Lund Hansen (21-06-2009)
Kommentar
Fra : Bertel Lund Hansen


Dato : 21-06-09 22:26

Soeren Sandmann skrev:

> Man kan ofte taenke paa arrays af type T som om de er pointere til
> elementer af type T. I dette tilfaelde er T 'pointer til filter', saa
> naar man konverterer et array til en pointer, bliver det til en
> pointer til pointer til filter. Altsaa:

> struct filter **filterpointer;

Ja, Kent Friis skrev noget lignende. Det var dobbeltpointere jeg
havde glemt alt om.

Jeg har også set Michael Rasmussens sidste forslag som jeg vil
overveje.

Hvor er du henne i verden siden du ikke har danske bogstaver på
dit tastatur?

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

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

Månedens bedste
Årets bedste
Sidste års bedste