139

Almost all languages have a foreach loop or something similar. Does C have one? Can you post some example code?

0

15 Answers 15

227

C doesn't have a foreach, but macros are frequently used to emulate that:

#define for_each_item(item, list) \
    for(T * item = list->head; item != NULL; item = item->next)

And can be used like

for_each_item(i, processes) {
    i->wakeup();
}

Iteration over an array is also possible:

#define foreach(item, array) \
    for(int keep = 1, \
            count = 0,\
            size = sizeof (array) / sizeof *(array); \
        keep && count != size; \
        keep = !keep, count++) \
      for(item = (array) + count; keep; keep = !keep)

And can be used like

int values[] = { 1, 2, 3 };
foreach(int *v, values) {
    printf("value: %d\n", *v);
}

Edit: In case you are also interested in C++ solutions, C++ has a native for-each syntax called "range based for"

Sign up to request clarification or add additional context in comments.

18 Comments

If you've got the "typeof" operator (gcc extension; pretty common on many other compilers) you can get rid of that "int *". The inner for loop becomes something like "for(typeof((array)+0) item = ..." Then you can call as "foreach( v, values ) ..."
@eSKay yes consider if(...) foreach(int *v, values) ... . If they are outside the loop it expands to if(...) int count = 0 ...; for(...) ...; and will break.
@rem it does not break the outer loop if you use "break"
@rem you can however simplify my code if you change the inner "keep = !keep" into "keep = 0". I liked the "symmetry" so i just used negation and not straight assignment.
@rem yes that is possible. But not portable. Typeof is nonstandard
|
17

As you probably already know, there's no "foreach"-style loop in C.

Although there are already tons of great macros provided here to work around this, maybe you'll find this macro useful:

// "length" is the length of the array.   
#define each(item, array, length) \
(typeof(*(array)) *p = (array), (item) = *p; p < &((array)[length]); p++, (item) = *p)

...which can be used with for (as in for each (...)).

Advantages of this approach:

  • item is declared and incremented within the for statement (just like in Python!).
  • Seems to work on any 1-dimensional array
  • All variables created in macro (p, item), aren't visible outside the scope of the loop (since they're declared in the for loop header).

Disadvantages:

  • Doesn't work for multi-dimensional arrays
  • Relies on typeof(), which is a GNU extension, not part of standard C
  • Since it declares variables in the for loop header, it only works in C11 or later.

Just to save you some time, here's how you could test it:

typedef struct {
    double x;
    double y;
} Point;

int main(void) {
    double some_nums[] = {4.2, 4.32, -9.9, 7.0};
    for each (element, some_nums, 4)
        printf("element = %lf\n", element);

    int numbers[] = {4, 2, 99, -3, 54};
    // Just demonstrating it can be used like a normal for loop
    for each (number, numbers, 5) { 
        printf("number = %d\n", number);
        if (number % 2 == 0)
                printf("%d is even.\n", number);
    }

    char* dictionary[] = {"Hello", "World"};
    for each (word, dictionary, 2)
        printf("word = '%s'\n", word);

    Point points[] = {{3.4, 4.2}, {9.9, 6.7}, {-9.8, 7.0}};
    for each (point, points, 3)
        printf("point = (%lf, %lf)\n", point.x, point.y);

    /* Neither p, element, number or word are visible outside the scope of
    their respective for loops. Try to see if these printfs work (they shouldn't): */
    //printf("*p = %s", *p);
    //printf("word = %s", word);

    return 0;
}

Seems to work on gcc and clang by default; haven't tested other compilers.

5 Comments

For loop declarations are actually part of the C99 standard.
Also you could avoid the typeof by passing the type as a macro argument. This is what you typically see in languages such as C#, with a syntax such as foreach (int n in numbers). Specifiying the type ensures you know what kind of data you're working especially if the array declaration is not right next to the loop.
typeof() is now blessed by C23. :)
You can make it work with multi-dimensional arrays, thanks to the decay operator (&*): #define each(ep, a, n) (typeof(&*(a)) (ep) = (a); (ep) < (a) + (n); (ep)++)
And if you'll only pass arrays, you could simplify: #define each(ep, a) (typeof(&*(a)) (ep) = (a); (ep) < ARRAY_SIZE(a); (ep)++)
13

Here is a full program example of a for-each macro in C99:

#include <stdio.h>

