Question on Pointers

Z

Zero

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
 
I

Ico

Zero said:
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.
 
I

Ivan Vecerina

: 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
 
Z

Zero

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

Rod Pemberton

Zero said:
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
 
?

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

Zero said:
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)
 
A

Andrey Tarasevich

Zero said:
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.
 
D

Default User

Zero said:
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
 
K

Keith Thompson

Rod Pemberton said:
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.
 
B

Barry Schwarz

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
 
R

Rod Pemberton

Keith Thompson said:
Rod Pemberton said:
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
 
A

Andrey Tarasevich

Rod said:
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.
 
R

Rod Pemberton

Andrey Tarasevich said:
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
 
A

Andrey Tarasevich

Rod said:
...
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.
 
R

Rod Pemberton

messag
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
 
C

Chris Torek

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):

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. :)
 
I

inno

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))
 
V

Vladimir S. Oka

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.
 

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,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top