change index between 0 and 1

E

Eric Lilja

Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?
 
K

Keith Thompson

Eric Lilja said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

The obvious way to do this would be to pass the index as a parameter,
but I presume you to do this independently of the caller.

Here's one approach:

void func(whatever)
{
static int index = 0;
static element_type arr[2];
/* ... code referring to arr[index] ... */
index = 1 - index;
}

For sizes other than 2, something like this:

index = (index + 1) % ARRAY_SIZE;

is more general.
 
I

Ian Collins

Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?
static unsigned index = 1;

return array[index^=1];
 
P

pete

Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

/* BEGIN new.c */

#include <stdio.h>

void sequence(size_t first, size_t second);

int main(void)
{
unsigned flip;
size_t index;

puts("/* BEGIN new.c output */\n");
for (index = 0; index != 5; ++index) {
sequence(flip++ & 1, index);
sequence(flip++ & 1, index);
}
puts("\n\n/* END new.c output */");
return 0;
}

void sequence(size_t first, size_t second)
{
int array[][5] = {0,2,4,6,8,1,3,5,7,9};

putchar('0' + array[first][second]);
}

/* END new.c */
 
J

Jack Klein

Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

static int index = 1; /* you'll see in a minute */

int values [2] = { first_value, second_value };

int get_value(void)
{
index = !index;
return values [index];
}

Initializing to 1 and performing the logical negation before use
ensures two things. First, you get the 0 element of the array the
first time, and second that the value you use for the subscript is
always 0 or 1, never out of range.
 
M

Martin Ambuhl

Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

void function(void)
{
static int index;
index = 1 - index;
}
 
N

Neil

Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?


how about:

index = (++index % 2); // works for powers of 2
return array[index];
 
B

Ben Pfaff

Neil said:
index = (++index % 2); // works for powers of 2

If "works" means "invokes undefined behavior", then you're
correct ;-)

Your suggestion is undefined because it modifies the value of
`index' twice between sequence points.

Here is a working suggestion in the same pattern as yours:
index = (index + 1) % 2;
 
E

Eric Lilja

Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

Thanks for the replies, everyone, I actually had a ++index %
2-statement
(index was initialized to 0), but I had forgot to make it static so I
always ended up using the element with index 0, heh. Now to a question
to a related problem, why am I getting the following warnings and how
do I fix
them?

typedef void (* fptr)();
fptr * array[] = {idle_callback, NULL}; /* This is the actual
two-element array. */
Warning for line above:
simple_1-5.c:24: warning: initialization from incompatible pointer type
idle_callback is declared as: static void idle_callback(void);

glutIdleFunc(array[++index % 2]);
Warning for line above:
simple_1-5.c:32: warning: passing arg 1 of `glutIdleFunc' from
incompatible pointer type

They seem harmless because my program works as expected on my system at
least, but I'd like to fix them anyway.
 
A

Antonio Contreras

Eric said:
Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

Thanks for the replies, everyone, I actually had a ++index %
2-statement
(index was initialized to 0), but I had forgot to make it static so I
always ended up using the element with index 0, heh. Now to a question
to a related problem, why am I getting the following warnings and how
do I fix
them?

typedef void (* fptr)();
fptr * array[] = {idle_callback, NULL}; /* This is the actual
two-element array. */
Warning for line above:
simple_1-5.c:24: warning: initialization from incompatible pointer type
idle_callback is declared as: static void idle_callback(void);

glutIdleFunc(array[++index % 2]);
Warning for line above:
simple_1-5.c:32: warning: passing arg 1 of `glutIdleFunc' from
incompatible pointer type

They seem harmless because my program works as expected on my system at
least, but I'd like to fix them anyway.

The warning description is quite explicit. You are initializing a
function pointer array element with a pointer of a different type. Look
at the declarations. fptr is declared as:

typedef void (* fptr) ();

This a pointer to a function returning void and with unspecified
parameters.

In the warning message says that idle_callback is declared as:

static void idle_callback (void);

This is a pointer to a function returning void and with no parameters.
Those types are not the same. The easiest way to remove those warnings
is to redeclare fptr as:

typedef void (* fptr) (void);
 
E

Eric Lilja

Antonio said:
Eric said:
Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

Thanks for the replies, everyone, I actually had a ++index %
2-statement
(index was initialized to 0), but I had forgot to make it static so I
always ended up using the element with index 0, heh. Now to a question
to a related problem, why am I getting the following warnings and how
do I fix
them?

typedef void (* fptr)();
fptr * array[] = {idle_callback, NULL}; /* This is the actual
two-element array. */
Warning for line above:
simple_1-5.c:24: warning: initialization from incompatible pointer type
idle_callback is declared as: static void idle_callback(void);

glutIdleFunc(array[++index % 2]);
Warning for line above:
simple_1-5.c:32: warning: passing arg 1 of `glutIdleFunc' from
incompatible pointer type

They seem harmless because my program works as expected on my system at
least, but I'd like to fix them anyway.