typedef struct list_node list_node;
struct list_node {
    list_node *next;
    void *data;
};

#define FOR_EACH(item, list) \
    for (list_node *(item) = (list); (item); (item) = (item)->next)

int
main(int argc, char *argv[])
{
    list_node list[] = {
        { .next = &list[1], .data = "test 1" },
        { .next = &list[2], .data = "test 2" },
        { .next = NULL,     .data = "test 3" }
    };

    FOR_EACH(item, list)
        puts((char *) item->data);

    return 0;
}

5 Comments

What does the dot do in the list[] definition? Couldn't you simply write next instead of .next?
@Rizo No, the dot is a part of the syntax for C99 designated initializers. See en.wikipedia.org/wiki/C_syntax#Initialization
@Rizo: Note also that that's a really hacky way of building a linked list. It'll do for this demo but don't do it that way in practice!
@Donal What makes it "hacky"?
@Judge: Well, for one thing it has “surprising” lifetime (if you're working with code which removes elements, chances are you'll crash in free()) and for another it has a reference to the value inside its definition. It's really an example of something that's just too damn clever; code's complex enough without purposefully adding cleverness to it. Kernighan's aphorism (stackoverflow.com/questions/1103299/…) applies!
10

There is no foreach in C.

You can use a for loop to loop through the data but the length needs to be know or the data needs to be terminated by a know value (eg. null).

char* nullTerm;
nullTerm = "Loop through my characters";

for(;nullTerm != NULL;nullTerm++)
{
    //nullTerm will now point to the next character.
}

3 Comments

You should add the initialization of the nullTerm pointer to the beginning of the data set. The OP might be confused about the incomplete for loop.
Fleshed out the example a little.
you are changing your original pointer, I would do something like: char* s;s="...";for(char *it=s;it!=NULL;it++){/*it point to the character*/}
8

While C does not have a for each construct, it has always had an idiomatic representation for one past the end of an array (&arr)[1]. This allows you to write a simple idiomatic for each loop as follows:

int arr[] = {1,2,3,4,5};
for(int *a = arr; a < (&arr)[1]; ++a)
    printf("%d\n", *a);

2 Comments

If not so sure this is well-defined. (&arr)[1] doesn't mean one array item past the end of the array, it means one array past the end of the array. (&arr)[1] is not the last item of array [0], it is the array [1], which decays into a pointer to the first element (of array [1]). I believe it would be much better, safer and idiomatic to do const int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr); and then for(const int* a = begin; a != end; a++).
@Lundin This is well defined. You're right, it's one array past the end of the array, but that array type converts to a pointer in this context (an expression), and that pointer is one past the end of the array.
5

This is a fairly old question, but I though I should post this. It is a foreach loop for GNU C99.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define FOREACH_COMP(INDEX, ARRAY, ARRAY_TYPE, SIZE) \
  __extension__ \
  ({ \
    bool ret = 0; \
    if (__builtin_types_compatible_p (const char*, ARRAY_TYPE)) \
      ret = INDEX < strlen ((const char*)ARRAY); \
    else \
      ret = INDEX < SIZE; \
    ret; \
  })

#define FOREACH_ELEM(INDEX, ARRAY, TYPE) \
  __extension__ \
  ({ \
    TYPE *tmp_array_ = ARRAY; \
    &tmp_array_[INDEX]; \
  })

#define FOREACH(VAR, ARRAY) \
for (void *array_ = (void*)(ARRAY); array_; array_ = 0) \
for (size_t i_ = 0; i_ && array_ && FOREACH_COMP (i_, array_, \
                                    __typeof__ (ARRAY), \
                                    sizeof (ARRAY) / sizeof ((ARRAY)[0])); \
                                    i_++) \
for (bool b_ = 1; b_; (b_) ? array_ = 0 : 0, b_ = 0) \
for (VAR = FOREACH_ELEM (i_, array_, __typeof__ ((ARRAY)[0])); b_; b_ = 0)

/* example's */
int
main (int argc, char **argv)
{
  int array[10];
  /* initialize the array */
  int i = 0;
  FOREACH (int *x, array)
    {
      *x = i;
      ++i;
    }

  char *str = "hello, world!";
  FOREACH (char *c, str)
    printf ("%c\n", *c);

  return EXIT_SUCCESS;
}

