473,386 Members | 1,754 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Question on Pointers

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

Feb 23 '06 #1
18 1349
Ico
Zero <ch********@web.de> 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
Feb 23 '06 #2
"Zero" <ch********@web.de> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
: 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
Feb 23 '06 #3
I get confused because I interpret pChar[2] as an address to offset, so
I change the address not the value behind the address.

Feb 23 '06 #4
Very good hint!

Feb 23 '06 #5

"Zero" <ch********@web.de> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
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
Feb 23 '06 #6
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.

Feb 23 '06 #7
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>[i]' is just another way of saying '*(<something> + i)' by
definition.

--
Best regards,
Andrey Tarasevich
Feb 23 '06 #8
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.
Feb 23 '06 #9
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> 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) ks***@mib.org <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.
Feb 23 '06 #10
On 23 Feb 2006 02:13:56 -0800, "Zero" <ch********@web.de> 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
Feb 24 '06 #11

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Rod Pemberton" <do*********@sorry.bitbucket.cmm> 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
Feb 24 '06 #12
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
Feb 24 '06 #13

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:11*************@news.supernews.com...
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

Feb 25 '06 #14
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
Feb 25 '06 #15
"Andrey Tarasevich" <an**************@hotmail.com> wrote in
message
news:11*************@news.supernews.com...
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

Feb 25 '06 #16
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 <11*************@news.supernews.com>
Andrey Tarasevich <an**************@hotmail.com> 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.
Feb 26 '06 #17
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))

Mar 11 '06 #18
On Saturday 11 March 2006 09:01, inno opined (in
<11**********************@i40g2000cwc.googlegroups .com>):
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.

Mar 11 '06 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: cppaddict | last post by:
Hi, I am deleting some objects created by new in my class destructor, and it is causing my application to error at runtime. The code below compiles ok, and also runs fine if I remove the body...
11
by: DamonChong | last post by:
Hi, I am new to c++. I recently spend an enormous among of time troubleshooting a seeminly innocuous piece of code. Although I narrow down this piece of code as the culprit but I don't...
27
by: Susan Baker | last post by:
Hi, I'm just reading about smart pointers.. I have some existing C code that I would like to provide wrapper classes for. Specifically, I would like to provide wrappers for two stucts defined...
20
by: __PPS__ | last post by:
Hello everybody in a quiz I had a question about dangling pointer: "What a dangling pointer is and the danger of using it" My answer was: "dangling pointer is a pointer that points to some...
9
by: Alfonso Morra | last post by:
Hi, I am having some probs with copying memory blocks around (part of a messaging library) and I would like some confirmation to make sure that I'm going about things the right way. I have...
9
by: Steven | last post by:
Hello, I have a question about strcmp(). I have four words, who need to be compared if it were two strings. I tried adding the comparison values like '(strcmp(w1, w2) + strcmp(w3, w4))', where...
21
by: Bo Yang | last post by:
As long as I write c++ code, I am worry about the pointer. The more the system is, the dangerous the pointer is I think. I must pass pointers erverywhere, and is there a way to ensure that every...
3
by: Filimon Roukoutakis | last post by:
Dear all, assuming that through a mechanism, for example reflexion, the Derived** is known explicitly. Would it be legal (and "moral") to do this conversion by a cast (probably reinterpret would...
21
by: Chad | last post by:
At the following url http://c-faq.com/lib/qsort2.html, they have the following Q: Now I'm trying to sort an array of structures with qsort. My comparison function takes pointers to structures,...
17
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.