The warning description is quite explicit. You are initializing a
function pointer array element with a pointer of a different type. Look
at the declarations. fptr is declared as:

typedef void (* fptr) ();

This a pointer to a function returning void and with unspecified
parameters.

In the warning message says that idle_callback is declared as:

static void idle_callback (void);

This is a pointer to a function returning void and with no parameters.
Those types are not the same. The easiest way to remove those warnings
is to redeclare fptr as:

typedef void (* fptr) (void);

No, that wasn't it. That yields the same warnings. The error turned out
to be:
fptr * array[] = {idle_callback, NULL};
this should be
fptr array[] = {idle_callback, NULL};
 
S

stathis gotsis

Eric Lilja said:
Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

Thanks for the replies, everyone, I actually had a ++index %
2-statement
(index was initialized to 0), but I had forgot to make it static so I
always ended up using the element with index 0, heh. Now to a question
to a related problem, why am I getting the following warnings and how
do I fix
them?

typedef void (* fptr)();
fptr * array[] = {idle_callback, NULL}; /* This is the actual
two-element array. */
Warning for line above:
simple_1-5.c:24: warning: initialization from incompatible pointer type
idle_callback is declared as: static void idle_callback(void);

glutIdleFunc(array[++index % 2]);
Warning for line above:
simple_1-5.c:32: warning: passing arg 1 of `glutIdleFunc' from
incompatible pointer type

They seem harmless because my program works as expected on my system at
least, but I'd like to fix them anyway.

Try this change:
fptr array[]={idle_callback,NULL};
 
A

Antonio Contreras

Eric said:
Antonio said:
Eric said:
Eric Lilja wrote:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

Thanks for the replies, everyone, I actually had a ++index %
2-statement
(index was initialized to 0), but I had forgot to make it static so I
always ended up using the element with index 0, heh. Now to a question
to a related problem, why am I getting the following warnings and how
do I fix
them?

typedef void (* fptr)();
fptr * array[] = {idle_callback, NULL}; /* This is the actual
two-element array. */
Warning for line above:
simple_1-5.c:24: warning: initialization from incompatible pointer type
idle_callback is declared as: static void idle_callback(void);

glutIdleFunc(array[++index % 2]);
Warning for line above:
simple_1-5.c:32: warning: passing arg 1 of `glutIdleFunc' from
incompatible pointer type

They seem harmless because my program works as expected on my system at
least, but I'd like to fix them anyway.

The warning description is quite explicit. You are initializing a
function pointer array element with a pointer of a different type. Look
at the declarations. fptr is declared as:

typedef void (* fptr) ();

This a pointer to a function returning void and with unspecified
parameters.

In the warning message says that idle_callback is declared as:

static void idle_callback (void);

This is a pointer to a function returning void and with no parameters.
Those types are not the same. The easiest way to remove those warnings
is to redeclare fptr as:

typedef void (* fptr) (void);

No, that wasn't it. That yields the same warnings. The error turned out
to be:
fptr * array[] = {idle_callback, NULL};
this should be
fptr array[] = {idle_callback, NULL};

Yup, missed that little asterisk. However, it is always a good idea
beeing explicit about the parameters when you declare function
pointers. That way the compiler can check argument types.
 
C

Chris McDonald

Sorry, I can no longer find earlier articles in this thread, but what
about the traditional:

static int index = 0;
......
index = 1 - index;
 
E

ena8t8si

Eric said:
Hello, I have a function that has a static array with two elements in
it. When the function is called the first time, it should access
element 0, the second time it should access element 1, the third time
element 0, the fourth element 1 etc. I can do it by having a static
variable holding the index and and if/else-statement but is there a
more clever way that doesn't need the if/else?

int alternate(void)
{
static int v[] = {411,219};
static _Bool vi;

return v[vi--];
}
 
M

Martin Ambuhl

Chris said:
Sorry, I can no longer find earlier articles in this thread, but what
about the traditional:

static int index = 0;
......
index = 1 - index;

When I suggested this in
<[email protected]> (11 hours before
yours) it was completely ignored, in favor of discussion of the sloppy
and obfuscated mechanism you responded to.
 
N

Neil

Ben said:
If "works" means "invokes undefined behavior", then you're
correct ;-)

Your suggestion is undefined because it modifies the value of
`index' twice between sequence points.

Here is a working suggestion in the same pattern as yours:
index = (index + 1) % 2;
Thanks
Sorry about the poor execution.
 
J

Joe Wright

Neil said:
Thanks
Sorry about the poor execution.

Too complicated. Assume a function to return alternatively 0, 1 then 0
etc. It might look like ..

int inc(void) {
static int i;
return i = i++ & 1;
}
 
P

pete

Joe said:
Too complicated. Assume a function to return alternatively 0, 1 then 0
etc. It might look like ..

int inc(void) {
static int i;
return i = i++ & 1;
}

That return statement has undefined behavior.

unsigned inc(void)
{
static unsigned i;

return i++ & 1;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top