This code has been tested to work with gcc, icc and clang on GNU/Linux.

Comments

4

Here is what I use when I'm stuck with C. You can't use the same item name twice in the same scope, but that's not really an issue since not all of us get to use nice new compilers :(

#define FOREACH(type, item, array, size) \
    size_t X(keep), X(i); \
    type item; \
    for (X(keep) = 1, X(i) = 0 ; X(i) < (size); X(keep) = !X(keep), X(i)++) \
        for (item = (array)[X(i)]; X(keep); X(keep) = 0)

#define _foreach(item, array) FOREACH(__typeof__(array[0]), item, array, length(array))
#define foreach(item_in_array) _foreach(item_in_array)

#define in ,
#define length(array) (sizeof(array) / sizeof((array)[0]))
#define CAT(a, b) CAT_HELPER(a, b) /* Concatenate two symbols for macros! */
#define CAT_HELPER(a, b) a ## b
#define X(name) CAT(__##name, __LINE__) /* unique variable */

Usage:

int ints[] = {1, 2, 0, 3, 4};
foreach (i in ints) printf("%i", i);
/* can't use the same name in this scope anymore! */
foreach (x in ints) printf("%i", x);

EDIT: Here is an alternative for FOREACH using the c99 syntax to avoid namespace pollution:

#define FOREACH(type, item, array, size) \
    for (size_t X(keep) = 1, X(i) = 0; X(i) < (size); X(keep) = 1, X(i)++) \
    for (type item = (array)[X(i)]; X(keep); X(keep) = 0)

6 Comments

Note: VAR(i) < (size) && (item = array[VAR(i)]) would stop once the array element had a value of 0. So using this with double Array[] may not iterate through all elements. Seems like the loop test should be one or the other: i<n or A[i]. Maybe add sample use cases for clarity.
Even with pointers in my previous approach the result seems to be 'undefined behavior'. Oh well. Trust the double for loop approach!
This version pollutes the scope and will fail if used twice in the same scope. Also doesn't work as an un-braced block (e.g. if ( bla ) FOREACH(....) { } else....
1, C is the language of scope pollution, some of us are limited to older compilers. 2, Don't Repeat Yourself / be descriptive. 3, yeah, unfortunately you MUST have braces if it is going to be a conditional for loop (people usually do anyway). If you have access to a compiler that supports variable declarations in a for loop, by all means do it.
@Watercycle: I took the liberty to edit your answer with an alternative version of FOREACH that uses the c99 syntax to avoid namespace pollution.
|
3

C has 'for' and 'while' keywords. If a foreach statement in a language like C# looks like this ...

foreach (Element element in collection)
{
}

... then the equivalent of this foreach statement in C might be be like:

for (
    Element* element = GetFirstElement(&collection);
    element != 0;
    element = GetNextElement(&collection, element)
    )
{
    //TODO: do something with this element instance ...
}

3 Comments

You should mention that your example code is not written in C syntax.
> You should mention that your example code is not written in C syntax You're right, thank you: I'll edit the post.
@monjardin-> sure you can just define pointer to function in the struct and there is no problem to make the call like this.
2

Here's a simple one, single for loop:

#define FOREACH(type, array, size) do { \
        type it = array[0]; \
        for(int i = 0; i < size; i++, it = array[i])
#define ENDFOR  } while(0);

int array[] = { 1, 2, 3, 4, 5 };

FOREACH(int, array, 5)
{
    printf("element: %d. index: %d\n", it, i);
}
ENDFOR

Gives you access to the index should you want it (i) and the current item we're iterating over (it). Note you might have naming issues when nesting loops, you can make the item and index names be parameters to the macro.

Edit: Here's a modified version of the accepted answer foreach. Lets you specify the start index, the size so that it works on decayed arrays (pointers), no need for int* and changed count != size to i < size just in case the user accidentally modifies 'i' to be bigger than size and get stuck in an infinite loop.

#define FOREACH(item, array, start, size)\
    for(int i = start, keep = 1;\
        keep && i < size;\
        keep = !keep, i++)\
    for (item = array[i]; keep; keep = !keep)

int array[] = { 1, 2, 3, 4, 5 };
FOREACH(int x, array, 2, 5)
    printf("index: %d. element: %d\n", i, x);

Output:

index: 2. element: 3
index: 3. element: 4
index: 4. element: 5

Comments

1

