doubt in USING POINTERS

T

thp

In comp.std.c (e-mail address removed) wrote:
+ In comp.std.c (e-mail address removed) wrote:
+>
+> - the value of the expression "x", which turns out to be a pointer
+> rvalue, namely the address of the first member of x.
+
+ That still isn't quite accurate -- the expression "x" is, in many cases,
+ automatically *converted* to a pointer, but it isn't itself a pointer.

Perhaps, the referent of my use of "which" was ambiguous. In any
case, I mean that the *value* of the expression "x" turns out to be a
pointer rvalue (in all but a few cases).

Tom Payne
 
V

Victor

Without worrying about what a modifiable lvalue is, it's probably
easiest to think of an array variable as a constant pointer.

Refer to the code below:

#include <stdlib.h>

int main( ) {

/* the compiler figures out how many array elements there are */
int x[ ] = { 8, 6, 7, 5, 3, 0, 9 };
/* allocate a block of 7 consecutive integers and assign this
address
* to the const pointer named xx
*/
int * const xx = ( int * ) malloc( 7 * sizeof( int ) );
const int *xp;
int i;

/* sizeof( ) will tell you how many bytes of storage, then divide
by the
size of each array element (an int typically is 4 bytes) to
determine
the number of array elements */
for ( i = 0; i < sizeof( x ) / sizeof( x[ 0 ] ); i++ )
/* perfectly legal, though it looks confusing... */
xx[ i ] = * ( x + i ) * -2;

/* assignment to a pointer to a constant int; contrast with this
xx, which
* is a constant pointer to an int.
*/
xp = x;
printf( "The 2nd element of array x is %d\n", * ( xp + 1 ) );
printf( "The 2nd element of array x is also this %d\n", xp[1] );
/* just showing off here a little bit... */
for ( i = 0; i < sizeof( x ) / sizeof( * ( x + 0 ) ); i++,xp++ )
printf( "x[ %d ] = %d\n", i, *xp );


/* note the different values returned by sizeof */
printf( "The size of x is %d, the size of xx is %d\n",
sizeof( x ), sizeof( xx ) );

for ( i = 0; i < sizeof( x ) / sizeof( int ); i++ )
printf( "element %d x: %d xx: %d\n", i, x[ i ], xx[ i ] );

/* I almost forgot this; you don't want to use dynamic memory
unless you
* truly have to, or like to give yourself fits with memory leaks.
*/
free ( xx );
return ( 0 );
}


The important things to note are that you can refer to array elements
as offsets from a pointer or using array brackets. Similarly, you can
also use the array brackets with a pointer. This suggests a close
correlation between pointers and array names. Note that you can store
the address of array, but you can not assign a value to an array name.
This is just like the constant pointer xx that I used above.

Using a pointer to a const int is a safe way to step through an array.
The compiler will warn you if you inadvertently attempt to modify
*xp. I hope this isn't more information than you wanted.

Best of luck,
Victor

Hello,
Am not very good with pointers in C,but I have a small doubt about
the way these pointers work..
We all know that in an array say x[5],x is gonna point to the first
element in that array(i.e)it will have the address of the first
element.In the the program below am not able to increment the value
stored in x,which is the address of the first element.Why am I not
able to do that?Afterall 1 is also a hexadecimal number then why
does adding 1 to x show me a error?
I got the message "Lvalue Required" when I complied the program.Even
if I declared x[5] as long int the same error continued.Can
someone please help me solve it out??
Thanks to all those who are gonna help me in this..
--ambika

#include<stdio.h>
void main()
{
int x[5]={1,2,3,4,5};
printf("\naddr in x:%p",x);
printf("\nnumber in the addr stored in x is:%d",*x);
x=x+1;
printf("\naddr in x after incrementation is:%p",x);
printf("\nnumber in the addr stored in x is:%d",*x);
}
 
R

Richard Heathfield

Irrwahn said:
For non-experts like me, in what contexts an array is not an lvalue?

None. Jack is quite correct.

An array is not a /modifiable/ lvalue, but it /is/ an lvalue.
 
R

Richard Heathfield

Victor said:
Without worrying about what a modifiable lvalue is, it's probably
easiest to think of an array variable as a constant pointer.

int array[32];
const int *constptr = array;

printf("size of array is %lu bytes.\n", (unsigned long)sizeof array);
printf("size of pointer is %lu bytes.\n", (unsigned long)sizeof constptr);

The important things to note are that you can refer to array elements
as offsets from a pointer or using array brackets. Similarly, you can
also use the array brackets with a pointer. This suggests a close
correlation between pointers and array names.

This is true, because the Standard guarantees that *(a + i) and a are
synonymous.
 
I

Irrwahn Grausewitz

