Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

11

02.04.2011, 11:16

Ich weiß jetzt nicht, ob ich dich richtig verstanden habe, aber du willst einen Zeiger auf ein 2D-Array an eine Funktion übergeben!?
Wenn ja, wurde die Funktion denke ich so aussehen:

C-/C++-Quelltext

1
2
3
4
5
// Funktion, die den Zeiger benötigt
void Funktion(S_Spielfeld* Spielfeld[Breite][Höhe]){
  ...
  return;
}

Und der Funktionsaufruf so:

C-/C++-Quelltext

1
2
3
4
5
6
7
int main(){
  ...
  S_Spielfeld Spielfeld[Breite][Höhe];
  Funktion(&Spielfeld);
  ...
  return 0;
}

jokester

Treue Seele

Beiträge: 125

Wohnort: Mainz

  • Private Nachricht senden

12

02.04.2011, 11:21


arrays sind ja eigentlich nichts anderes als pointer, nur eben ne "extra" syntax.

Bullshit. :P
Beweis:

Quellcode

1
2
3
4
5
6
7
8
9
#include <iostream>
int main()
{
    int array[10];
    int* pointer = array;
    std::cout << sizeof(array) << ' ' << sizeof(pointer) << '\n';
    std::cout << &array << ' ' << &array[0] << '\n';
    std::cout << &pointer << ' ' << &pointer[0] << '\n';
}

Und der char array[X][Y] ==char** array-Kram stimmt noch weniger. Da klappt nichtmal die Zuweisung, weil der array-to-pointer-decay nur auf Toplevel-Ebene funktioniert. Man könnte ein char array[X][Y] höchstens einem char (*pointer)[Y] zuweisen. char** ist was völlig anderes.

@ Harry: nimm S_Spielfeld (*Spielfeld)[Hoehe] als Parameter. oder S_Spielfeld Spielfeld[][Hoehe].
"There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened" -- Douglas Adams.

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

13

02.04.2011, 11:24

@jokester Wiso das denn? :huh:

jokester

Treue Seele

Beiträge: 125

Wohnort: Mainz

  • Private Nachricht senden

14

02.04.2011, 11:25

Weil deine Version nicht kompiliert.
"There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened" -- Douglas Adams.

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

15

02.04.2011, 11:35

Stimmt! :pinch:
Hatte ich vergessen, dass das nicht funktioniert! ^^

16

02.04.2011, 11:43

@jokester:

ich sagte _eigentlich_. genauer lesen pls.

und zweitens:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
struct _game_field {
    unsigned int l;
    bool **field;
};

static struct _game_field *new_game_field(unsigned int l)
{
    int i, j;
    struct _game_field *n;

    // allocate memory for the game field struct
    n = malloc(sizeof(struct _game_field));
    if(!n)
        return NULL;

    n->l = l;
    // allocate memory for pointers to each row
    n->field = malloc(sizeof(bool *) * l);
    if(!n->field){
        free(n);
        return NULL;
    }

    // allocate space on each row for l fields
    for(i = 0; i < l; i++){
        n->field[i] = malloc(sizeof(bool) * l);

        // then we're out of memory, clean up
        if(!n->field[i]){
            while(i--)
                free(n->field[i]);

            free(n->field);
            free(n);
            return NULL;
        }
    }

    // set all fields to 0
    for(i = 0; i < l; i++)
        for(j = 0; j < l; j++)
            n->field[i][j] = 0;

    return n;
}


bool **field == field[x][y]. von der verwendung her.
sehe da keine zuweisungsprobleme oder sonstiges.


game_of_life code bsp.:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*
 * game of life
 * (c) 2010 richard weinberger <richard@nod.at>
 *
 * usage:
 * $ mkdir tmp
 * $ cd tmp
 * $ ../gol 150 50 7
 * $ convert -delay 75 -loop 0 field* ../game_of_life.gif
 * $ cd ..
 * $ gwenview game_of_life.gif
 * $ rm -rf tmp/
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>

#ifdef DEBUG
    #define debug(fmt, ...) printf("DEBUG: " fmt, __VA_ARGS__)
#else
    #define debug(fmt, ...) {}while(0)
#endif

struct _game_field {
    unsigned int l;
    bool **field;
};

static struct _game_field *new_game_field(unsigned int l)
{
    int i, j;
    struct _game_field *n;

    // allocate memory for the game field struct
    n = malloc(sizeof(struct _game_field));
    if(!n)
        return NULL;

    n->l = l;
    // allocate memory for pointers to each row
    n->field = malloc(sizeof(bool *) * l);
    if(!n->field){
        free(n);
        return NULL;
    }

    // allocate space on each row for l fields
    for(i = 0; i < l; i++){
        n->field[i] = malloc(sizeof(bool) * l);

        // then we're out of memory, clean up
        if(!n->field[i]){
            while(i--)
                free(n->field[i]);

            free(n->field);
            free(n);
            return NULL;
        }
    }

    // set all fields to 0
    for(i = 0; i < l; i++)
        for(j = 0; j < l; j++)
            n->field[i][j] = 0;

    return n;
}

static struct _game_field *copy_game_field(struct _game_field *gf)
{
    struct _game_field *n;
    int i;

    // request a new game field
    n = new_game_field(gf->l);
    if(!n)
        return NULL;