Eric's answer doesn't work when you're using "break" or "continue".

This can be fixed by rewriting the first line:

Original line (reformatted):

for (unsigned i = 0, __a = 1; i < B.size(); i++, __a = 1)

Fixed:

for (unsigned i = 0, __a = 1; __a && i < B.size(); i++, __a = 1)

If you compare it to Johannes' loop, you'll see that he's actually doing the same, just a bit more complicated and uglier.

Comments

1

If you're planning to work with function pointers

#define lambda(return_type, function_body)\
    ({ return_type __fn__ function_body __fn__; })

#define array_len(arr) (sizeof(arr)/sizeof(arr[0]))

#define foreachnf(type, item, arr, arr_length, func) {\
    void (*action)(type item) = func;\
    for (int i = 0; i<arr_length; i++) action(arr[i]);\
}

#define foreachf(type, item, arr, func)\
    foreachnf(type, item, arr, array_len(arr), func)

#define foreachn(type, item, arr, arr_length, body)\
    foreachnf(type, item, arr, arr_length, lambda(void, (type item) body))

#define foreach(type, item, arr, body)\
    foreachn(type, item, arr, array_len(arr), body)

Usage:

int ints[] = { 1, 2, 3, 4, 5 };
foreach(int, i, ints, {
    printf("%d\n", i);
});

char* strs[] = { "hi!", "hello!!", "hello world", "just", "testing" };
foreach(char*, s, strs, {
    printf("%s\n", s);
});

char** strsp = malloc(sizeof(char*)*2);
strsp[0] = "abcd";
strsp[1] = "efgh";
foreachn(char*, s, strsp, 2, {
    printf("%s\n", s);
});

void (*myfun)(int i) = somefunc;
foreachf(int, i, ints, myfun);

But I think this will work only on gcc (not sure).

Comments

1

C does not have an implementation of for-each. When parsing an array as a point the receiver does not know how long the array is, thus there is no way to tell when you reach the end of the array. Remember, in C int* is a point to a memory address containing an int. There is no header object containing information about how many integers that are placed in sequence. Thus, the programmer needs to keep track of this.

However, for lists, it is easy to implement something that resembles a for-each loop.

for(Node* node = head; node; node = node.next) {
   /* do your magic here */
}

To achieve something similar for arrays you can do one of two things.

  1. use the first element to store the length of the array.
  2. wrap the array in a struct which holds the length and a pointer to the array.

The following is an example of such struct:

typedef struct job_t {
   int count;
   int* arr;
} arr_t;

Comments

0

I defined foreach using a macro and helper function. It allows for nested cycles (although limited) and the item is only defined in scope of the cycle. The only problem is that the macro contains 2 statements, so no if(...) foreach(...) printf(...);, but I wouldn't recommend doing that with any statement.

You can probably improve it with the gnu typeof macro and the #define in ,, if you want.

#define MAX_FOREACH_NESTING 16

#define foreach(type, item, set) \
    helper_foreach_next(NULL, 0, NULL, 0, 1); \
    for(type item;helper_foreach_next((char *) array, sizeof(array)/sizeof(array[0]), &item, sizeof(type), 0);)


int helper_foreach_next(char *array, size_t array_size, void *item, size_t item_size, int setup) {
    static int nesting = -1;
    static size_t indexes[MAX_FOREACH_NESTING] = { 0 };

    if(setup) {
        nesting++;
        return 0;
    }
    if (indexes[nesting] < array_size) {
        memcpy(item, array + indexes[nesting]*item_size, item_size);
        indexes[nesting]++;
        return 1;
    } else {
        indexes[nesting] = 0;
        nesting--;
        return 0;
    }
}

You can call it like this:

int array1[] = { 3, 4, 5};

foreach(int, a, array1) {
    foreach(int, b, array1) {
        printf("%d-%d\n", a, b);
    }
}

Comments

0

Here are some more foreach macros:

They are fully standard-compliant but require C99.

Standard

  • type cannot be const-qualified
  • Mangles a pointer to the current element: you can change __p_##varName to a friendlier name if necessary.
#include <stdio.h>