Richard Heathfield said:
None. Jack is quite correct.

An array is not a /modifiable/ lvalue, but it /is/ an lvalue.

Before confusion overwhelms me, let's see if I got it right:

1. In C99 arrays are lvalues, though not modifiable lvalues
(as stated in ISO/IEC 9899:1999 6.3.2.1#1).

2. There is no context that changes arrays from being (non-modifiable)
lvalues whatsoever.

3. Prior to C89 arrays weren't lvalues at all.

Right?

Regards

Irrwahn
 
J

Jack Klein

Before confusion overwhelms me, let's see if I got it right:

1. In C99 arrays are lvalues, though not modifiable lvalues
(as stated in ISO/IEC 9899:1999 6.3.2.1#1).

2. There is no context that changes arrays from being (non-modifiable)
lvalues whatsoever.

3. Prior to C89 arrays weren't lvalues at all.

Right?

Regards

Irrwahn

No, you are incorrect. It was the original 1989 ANSI standard that
made lvalues arrays and introduced the concept that some lvalues were
non-modifiable. That had to be so because the 1989 ANSI standard also
introduced the const qualifier to the language, and any object defined
as const was certainly an lvalue, but certainly not modifiable.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
K

Keith Thompson

Without worrying about what a modifiable lvalue is, it's probably
easiest to think of an array variable as a constant pointer.

It's easiest (or at least most correct) to think of an array variable
as an array variable.

The name of an array variable, in most contexts, is *converted* to a
pointer to its first element.
 
G

Gabriel Dos Reis

| Irrwahn Grausewitz wrote:
| >>| No, arrays are lvalues.
| >>Not always.
| > For non-experts like me, in what contexts an array is not an lvalue?
|
| None.

Consider

struct Point {
int coord[2];
};

extern make_point(int, int);

The expression

make_point(34, 2).coord

is a non-lvalue array.

-- Gaby
 
P

pete

Gabriel said:
| Irrwahn Grausewitz wrote:
| >>| No, arrays are lvalues.
| >>Not always.
| > For non-experts like me, in what contexts an array is not an lvalue?
|
| None.

Consider

struct Point {
int coord[2];
};

extern make_point(int, int);

The expression

make_point(34, 2).coord

is a non-lvalue array.

Assuming that make_point returns the appropriate type structure,
what's nonlvalue about make_point(34, 2).coord ?
It designates an object, doesn't it.
 
I

Irrwahn Grausewitz

Jack Klein said:
No, you are incorrect. It was the original 1989 ANSI standard that
made lvalues arrays and introduced the concept that some lvalues were
non-modifiable. That had to be so because the 1989 ANSI standard also
introduced the const qualifier to the language, and any object defined
as const was certainly an lvalue, but certainly not modifiable.

And how does this contradict any of my above statements?!?
Ah, I see, for the sake of absolute correctness I should have written:

1. In C89 and C99 arrays are lvalues ...
=======

Irrwahn
 
T

thp

+ Gabriel Dos Reis wrote:
+>
+>
+> | Irrwahn Grausewitz wrote:
+> | >>| No, arrays are lvalues.
+> | >>Not always.
+> | > For non-experts like me, in what contexts an array is not an lvalue?
+> |
+> | None.
+>
+> Consider
+>
+> struct Point {
+> int coord[2];
+> };
+>
+> extern make_point(int, int);
+>
+> The expression
+>
+> make_point(34, 2).coord
+>
+> is a non-lvalue array.
+
+ Assuming that make_point returns the appropriate type structure,
+ what's nonlvalue about make_point(34, 2).coord ?
+ It designates an object, doesn't it.

Since functions return structs by value, make_point(34,2) is not an
lvalue -- e.g., taking its address is a syntax error. So
make_point(34,2).coord is an array member of an rvalue, simply a
pointer rvalue pointing to make_point(34,2).coord[0]. However,
make_point(34,2).coord[0] is an lvalue.

Intricate stuff!

Tom Payne
 
G

Gabriel Dos Reis

| Gabriel Dos Reis wrote:
| >
| >
| > | Irrwahn Grausewitz wrote:
| > | >>| No, arrays are lvalues.
| > | >>Not always.
| > | > For non-experts like me, in what contexts an array is not an lvalue?
| > |
| > | None.
| >
| > Consider
| >
| > struct Point {
| > int coord[2];
| > };
| >
| > extern make_point(int, int);
^

oops, missing "struct Point"

| >
| > The expression
| >
| > make_point(34, 2).coord
| >
| > is a non-lvalue array.
|
| Assuming that make_point returns the appropriate type structure,
| what's nonlvalue about make_point(34, 2).coord ?

6.5.2.3

[#3] A postfix expression followed by the . operator and an
identifier designates a member of a structure or union
object. The value is that of the named member, and is an
lvalue if the first expression is an lvalue. If the first
expression has qualified type, the result has the so-
qualified version of the type of the designated member.

-- Gaby
 
S

Sona

Keith said:
It's easiest (or at least most correct) to think of an array variable
as an array variable.

The name of an array variable, in most contexts, is *converted* to a
pointer to its first element.

So in other words, if we're passing arrays to functions, we should
always do:

callSomeFunc(&someArray[0]);

Right? At least to make sure the code is portable? Thanks


Sona
 
C

Chris Dollin

Sona said:
Keith said:
It's easiest (or at least most correct) to think of an array variable
as an array variable.

The name of an array variable, in most contexts, is *converted* to a
pointer to its first element.

So in other words, if we're passing arrays to functions, we should
always do:

callSomeFunc(&someArray[0]);

Right?
No.

At least to make sure the code is portable? Thanks

No.

It's not necessary; arguments to functions are one of the places where
array names do decay into pointers to their first element.

[The two places where they don't are as operands to sizeof and monadic
&. The third place is for string literals used as initialisers for
string arrays.]
 
T

thp

[...]
+ Before confusion overwhelms me, let's see if I got it right:
[...]
+ 2. There is no context that changes arrays from being (non-modifiable)
+ lvalues whatsoever.

Arrays are arrays, and lvalues are expressions. Some but not all
array expressions are lvalues. Per C99 6.3.2.1:

Except when it is the operand of the sizeof operator or the
unary & operator, or is a string literal used to intialize
an array, an expression that has type "array of <type>" is
converted to an expression with type "pointer to <type>"
that points to the initial element of the array object and
is not an lvalue.

Also, Gabriel Dos Reis has posted an example of a non-lvalue array
expression that is not the result of such conversion.

Tom Payne
 
I

Irrwahn Grausewitz

Sona said:
Keith said:
It's easiest (or at least most correct) to think of an array variable
as an array variable.

The name of an array variable, in most contexts, is *converted* to a
pointer to its first element.

So in other words, if we're passing arrays to functions, we should
always do:

callSomeFunc(&someArray[0]);

Which is indeed eqivalent to:

callSomeFunc( someArray );

To readers of c.lang.c and c.std.c this is aka Chris Torek's "The Rule":

<quote C.T.>

In any value context, an object of type 'array of T' is converted
to a value of type 'pointer to T', pointing to the first element
of that array, i.e., the one with subscript 0.

</quote C.T.>

Regards

Irrwahn
 
K

Keith Thompson

Sona said:
Keith said:
It's easiest (or at least most correct) to think of an array variable
as an array variable.
The name of an array variable, in most contexts, is *converted* to a
pointer to its first element.

So in other words, if we're passing arrays to functions, we should
always do:

callSomeFunc(&someArray[0]);

Right? At least to make sure the code is portable? Thanks

No.
 
R

Richard Heathfield

[Much snippage]
Gabriel Dos Reis wrote:
IG: For non-experts like me, in what contexts an array is not an lvalue?
RJH: None.
GDR: Consider
GDR:
GDR: struct Point {
GDR: int coord[2];
GDR: };
GDR:
GDR: extern struct Point make_point(int, int);
GDR: 6.5.2.3

White flag. Thanks for pointing that out, and apologies to IG (et al) for
posting an incorrect answer to his question.
 
M

Micah Cowan

Irrwahn Grausewitz said:
And how does this contradict any of my above statements?!?
Ah, I see, for the sake of absolute correctness I should have written:

1. In C89 and C99 arrays are lvalues ...
=======

1. and 2. As has already been pointed out, arrays are not always
lvalues, in C89 nor in C99. The context provided was as a member of a
non-lvalue struct (e.g., returned from a function).

-Micah
 
M

Micah Cowan

[...]
+ Before confusion overwhelms me, let's see if I got it right:
[...]
+ 2. There is no context that changes arrays from being (non-modifiable)
+ lvalues whatsoever.

Arrays are arrays, and lvalues are expressions. Some but not all
array expressions are lvalues. Per C99 6.3.2.1:

Except when it is the operand of the sizeof operator or the
unary & operator, or is a string literal used to intialize
an array, an expression that has type "array of <type>" is
converted to an expression with type "pointer to <type>"
that points to the initial element of the array object and
is not an lvalue.

Also, Gabriel Dos Reis has posted an example of a non-lvalue array
expression that is not the result of such conversion.

To others: note that the quote above has implications regarding
non-lvalue arrays when applied to an array-of-arrays type.

-Micah
 

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

Similar Threads


Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,223
Latest member
Jurgen2087

Latest Threads

Top