referencing with &

R

Roman Mashak

Hello,

I encountered a piece of code, which I can't entirely understand. Here it
is:

#define TX_BUF_SIZE 1024
struct priv {
...
unsigned char *tx_buf[4];
unsigned char *tx_bufs;
};

static void init_ring()
{
struct priv *tp;
int i;
...
for (i = 0; i < 4; i++)
tp->tx_buf = &tp->tx_bufs[i * TX_BUF_SIZE];
}

static int open_dev()
{
...
/* here tp->tx_bufs gets initialised properly, i.e. it's not NULL. It
points to a big buffer */
init_ring();
...
}

Both structure members cause doubts to me: 'tx_buf' is array of pointers,
'tx_bufs' is just a pointer. So what they're doing in 'init_ring' is
initialising this array with addresses, but I can't figure out how. Setting
&tp->tx_bufs will yield address of object (i.e. address of pointer), so it
seems to me the wrong way, but ot works as it's supposed to do.

Please clarify my doubts. Thank you.
 
Y

yunyuaner

Hello,

I encountered a piece of code, which I can't entirely understand. Here it
is:

#define TX_BUF_SIZE 1024
struct priv {
...
unsigned char *tx_buf[4];
unsigned char *tx_bufs;

};

static void init_ring()
{
struct priv *tp;
int i;
...
for (i = 0; i < 4; i++)
tp->tx_buf = &tp->tx_bufs[i * TX_BUF_SIZE];

}

static int open_dev()
{
...
/* here tp->tx_bufs gets initialised properly, i.e. it's not NULL. It
points to a big buffer */
init_ring();
...

}

Both structure members cause doubts to me: 'tx_buf' is array of pointers,
'tx_bufs' is just a pointer. So what they're doing in 'init_ring' is
initialising this array with addresses, but I can't figure out how. Setting
&tp->tx_bufs will yield address of object (i.e. address of pointer), so it
seems to me the wrong way, but ot works as it's supposed to do.

Please clarify my doubts. Thank you.


I think there may be some codes like these which do not be shown here
tx_bufs = (unsigned char *)malloc(TX_BUF_SIZE * 4);
the four elements of the tx_buf array just point to the 4 segmengts of
tx_bufs,
each of which sized TX_BUF_SIZE.
I don't know if I made myself understood with my poor Enlish :)
 
J

Jack Klein

Hello,

I encountered a piece of code, which I can't entirely understand. Here it
is:

#define TX_BUF_SIZE 1024
struct priv {
...
unsigned char *tx_buf[4];
unsigned char *tx_bufs;
};

static void init_ring()
{
struct priv *tp;
int i;
...
for (i = 0; i < 4; i++)
tp->tx_buf = &tp->tx_bufs[i * TX_BUF_SIZE];
}

static int open_dev()
{
...
/* here tp->tx_bufs gets initialised properly, i.e. it's not NULL. It
points to a big buffer */
init_ring();
...
}

Both structure members cause doubts to me: 'tx_buf' is array of pointers,
'tx_bufs' is just a pointer. So what they're doing in 'init_ring' is
initialising this array with addresses, but I can't figure out how. Setting
&tp->tx_bufs will yield address of object (i.e. address of pointer), so it
seems to me the wrong way, but ot works as it's supposed to do.

Please clarify my doubts. Thank you.


Assuming that the tx_bufs pointer member of the structure is
initialized with the address of a block containing at least 4 *
TX_BUF_SIZE characters, then, as 'i' is incremented in four passes
through the loop:

tx_bufs [0 * TX_BUF_SIZE] is the first character that it points to and
&tx_bufs [0 * TX_BUF_SIZE] is the address of the first character.

So at the end of the loop, tx_buf[0] points to the first character of
the block, tx_buf[1] points to the 1024th character of the block, and
so on. This is because the & operator and the [] operator, when
applied to the same pointer in a single expression cancel each other
out (the standard actually states that "is evaluated and the result is
as if the & operator were removed and the [] operator were changed to
a + operator."

So &array[subscript] is equivalent to array + subscript.

Many C programmers, myself included, feel that the equivalent source
is much easier to understand:

for (i = 0; i < 4; i++)
tp->tx_buf = tp->tx_bufs + (i * TX_BUF_SIZE);

It makes it clearer that you are adding an integer value to a pointer,
which results in a pointer.
 
B

Bill Pursell

Hello,

I encountered a piece of code, which I can't entirely understand. Here it
is:
tp->tx_buf = &tp->tx_bufs[i * TX_BUF_SIZE];

<snip>

This is probably more clear if you read it as
tp->tx_buf = tp->tx_bufs + i * TX_BUF_SIZE

The array is simply being initialized to point
into the transfer buffer at equally spaced
intervals.
 
B

Barry Schwarz

Hello,

I encountered a piece of code, which I can't entirely understand. Here it
is:

#define TX_BUF_SIZE 1024
struct priv {
...
unsigned char *tx_buf[4];
unsigned char *tx_bufs;
};

static void init_ring()
{
struct priv *tp;
int i;
...
for (i = 0; i < 4; i++)
tp->tx_buf = &tp->tx_bufs[i * TX_BUF_SIZE];
}

static int open_dev()
{
...
/* here tp->tx_bufs gets initialised properly, i.e. it's not NULL. It
points to a big buffer */
init_ring();
...
}

Both structure members cause doubts to me: 'tx_buf' is array of pointers,
'tx_bufs' is just a pointer. So what they're doing in 'init_ring' is
initialising this array with addresses, but I can't figure out how. Setting
&tp->tx_bufs will yield address of object (i.e. address of pointer), so it


It would if the & operator were applied to tp->tx_bufs. But it isn't.
Se below.
seems to me the wrong way, but ot works as it's supposed to do.

The [] operator has higher precedence than the & operator. The
expression on the right hand side evaluates as &(tp->tx_bufs[...]).

Start at the beginning and work it through step by step.

tx_buf is an array of pointers.
tx_buf is the i-th pointer in the array. It will hold an
address.

tx_bufs is a pointer. It already holds an address (courtesy
of code you omitted). This address is the address of an object. By
program design, this object is the first of many objects arranged
sequentially in memory (just like an array of objects).
tx_bufs[i*TX_BUF_SIZE] is one of these objects.
&tx_bufs[i*TX_BUF_SIZE] is the address of the object describe
above.

The address of this object is assigned to the i-th pointer in
tx_buf.


Remove del for email
 
R

Roman Mashak

Hello, Barry!
You wrote on Mon, 12 Feb 2007 21:07:17 -0800:

[skip]
BS> tx_bufs is a pointer. It already holds an address (courtesy
BS> of code you omitted). This address is the address of an object. By
BS> program design, this object is the first of many objects arranged
BS> sequentially in memory (just like an array of objects).
BS> tx_bufs[i*TX_BUF_SIZE] is one of these objects.
BS> &tx_bufs[i*TX_BUF_SIZE] is the address of the object describe
BS> above. The address of this object is assigned to the i-th pointer in
BS> tx_buf.
I thank everybody for comprehensive explanation. The code is now obvious for
me.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top