#define foreach(type, varName, array, count) for (   \
    type *__p_##varName = array, varName = array[0]; \
    __p_##varName != array + count;                  \
    varName = *(++__p_##varName))

int main()
{
    int arr[] = { 1,2,3,4,5 };
    
    foreach(int, myInt, arr, 5)
    {
        printf("%d\n", myInt);
    }
    
    return 0;
}

Pointer

  • type can be const-qualified
  • varName will be of type*
#include <stdio.h>

#define foreach(type, varName, array, count) for ( \
    type *varName = array;                         \
    varName != array + count;                      \
    ++varName)

int main()
{
    int arr[] = { 1,2,3,4,5 };
    
    foreach(int const, myInt, arr, 5)
    {
        printf("%d\n", *myInt);
    }
    
    return 0;
}

Body

  • type can be const-qualified
  • Requires loop body to be passed as an argument
  • Mangles a pointer to the current element: you can change __p_##varName to a friendlier name if necessary.
#include <stdio.h>

#define foreach(type, varName, array, count, body) for ( \
    type *__p_##varName = array;                         \
    __p_##varName != array + count;                      \
    ++__p_##varName)                                     \
    { type varName = *__p_##varName; { body } }

int main()
{
    int arr[] = { 1,2,3,4,5 };
    
    foreach(int const, myInt, arr, 5,
    {
        printf("%d\n", myInt);
    })

    // Also supports single-statement style:
    foreach(int const, myInt, arr, 5,
        printf("%d\n", myInt);)
    
    return 0;
}

Please be careful though: defining custom control structures with macros could hurt code readability.

Comments

0

To do a range over a C style array, you can build a set of macros that will allow you to create a rangefor macro that will do the job with some limitations. With this macro you can iterate over an array using a pointer to the current item. The main problem is that the rangefor macro must be able to see the definition of the array so that it can determine the size of the array. However below we have a solution for this issue to allow us to pass an array to a function and use a similar macro arrayfor to iterate over it.

One thing to note is that this requires C11. I doubt it will compile with earlier compilers. In my testing I used Visual Studio 2019 Community Edition. Some of this code depends on the C operator precedence and the fact that the dot (.) operator has higher precedence than the dereference operator (*) so *jj.i is the same as *(jj.i).

Using this system you can have constructions such as:

    int ar[] = { 1,2,3,4,5,6 };
    int ari, i;

    rangefor(jj, ar, int) {
        int k = *jj.i;    // jj is the name specified in the macro, i is the iterator.
    }

    typedef struct {
        int a;
        int b;
        int c;
    } MyType;

    MyType arg[] = { {1,2,3}, {4,5,6}, {7,8,9} };

    rangefor(jj, arg, MyType) {
        MyType k = *jj.i;
        (jj.i)->a = 5;
    }

Here are the three macros that are combined together to provide this fairly flexible rangefor addition to the C language.

#define rangeset(x, y, t)  struct { \
        t *i;   \
        t *ar;     \
        t *begin;  \
        t *end;    \
    } x = { y, y, y, y + sizeof(y)/sizeof(y[0]) }

#define rangeend(x)  (x).i < (x).end

#define rangefor(x,y,t) for (rangeset(x, y,t); rangeend(x); ++((x).i))

Passing an array to a function

If we are passing the array to a function where we want do use the rangefor, we have to do a bit of extra work. The problem is that when you pass an array to a function, the array size information is discarded and what the function sees is a pointer to the array. So the rangefor provided above isn't a solution.

What we can do is to provide a mechanism to know the beginning and end of the array. We will require of the programmer that she know and can specify the type for the array and all we need to wrap up and deliver to the function is the beginning pointer to the array and the ending pointer of the array.

So our function may look something like the following initially using the C for keyword:

int jfunc(MyType *p, size_t n) {

    for (MyType *x ; x < p + n; ++x) {
        MyType k = *x;
        k.a += 1;
    }
}

What we are going to do is to change the function argument list to use an unnamed struct with Preprocessor macros to hide the dirty plumbing.

First we will introduce the macro for our new arrayfor keyword.

#define arraypset(x, p, t) struct { \
        t *i; /* current item */   \
        t *ar;     \
        t *begin; /* first array item */ \
        t *end; /* last array item + 1 */   \
    } x = { p->a, p->a, p->a, p->end }

#define arrayfor(x, p, t) for (arraypset((x),(p),t); rangeend(x); ++((x).i))

Next we introduce a couple of helper macros that will make it easy to specify the function interface. Notice that arrayfor is similar to rangefor however it uses arraypset() to initialize the for statement rather than rangeset.

