Question on Pointers

Discussion in 'C Programming' started by Zero, Feb 23, 2006.

  1. Zero

    Zero Guest

    Hello everybody!

    I have a question and need some kind of confirmation!

    Is it right that


    pChar[2] = 'a' is the same as
    *(pChar + 2) = 'a'!

    (where char * pChar and pChar = malloc(20))

    I get confused with the first example. Why is that?

    Zero
     
    Zero, Feb 23, 2006
    #1
    1. Advertising

  2. Zero

    Ico Guest

    Zero <> wrote:
    > Hello everybody!
    >
    > I have a question and need some kind of confirmation!
    >
    > Is it right that
    >
    >
    > pChar[2] = 'a' is the same as
    > *(pChar + 2) = 'a'!
    >
    > (where char * pChar and pChar = malloc(20))
    >
    > I get confused with the first example. Why is that?


    Pointer and array equivalance often can be confusing to those new to C.
    The comp.lang.c faq has a chapter dedicated to this subject :

    http://c-faq.com/aryptr/index.html

    Reading this might answer your question and clear up your confusion.

    --
    :wq
    ^X^Cy^K^X^C^C^C^C
     
    Ico, Feb 23, 2006
    #2
    1. Advertising

  3. "Zero" <> wrote in message
    news:...
    : Hello everybody!
    :
    : I have a question and need some kind of confirmation!
    :
    : Is it right that
    :
    : pChar[2] = 'a' is the same as
    : *(pChar + 2) = 'a'!

    yes.
    Even the following is equivalent:
    2[pChar] = 'a'

    : (where char * pChar and pChar = malloc(20))
    :
    : I get confused with the first example. Why is that?

    Why are you getting confused?
    Accessing an element at an offset from a pointer
    was seen as a frequent enough need to deserve
    a friendly notation of its own.
    Just as a->x, which is equivalent to (*a).x


    Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
     
    Ivan Vecerina, Feb 23, 2006
    #3
  4. Zero

    Zero Guest

    I get confused because I interpret pChar[2] as an address to offset, so
    I change the address not the value behind the address.
     
    Zero, Feb 23, 2006
    #4
  5. Zero

    Zero Guest

    Very good hint!
     
    Zero, Feb 23, 2006
    #5
  6. "Zero" <> wrote in message
    news:...
    > Hello everybody!
    >
    > I have a question and need some kind of confirmation!
    >
    > Is it right that
    >
    >
    > pChar[2] = 'a' is the same as
    > *(pChar + 2) = 'a'!
    >
    > (where char * pChar and pChar = malloc(20))
    >
    > I get confused with the first example. Why is that?


    Dennis Ritchie in the 1974-5 versions of "C Reference Manual" said the
    following:

    "The expression ''E1[E2]'' is identical (by definition) to ''* ( (E1) + (
    E2 ) ) ''."

    and :

    "Except for the relaxation of the requirement that E1 be of pointer type,
    the expression ''E1->MOS'' is exactly
    equivalent to ''(*E1).MOS''."


    Rod Pemberton
     
    Rod Pemberton, Feb 23, 2006
    #6
  7. Zero wrote:
    > I get confused because I interpret pChar[2] as an address to offset, so

    it's also a lookup at that address, not just an offset to an address.
    So indeed,pChar[2] is NOT the same as just (pchar + 2), but
    *(pchar +2)

    > I change the address not the value behind the address.
     
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Feb 23, 2006
    #7
  8. Zero wrote:
    >
    > I have a question and need some kind of confirmation!
    >
    > Is it right that
    >
    >
    > pChar[2] = 'a' is the same as
    > *(pChar + 2) = 'a'!
    >
    > (where char * pChar and pChar = malloc(20))


    Yes.

    > I get confused with the first example. Why is that?


    Because that's how the '[]' operator is defined in C language. Saying
    '<something>' is just another way of saying '*(<something> + i)' by
    definition.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Feb 23, 2006
    #8
  9. Zero

    Default User Guest

    Zero wrote:

    > I get confused because I interpret pChar[2] as an address to offset,
    > so I change the address not the value behind the address.


    That's ok, we get confused because you don't quote enough for context.
    See below.



    Brian
    --
    Please quote enough of the previous message for context. To do so from
    Google, click "show options" and use the Reply shown in the expanded
    header.
     
    Default User, Feb 23, 2006
    #9
  10. "Rod Pemberton" <> writes:
    [...]
    > Dennis Ritchie in the 1974-5 versions of "C Reference Manual" said the
    > following:
    >
    > "The expression ''E1[E2]'' is identical (by definition) to ''* ( (E1) + (
    > E2 ) ) ''."


    Still true.

    > and :
    >
    > "Except for the relaxation of the requirement that E1 be of pointer type,
    > the expression ''E1->MOS'' is exactly
    > equivalent to ''(*E1).MOS''."


    I'm not sure what he means by "the relaxation of the requirement that
    E1 be of pointer type"; I don't believe that clause applies in modern
    C.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Feb 23, 2006
    #10
  11. On 23 Feb 2006 02:13:56 -0800, "Zero" <> wrote:

    >I get confused because I interpret pChar[2] as an address to offset, so
    >I change the address not the value behind the address.


    Given
    int i = 1;
    int a[5] = {3,2,1};
    int *p = a;

    If you consider a[2] any different than i, you are creating
    unnecessary problems for yourself. They are each an object of type
    int.

    The standard requires that a[2] be the same as *(a+2) and you should
    have no problem with a+2 being the same as 2+a which leads to *(a+2)
    being the same as *(2+a) and from there to the very strange looking
    but perfectly legal 2[a].

    All of the above is equally true using p instead of a.


    Remove del for email
     
    Barry Schwarz, Feb 24, 2006
    #11
  12. "Keith Thompson" <> wrote in message
    news:...
    > "Rod Pemberton" <> writes:
    > [...]
    > > Dennis Ritchie in the 1974-5 versions of "C Reference Manual" said the
    > > following:
    > >
    > > "The expression ''E1[E2]'' is identical (by definition) to ''* ( (E1) +

    (
    > > E2 ) ) ''."

    >
    > Still true.
    >
    > > and :
    > >
    > > "Except for the relaxation of the requirement that E1 be of pointer

    type,
    > > the expression ''E1->MOS'' is exactly
    > > equivalent to ''(*E1).MOS''."

    >
    > I'm not sure what he means by "the relaxation of the requirement that
    > E1 be of pointer type"; I don't believe that clause applies in modern
    > C.


    I don't know either. It seemed out of place relative to everything else in
    the paragraph. So, I figured it might be referenced elsewhere in the
    document which are available on DMR's webpages.


    Rod Pemberton
     
    Rod Pemberton, Feb 24, 2006
    #12
  13. Rod Pemberton wrote:
    >> >
    >> > "Except for the relaxation of the requirement that E1 be of pointer

    > type,
    >> > the expression ''E1->MOS'' is exactly
    >> > equivalent to ''(*E1).MOS''."

    >>
    >> I'm not sure what he means by "the relaxation of the requirement that
    >> E1 be of pointer type"; I don't believe that clause applies in modern
    >> C.

    >
    > I don't know either. It seemed out of place relative to everything else in
    > the paragraph. So, I figured it might be referenced elsewhere in the
    > document which are available on DMR's webpages.


    The whole thing reads as follows:

    ****
    7.1.8 primaryexpression -> memberofstructure
    The primaryexpression is assumed to be a pointer which points to an
    object of the same form as the structure of which the memberofstructure
    is a part. The result is an lvalue appropriately offset from the origin
    of the pointed to structure whose type is that of the named structure
    member. The type of the primaryexpression need not in fact be pointer;
    it is sufficient that it be a pointer, character, or integer.

    Except for the relaxation of the requirement that E1 be of pointer type,
    the expression ‘‘E1->MOS’’ is exactly equivalent to ‘‘(*E1).MOS’’.
    ****

    In this context the last sentence makes perfect sense. What does look
    strange is the previous sentence: "it is sufficient that it
    (primaryexpression - A.T.) be a pointer, character, or integer".

    Now, if we take a look at 8.5, it says

    ****
    The same member name can appear in different structures only if the two
    members are of the same type and if their origin with respect to their
    structure is the same
    ****

    If we think a bit about what is implied by the latter quote and also
    take into account the fact that in those days C language used much less
    restrictive rules about mixing pointers and integers (for example, it
    was perfectly legal to assign an 'int' value to a pointer), it is
    probably likely that that early version of C language allowed using
    integers in address parts of '->' expressions. Integral value was
    interpreted as memory address:

    int addr;
    int res;

    addr = <whatever>;
    res = addr->fld; /* OK */

    In case of unary '*' operator, non-pointer operand values were not allowed

    ****
    7.2.1 * expression
    The unary * operator means indirection: the expression must be a
    pointer, and the result is an lvalue referring to the object to which
    the expression points. If the type of the expression is ‘pointer to...’,
    the type of the result is ‘...’.
    ****

    Probably because they would lead to syntactical ambiguities. Or some
    other reason.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Feb 24, 2006
    #13
  14. "Andrey Tarasevich" <> wrote in message
    news:...
    > Rod Pemberton wrote:
    > >> >
    > >> > "Except for the relaxation of the requirement that E1 be of pointer

    > > type,
    > >> > the expression ''E1->MOS'' is exactly
    > >> > equivalent to ''(*E1).MOS''."
    > >>
    > >> I'm not sure what he means by "the relaxation of the requirement that
    > >> E1 be of pointer type"; I don't believe that clause applies in modern
    > >> C.

    > >
    > > I don't know either. It seemed out of place relative to everything else

    in
    > > the paragraph. So, I figured it might be referenced elsewhere in the
    > > document which are available on DMR's webpages.

    >
    > The whole thing reads as follows:
    >
    > ****
    > 7.1.8 primaryexpression -> memberofstructure
    > The primaryexpression is assumed to be a pointer which points to an
    > object of the same form as the structure of which the memberofstructure
    > is a part. The result is an lvalue appropriately offset from the origin
    > of the pointed to structure whose type is that of the named structure
    > member. The type of the primaryexpression need not in fact be pointer;
    > it is sufficient that it be a pointer, character, or integer.
    >
    > Except for the relaxation of the requirement that E1 be of pointer type,
    > the expression ‘‘E1->MOS’’ is exactly equivalent to ‘‘(*E1).MOS’’.
    > ****
    >
    > In this context the last sentence makes perfect sense. What does look
    > strange is the previous sentence: "it is sufficient that it
    > (primaryexpression - A.T.) be a pointer, character, or integer".
    >
    > Now, if we take a look at 8.5, it says
    >
    > ****
    > The same member name can appear in different structures only if the two
    > members are of the same type and if their origin with respect to their
    > structure is the same
    > ****
    >
    > If we think a bit about what is implied by the latter quote and also
    > take into account the fact that in those days C language used much less
    > restrictive rules about mixing pointers and integers (for example, it
    > was perfectly legal to assign an 'int' value to a pointer), it is
    > probably likely that that early version of C language allowed using
    > integers in address parts of '->' expressions. Integral value was
    > interpreted as memory address:
    >


    I think you're correct. Although you could have compared 7.1.8
    "primary-expression->member-of-structure" and 7.2.1 "* expression". From
    rereading those sections, I'd say E1 in:

    "E1->MOS"

    can be an pointer, character, or integer according to 7.1.8. While E1 in:

    "(*E1).MOS"

    must be a pointer according to 7.2.1. Which is the reason why he mentioned
    the "relaxation."


    Rod Pemberton
     
    Rod Pemberton, Feb 24, 2006
    #14
  15. Rod Pemberton wrote:
    > ...
    > I think you're correct. Although you could have compared 7.1.8
    > "primary-expression->member-of-structure" and 7.2.1 "* expression".
    > ...


    Er... Among other things, I did compare 7.1.8 to 7.2.1 in my previous message.
    For some reason you omitted my quote of 7.2.1 and then re-quoted it yourself.
    Yes, that is indeed what is meant by "relaxation".

    The rest of my message just presented my understanding of a related issue: what
    integral values might mean on the lhs of -> operator.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Feb 25, 2006
    #15
  16. "Andrey Tarasevich" <> wrote i
    messag
    news:..
    > Rod Pemberton wrote
    >
    > "Except for the relaxation of the requirement that E1 be of pointe
    > type
    > the expression ''E1->MOS'' is exactl
    > equivalent to ''(*E1).MOS''.
    >
    > I'm not sure what he means by "the relaxation of the requiremen

    tha
    > E1 be of pointer type"; I don't believe that clause applies i

    moder
    > C
    >
    > I don't know either. It seemed out of place relative to everythin

    els
    > i
    > the paragraph. So, I figured it might be referenced elsewhere i

    th
    > document which are available on DMR's webpages
    >
    > The whole thing reads as follows
    >
    > ***
    > 7.1.8 primaryexpression -> memberofstructur
    > The primaryexpression is assumed to be a pointer which points to a
    > object of the same form as the structure of which th

    memberofstructur
    > is a part. The result is an lvalue appropriately offset from th

    origi
    > of the pointed to structure whose type is that of the name

    structur
    > member. The type of the primaryexpression need not in fact b

    pointer
    > it is sufficient that it be a pointer, character, or integer
    >
    > Except for the relaxation of the requirement that E1 be of pointe

    type
    > the expression ‘‘E1->MOS’’ is exactly equivalent t

    ‘‘(*E1).MOS’’
    > ***
    >
    > In this context the last sentence makes perfect sense. What doe

    loo
    > strange is the previous sentence: "it is sufficient that i
    > (primaryexpression - A.T.) be a pointer, character, or integer"
    >
    > Now, if we take a look at 8.5, it say
    >
    > ***
    > The same member name can appear in different structures only if th

    tw
    > members are of the same type and if their origin with respect t

    thei
    > structure is the sam
    > ***
    >
    > If we think a bit about what is implied by the latter quote and als
    > take into account the fact that in those days C language used muc

    les
    > restrictive rules about mixing pointers and integers (for example

    i
    > was perfectly legal to assign an 'int' value to a pointer), it i
    > probably likely that that early version of C language allowed usin
    > integers in address parts of '->' expressions. Integral value wa
    > interpreted as memory address
    >
    >

    I think you're correct. Although you could have compared 7.1.
    "primary-expression->member-of-structure" and 7.2.1 "* expression"
    Fro
    rereading those sections, I'd say E1 in

    "E1->MOS

    can be an pointer, character, or integer according to 7.1.8. While E
    in

    "(*E1).MOS

    must be a pointer according to 7.2.1. Which is the reason why h
    mentione
    the "relaxation.

    Rod Pemberto
     
    Rod Pemberton, Feb 25, 2006
    #16
  17. Zero

    Chris Torek Guest

    Regarding some rather old wording describing a language that is
    not compatible with C-as-it-exists-today (or even as it existed
    back in 1985 or so):

    In article <>
    Andrey Tarasevich <> wrote:
    >If we think a bit about what is implied by the latter quote and also
    >take into account the fact that in those days C language used much less
    >restrictive rules about mixing pointers and integers (for example, it
    >was perfectly legal to assign an 'int' value to a pointer), it is
    >probably likely that that early version of C language allowed using
    >integers in address parts of '->' expressions. Integral value was
    >interpreted as memory address:
    >
    > int addr;
    > int res;
    >
    > addr = <whatever>;
    > res = addr->fld; /* OK */


    This is correct. In fact, in sufficiently old C (Version 6 and
    earlier) people used to write drivers with code like this:

    0177440->csr = RESET;
    delay(10);
    0177440->csr = 0;

    This kind of construct was already disallowed by many C compilers
    in the early 1980s, and was never included in the C89 standard.

    Steve Johnson's "Portable C Compiler" had special rules for structure
    and union member access, in which you could use the "wrong" member
    names:

    struct A {
    int a_first;
    int a_second;
    double a_third;
    };
    struct B {
    long b_first;
    double b_second;
    };

    struct A somevar;

    f() {
    ...
    if (somecond)
    somevar.b_first = 0;

    Here, the compiler would complain, because b_first was not a valid
    element of the structure "struct A"; but then it would go on to
    generate code "as if" somevar had type "struct B".

    To make this compile on today's compilers, one must write something
    like:

    ((struct B *)&somevar)->b_first = 0;

    which has the same effect, i.e., does nothing useful when
    sizeof(int)==sizeof(long) because you moved your code from
    the PDP-11 to the VAX. :)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Feb 26, 2006
    #17
  18. Zero

    inno Guest

    le nom d'un tableau est un pointeur qui pointe sur le premier element
    exemple:
    int tab[10]
    est equivalent a int * tab=malloc(sizeof(10))
     
    inno, Mar 11, 2006
    #18
  19. On Saturday 11 March 2006 09:01, inno opined (in
    <>):

    > le nom d'un tableau est un pointeur qui pointe sur le premier element
    > exemple:
    > int tab[10]
    > est equivalent a int * tab=malloc(sizeof(10))


    Lingua franca in c.l.c is standard English. Other useful rules:

    - quote context
    - do not top-post
    - stay on-topic (Standard C)

    Examine and follow: <http://cfaj.freeshell.org/google/>

    Now, if my kindergarten French still serves:

    I think you're wrong. The name of the array is not the same the pointer
    to the first element (unless you use "equivalent" in a very loose,
    usage related sense). It may be useful to think of it that way, and
    compilers are allowed to treat them that way behind the scenes, but
    array is a data type in it's own right, not a shorthand for a pointer.

    Also, your example is pure rubbish! Your `malloc` actually allocates
    just sizeof(int) bytes (courtesy of the fact that undecorated integer
    constants in C have type `int`), and that will certainly not hold 10
    `int`s. What you really wanted is:

    int *tab = malloc(10 * sizeof(int));

    Again, this is *not* the same as:

    int tab[10];

    Although `tab` can later be used in same syntactic constructs in the
    same way, one important exception is:


    for `int tab[10]` sizeof(tab) == 10 * sizeof(int)
    for `int *tab` sizeof(tab) == <size of ptr to int on your system>

    --
    BR, Vladimir

    The goys have proven the following theorem...
    -- Physicist John von Neumann, at the start of a classroom
    lecture.
     
    Vladimir S. Oka, Mar 11, 2006
    #19
    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. Phil
    Replies:
    1
    Views:
    653
    llewelly
    Sep 16, 2003
  2. muser
    Replies:
    3
    Views:
    769
    Ron Natalie
    Sep 18, 2003
  3. A
    Replies:
    3
    Views:
    462
    Alan Kelon
    Oct 29, 2003
  4. Chad

    pointers to pointers question

    Chad, Mar 26, 2006, in forum: C Programming
    Replies:
    5
    Views:
    317
    Default User
    Mar 27, 2006
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    687
Loading...

Share This Page