    n->l = gf->l;
    for(i = 0; i < gf->l; i++){
        // copy each row from the old one
        // memcpy() is faster than copying field per field by hand
        memcpy(n->field[i], gf->field[i], sizeof(bool) * gf->l);
    }

    return n;
}

static void del_game_field(struct _game_field *gf)
{
    int i;

    // free each row
    for(i = 0; i < gf->l; i++)
        free(gf->field[i]);

    // free pointers to each row
    free(gf->field);
    // free the remaining struct
    free(gf);
}

static int get_neighbors(struct _game_field *gf, int x, int y)
{
    int n = 0;
    int l = gf->l - 1;

    // check each neighbor
    // it's simpler to write 8 if statements than a complex loop 8-)

    if(l > x && gf->field[x + 1][y])
        n++;

    if(l > y && gf->field[x][y + 1])
        n++;

    if(l > x && l > y && gf->field[x + 1][y + 1])
        n++;

    if(x && y && gf->field[x - 1][y - 1])
        n++;

    if(x && gf->field[x - 1][y])
        n++;

    if(y && gf->field[x][y - 1])
        n++;

    if(l > x && y && gf->field[x + 1][y - 1])
        n++;

    if(x && l > y && gf->field[x - 1][y + 1])
        n++;

    return n;
}

static struct _game_field *game_iteration(struct _game_field *gf)
{
    int i, j, n;
    // request a copy of our current game field
    struct _game_field *next = copy_game_field(gf);

    if(!next)
        return NULL;

    // apply for each cell the three rules on the new game field
    for(i = 0; i < gf->l; i++){
        for(j = 0; j < gf->l; j++){
            // get neighbors of cell i,j
            n = get_neighbors(gf, i, j);

            if(gf->field[i][j] && n <= 1){
                debug("field[%i][%i] dies!\n", i, j);
                next->field[i][j] = 0;
            }
            if(gf->field[i][j] && n >= 4){
                debug("field[%i][%i] dies!\n", i, j);
                next->field[i][j] = 0;
            }
            if(!gf->field[i][j] && n == 3){
                debug("field[%i][%i] lifes!\n", i, j);
                next->field[i][j] = 1;
            }
        }
    }

    del_game_field(gf);

    return next;
}

static int write_pbm_file(const char *fn, struct _game_field *gf)
{
    int i, j;
    FILE *fp;

    debug("writing game field to %s\n", fn);

    // open the file for writing
    fp = fopen(fn, "w+");
    if(!fp){
        printf("unable to open '%s' - '%s'\n", fn, strerror(errno));

        return -1;
    }

    // write the pbm header
    fprintf(fp, "P1\n");
    fprintf(fp, "%i\n", gf->l);
    fprintf(fp, "%i\n", gf->l);

    // write each cell
    for(i = 0; i < gf->l; i++)
        for(j = 0; j < gf->l; j++)
            fprintf(fp, "%i\n", gf->field[i][j]);

    fclose(fp);

    return 0;
}

static void set_random_life(struct _game_field *gf, int factor)
{
    int i, j, k;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    srand(tv.tv_usec);

    // when we have n cells, select n times a random cell to be alive
    for(i = 0; i < gf->l * gf->l; i = i + factor){
        j = rand() % gf->l;
        k = rand() % gf->l;

        gf->field[j][k] = 1;
    }
}

static void run_game(int length, int iterations, int factor)
{
    int i;
    char fname[256] = {0};
    struct _game_field *gf;

    // create the initial game field
    gf = new_game_field(length);
    if(!gf){
        printf("Unable to allocate memory for game field!\n");

        return;
    }

    // fill it randomly with life
    set_random_life(gf, factor);

    // for each iteration write a pbm file, apply the three rules of life
    for(i = 0; i < iterations; i++){
        debug("game iteration %i of %i\n", i, iterations);
        snprintf(fname, sizeof fname, "field%03i.pbm", i);
        write_pbm_file(fname, gf);
        gf = game_iteration(gf);
        if(!gf){
            printf("Unable to allocate memory for next game field!\n");

            return;
        }
    }

    del_game_field(gf);
}

int main(int argc, char **argv)
{
    int length;
    int iterations;
    int factor;

    if(argc < 4){
        printf("Usage: %s field-length num-iterations randfactor\n", argv[0]);

        return 1;
    }

    length = atoi(argv[1]);
    if(!length){
        printf("Invalid length value!\n");

        return 1;
    }

    iterations = atoi(argv[2]);
    if(!iterations){
        printf("Invalid iteration value!\n");

        return 1;
    }

    factor = atoi(argv[3]);
    if(!factor){
        printf("Invalid randfactor value!\n");

        return 1;
    }

    debug("running game with length=%i iterations=%i factor=%i\n", length, iterations, factor);
    run_game(length, iterations, factor);

    return 0;
}


ist zwar C, aber das ist in c++ nicht viel anders.

edit: nvm. wir haben das anders gelöst sehe ich gerade. wir übergeben nirgends dann das field, sondern haben das in der struktur eingekapselt. ist also was anderes. dennoch bleibt meine ursprüngliche aussage stehen. wenn ich ein array/2d array habe, kann ich damit genausogut mit einem pointer/doublepointer durch das array durchgehen. siehe auch codebeispiel

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Draculark« (02.04.2011, 11:54)


Werbeanzeige