#define arrayp(x) struct { void * a; void * end; } * (x)

#define arrayit(ar) (void *)&((struct { void * a; void * end; }) {ar, ar + sizeof(ar)/sizeof(ar\[0\])})

One thing to notice about the macro arrayit() is that it creates a void pointer to an unnamed struct containing the minimum necessary characteristics of the array. It is expected that any function that is called with this array wrapper will know the type of the array and will only need to know its beginning and its end.

And then we rewrite the function to use our new macros for doing a version of foreach.

int jfunc(arrayp(p)) {

    arrayfor(jj, p, MyType) {
        MyType k = *jj.i;
        k.a += 1;
    }
}

and when we call the function, it will look something like the following:

jfunc(arrayit(arg));

We can also create an array descriptor whose address is stored in a void pointer and then use that pointer as an argument to the function.

void *pr = arrayit(arg);  // create array descriptor with a pointer to it

jfunc(pr);    // call a function with the void pointer to array descriptor.

Or we can create a variable containing the array descriptor by using the arrayp() macro to create the variable and assign the pointer to the variable created.

arrayp(q) = pr;

printf("\narrayfor with arrayp() from void pointer\n");
arrayfor(jj, q, MyType) {
    printf("  jj.i->a = %d, %d, %d\n", jj.i->a, jj.i->b, jj.i->c);
}

Important Note about arrayit() macro

When you use the macro arrayit() to create an array descriptor and assign the address of that descriptor to a void pointer, the address is only good for the scope in which the arrayit() macro is used. So you can use the pointer created as a function argument or with the arrayfor() macro within the same scope as the arrayit() macro. However once you leave that valid scope the pointer is no longer guaranteed to point to a valid array descriptor.

Also note that you may also see the following warning or at least I see it with Microsoft Visual Studio Community Edition 2019 with warning level 3:

warning C4116: unnamed type definition in parentheses

The entire test harness

A complete test harness for all of the above would look like the following. In the macros, the argument x is the temporary variable used in the rangefor or arrayfor as the array is iterated. The argument t is the type for the array.

#define rangeset(x, y, t)  struct { \
        t *i; /* current item */   \
        t *ar;     \
        t *begin; /* first array item */ \
        t *end; /* last array item + 1 */   \
    } x = { y, y, y, y + sizeof(y)/sizeof(y[0]) }

#define rangeend(x)  (x).i < (x).end

#define rangefor(x,y,t) for (rangeset((x),(y),t); rangeend(x); ++((x).i))

#define arrayp(x) struct { void* a; void* end; } * (x)

#define arrayit(ar) (void *)&((struct { void* a; void* end; }) {ar, ar + sizeof(ar)/sizeof(ar[0])})

#define arraypset(x, p, t) struct { \
        t *i; /* current item */   \
        t *ar;     \
        t *begin; /* first array item */ \
        t *end; /* last array item + 1 */   \
    } x = { p->a, p->a, p->a, p->end }

#define arrayfor(x, p, t) for (arraypset((x),(p),t); rangeend(x); ++((x).i))


typedef struct {
    int a;
    int b;
    int c;
} MyType;

int jfunc(arrayp(p)) {

    arrayfor(jj, p, MyType) {
        MyType k = *jj.i;
    printf ("k = %d, %d, %d\n", k.a, k.b, k.c);
    }
    return 0;
}

int main () {

    int ar[] = { 1,2,3,4,5,6 };
    int ari;

    rangefor(jj, ar, int) {
        int k = *jj.i;
        printf (" k = %d\n", k);
    }


    MyType arg[] = { {1,2,3}, {4,5,6}, {7,8,9} };

    rangefor(jj, arg, MyType) {
        MyType k = *jj.i;

        printf ("k = %d, %d, %d\n", k.a, k.b, k.c);

        (jj.i)->a = 5;
    }

    jfunc(arrayit(arg));


    void *pr = arrayit(arg);  // create array descriptor with a pointer to it

    jfunc(pr);    // call a function with the void pointer to array descriptor.


    arrayp(q) = pr;

    printf("\narrayfor with arrayp() from void pointer\n");
    arrayfor(jj, q, MyType) {
        printf("  jj.i->a = %d, %d, %d\n", jj.i->a, jj.i->b, jj.i->c);
    }

    return 0;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.