referencing with &

Discussion in 'C Programming' started by Roman Mashak, Feb 13, 2007.

  1. Roman Mashak

    Roman Mashak Guest

    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.

    ---
    Best regards, Roman
     
    Roman Mashak, Feb 13, 2007
    #1
    1. Advertising

  2. Roman Mashak

    Guest

    On 2ÔÂ13ÈÕ, ÉÏÎç11ʱ21·Ö, "Roman Mashak" <> wrote:
    > 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.
    >
    > ---
    > Best regards, Roman


    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 :)
     
    , Feb 13, 2007
    #2
    1. Advertising

  3. Roman Mashak

    Jack Klein Guest

    On Tue, 13 Feb 2007 12:21:08 +0900, "Roman Mashak" <>
    wrote in comp.lang.c:

    > 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.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Feb 13, 2007
    #3
  4. Roman Mashak

    Bill Pursell Guest

    On Feb 13, 3:21 am, "Roman Mashak" <> wrote:
    > Hello,
    >
    > I encountered a piece of code, which I can't entirely understand. Here it
    > is:

    <snip>
    > 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.

    --
    Bill Pursell
     
    Bill Pursell, Feb 13, 2007
    #4
  5. On Tue, 13 Feb 2007 12:21:08 +0900, "Roman Mashak" <>
    wrote:

    >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
     
    Barry Schwarz, Feb 13, 2007
    #5
  6. wrote:

    > I think there may be some codes like these which do not be shown here


    code. code. code.

    > tx_bufs = (unsigned char *)malloc(TX_BUF_SIZE * 4);


    No cast.
     
    Christopher Layne, Feb 13, 2007
    #6
  7. Roman Mashak

    Roman Mashak Guest

    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.

    ---
    Best regards, Roman Mashak
     
    Roman Mashak, Feb 13, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. K. Shier
    Replies:
    6
    Views:
    541
    K. Shier
    Oct 10, 2003
  2. geoffrey wall

    vhdl source cross-referencing tool

    geoffrey wall, Jul 1, 2005, in forum: VHDL
    Replies:
    7
    Views:
    2,073
    Ajeetha
    Jul 7, 2005
  3. John
    Replies:
    2
    Views:
    395
    David Waz...
    Jul 8, 2003
  4. Mark Friedman

    Referencing subcontrols within UserControl

    Mark Friedman, Jul 9, 2003, in forum: ASP .Net
    Replies:
    4
    Views:
    412
    Christopher Young
    Jul 14, 2003
  5. William F. Robertson, Jr.

    Re: Referencing Custom Page Class within a Control

    William F. Robertson, Jr., Jul 10, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    399
    Cheung, Jeffrey Jing-Yen
    Jul 10, 2003
Loading...

Share This Page