472,955 Members | 2,610 Online

# double pointer

Hi, if I have:

int a=100, b = 200, c = 300;

int *a[] = {&a, &b, &c};

than say that:

int **b is equal to int *a[] is correct????

thus a double pointer is the same of an array of pointers ???

Thanks

Sep 26 '06 #1
42 5141
xdevel wrote:
Hi, if I have:

int a=100, b = 200, c = 300;

int *a[] = {&a, &b, &c};
I don't think this will compile, you've defined "a" twice. Post a
complete
example and compile it before you post.
than say that:

int **b is equal to int *a[] is correct????
now you've redfined "b".
thus a double pointer is the same of an array of pointers ???
no. But I don't understand what you are trying to do. Post real code.
--
Nick Keighley

Sep 26 '06 #2
xdevel said:
Hi, if I have:

int a=100, b = 200, c = 300;

int *a[] = {&a, &b, &c};
Name conflict.
than say that:

int **b is equal to int *a[] is correct????
No. int **b conflicts with int b = 200.

And no, int ** is not the same type as int [3].
thus a double pointer is the same of an array of pointers ???
No, a double pointer is a pointer to a double:

double d = 3.14;
double *p = &d;

int ** is a pointer to a pointer to an int. So the thing that it points to
(if it is pointing anywhere sensible) is a pointer to int.

int i = 42; /* int */
int *p = &i; /* p points to i */
int **pp = &p; /* pp points to p */
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 26 '06 #3
"xdevel" <xd********@yahoo.comwrites:
Hi, if I have:

int a=100, b = 200, c = 300;

int *a[] = {&a, &b, &c};

than say that:

int **b is equal to int *a[] is correct????

thus a double pointer is the same of an array of pointers ???
No. Arrays are not pointers. Pointers are not arrays.

The comp.lang.c FAQ is at <http://www.c-faq.com/>. Read section 6,
"Arrays and Pointers".

--
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.
Sep 26 '06 #4

xdevel wrote:
Hi, if I have:

int a=100, b = 200, c = 300;

int *a[] = {&a, &b, &c};
Redefinition of a.
than say that:

int **b is equal to int *a[] is correct????
Redefinition of b.
thus a double pointer is the same of an array of pointers ???
No. You can occasionally treat a doubly-indirect pointer as though it
were an array of pointers thanks to the semantics of the subscript
operator, but it is not the same thing.

In most contexts, a value of an array type (such as foo) will
implicitly be converted to a pointer to the base type (in this case, a
pointer to int*, or int**), and its value will be the address of the
first item in the array.

This conversion is handy, since the definition of the subscript
operation a[i] is *(a + i); that is, the offset is added to the
pointer, and the result is dereferenced.

Assume the following:

int a, b, c;
int *foo[] = {&a, &b, &c};
int **bar;

then you can write

bar = foo;

and use subscript notation on bar *as though* it were an array:

bar[0] == foo[0] == &a
*bar[0] == *foo[0] == a;

However, bar and foo are two different types. Remember that I said "in
most contexts" an array value is converted to a pointer value. There
are several exceptions to this, two of which are when the array is an
operand to either the sizeof or address-of (&) operators. Applying the
sizeof operator to each will give different results:

sizeof foo == sizeof(int) * 3
sizeof bar == sizeof(int**)

And the result of the address-of operator will be different types:

type of &foo == int *(*)[3] (pointer to 3-element array of pointers
to int)
type of &bar == int *** (pointer to pointer to pointer to int)

Sep 26 '06 #5
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???

so if I write:
int d_pointer ** = arr_to_point;
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));

it compile perfectly and the output is the values of a,b and c variable
pointed
by the pointers in d_pointer.

Sep 27 '06 #6
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???

so if I write:
int d_pointer ** = arr_to_point;
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));

it compile perfectly and the output is the values of a,b and c variable
pointed
by the pointers in d_pointer.

Sep 27 '06 #7
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???

so if I write:
int d_pointer ** = arr_to_point;
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));

it compile perfectly and the output is the values of a,b and c variable
pointed
by the pointers in d_pointer.

Sep 27 '06 #8
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???

so if I write:
int d_pointer ** = arr_to_point;
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));

it compile perfectly and the output is the values of a,b and c variable
pointed
by the pointers in d_pointer.

Sep 27 '06 #9
xdevel said:
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???
No. There's no such thing as a "double pointers to int". There is, however,
such a thing as "pointer to pointer to int", and such things point at,
would you believe, pointers to int.
>
so if I write:
int d_pointer ** = arr_to_point;
int ** d_pointer = arr_to_point;

Equivalently: int ** d_pointer = &arr_to_point[0];

This is legal, because the arr_to_point array is an array of int *, so
arr_to_point[0] is an int *, so &arr_to_point[0] is an int **.
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));
d_pointer is an int **, which points at &arr_pointer[0], so d_pointer + n is
an int ** which points at &arr_pointer[n], so **(d_pointer + n) is an int,
and is the int pointed to by the nth member of the arr_to_point array.

So yes, that's all fine. But I get the uneasy feeling that you will deduce
from this that arrays and pointers are the same thing, which they most
certainly are not.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #10

xdevel wrote:
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???

so if I write:
int d_pointer ** = arr_to_point;
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));

it compile perfectly and the output is the values of a,b and c variable
pointed
by the pointers in d_pointer.
why don't you try reading the responses you are getting? A pointer and
an array
are not the same thing. Read the FAQ if you are confused.
--
Nick Keighley

Sep 27 '06 #11
xdevel wrote:
Sorry I wrote the code incorrectly:

thus I've three int:
int a=100, b = 200, c = 300;

and an array of pointers to int
int *arr_to_point[] = {&a, &b, &c};

and than my question was:
an array of pointers to int is the same thing of a double pointers to
int ???

so if I write:
int d_pointer ** = arr_to_point;
That's because the name of an array yields a pointer to its first
element (except in a few cases, notably when it's the operand
of & or sizeof). That doesn't mean they are the same.

int **d_pointer = arr_to_point;
is the same as
int **d_pointer = &arr_to_point[0];
That's a property of arrays in C.

In the above case, arr_to_point holds 3 pointers, to a,b,c
while a,b,c holds the int values and d_pointer

int **d_pointer can just store one pointer, which in this case points at
the start of arr_to_point. It cannot store more than that one pointer -
but you can point it at something that does - e.g. an array.

And by the way dereferencing and pointers works in C you can address
those elements it points to as you would with an actual array.
int n=0;
for(; n < 3; n++)
printf("%d ", **(d_pointer +n));

it compile perfectly and the output is the values of a,b and c variable
pointed
by the pointers in d_pointer.
Sep 27 '06 #12
Richard Heathfield ha scritto:
So yes, that's all fine. But I get the uneasy feeling that you will deduce
from this that arrays and pointers are the same thing, which they most
certainly are not.

so we can, generally, say that array and pointers are interchangeable
for members
accessing (or by pointer indexing or by array subscripting) but
the array is not the same of a pointer because if I write
int a[] = {1,2};
than it is like a:
int *const a;

that is a constant pointer to an int

Sep 27 '06 #13
xdevel said:
Richard Heathfield ha scritto:
>So yes, that's all fine. But I get the uneasy feeling that you will
deduce from this that arrays and pointers are the same thing, which they
most certainly are not.

so we can, generally, say that array and pointers are interchangeable
for members
accessing (or by pointer indexing or by array subscripting)
In a value context, A[N] and *(A + N) are synonymous. So A can be either an
array name or a pointer to the first element of that array.
but
the array is not the same of a pointer because if I write
int a[] = {1,2};
than it is like a:
int *const a;

that is a constant pointer to an int
No, it's more like: int a[] = {1,2};

In that example, a has type int[2], not int *const

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #14
Ok I'll do that ...
but sometimes is most interesting to interact with humans.......

however I thank you for the help

Bye

Sep 27 '06 #15
Nick Keighley said:
why don't you try reading the responses you are getting?
xdevel said:
Ok I'll do that ...
but sometimes is most interesting to interact with humans.......
Interacting with humans on Usenet involves reading as well as writing.
Several people have given you excellent responses. I suggest you read them.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #16
Ok I read all the responses but I am not agree
with the 'sentence' array are not pointers:

on some books like:
C++ How To Program (Deitel)
C++ The Complete Reference (Shildt)
C++ Primer (Lippman)
and Stroustrupp an K&R

is cited that:

the array is a pointer (constant on the Deitel book...) to is first
elements ....
so I understand that the array name is a type of a costant pointer of
its first element
Bye

Sep 27 '06 #17
xdevel wrote:
Ok I read all the responses but I am not agree
with the 'sentence' array are not pointers:

on some books like:
C++ How To Program (Deitel)
C++ The Complete Reference (Shildt)
C++ Primer (Lippman)
and Stroustrupp an K&R

is cited that:

the array is a pointer (constant on the Deitel book...) to is first
elements ....
so I understand that the array name is a type of a costant pointer of
its first element
In certain situation, yes.
It may make sense if you seperate the notion of an array from
the name of that array. There's the array - storage with a
given type, and to reach that storage you use its name.

That name however, is a pointer to the first element in the
array in some situations. It is not a pointer to its first
element if you apply sizeof or unary & to it.
Sep 27 '06 #18
xdevel said:
Ok I read all the responses but I am not agree
with the 'sentence' array are not pointers:
It isn't your decision. Nor is it up to me, Deitel 1, Deitel 2, Schildt,
Lippman, bs, bwk, or dmr.
>
on some books like:
C++ How To Program (Deitel)
"Arrays and pointers are intimately related in C++ and may be used /almost/
interchangeably. An array can be thought of as a constant pointer."

This is true, but note that "can be thought of as" does not mean the same as
"is". Note further that C++ is not C. Deitel and Deitel are not claiming
that arrays are pointers, or that pointers are arrays, in C++.

Still, in "C: How To Program" (5th edition), the wording is almost
identical:

"Arrays and pointers are intimately related in C and often may be used
interchangeably. An array name can be thought of as a constant pointer."

Again, note that "can be thought of as" does not mean the same as "is".
Deitel and Deitel are not claiming that arrays are pointers, or that
pointers are arrays, in C.

C++ The Complete Reference (Shildt)
You'd think Schildt wouldn't know the difference between arrays and
functions, let alone arrays and pointers. But in fact even he realises they
are different. I don't have "C++ - The Complete Reference", but I *do* have
a copy of "C - The Complete Reference", which a well-meaning friend spotted
on the remainder pile in a bookshop, and bought in the hope that I would
find it useful. And, in a way, he was right! Anyway, Schildt has this to
say:

"In C, arrays and pointers are closely related; a discussion of one usually
refers to the other. This chapter focuses on arrays while Chapter 5 looks
closely at pointers. You should read both to understand fully these
important C constructs."

written by Herbert Schildt, let alone two), it is nevertheless clear from
the above that he realises arrays and pointers are sufficiently different
that each deserves its own chapter.

Schildt is not claiming that arrays are pointers, or that pointers are
arrays, in C.
C++ Primer (Lippman)
I don't have that, so I can't check it.
and Stroustrupp
Stroustrup says: "In C++, pointers and arrays are closely related. The name
of an array can be used as a pointer to its initial element." This is true,
but note that "can be used as" does not mean the same as "is". Note further
that C++ is not C. Stroustrup is not claiming that arrays are pointers, or
that pointers are arrays, either in C++ or in C.

an K&R
"In C, there is a strong relationship between pointers and arrays, strong
enough that pointers and arrays should be discussed simultaneously."
Kernighan is not claiming that arrays are pointers, or that pointers are
arrays, in C.

But even if any of them /did/ claim that arrays are pointers, it wouldn't
make it true. What matters is what the language definition says. If you can
find proof that the ISO C Standard says arrays are pointers, feel free to
post it. But I'm not holding my breath.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #19
Ok so we can think that the array name is a constant address of memory
(in
a pointer is a name of a 'pure variable' (in the data segment) in
which we can change its address

and for this raison can we say that "can be thought of as" is not the
same of "is" ?

Sep 27 '06 #20
xdevel said:
Ok so we can think that the array name is a constant address of memory
(in
the code segment)
No, there is no reason to think that an array name is an address, constant
or otherwise. An array name is the name of an array. C does not require the
implementation to provide or cater for a "code segment". Do not confuse the
language with the implementation.
a pointer is a name of a 'pure variable'
No. For example, (void *)0 is a pointer, but it is not the name of a
variable, pure or otherwise.
(in the data segment)
C does not require the implementation to provide or cater for a "data
segment" either.
in which we can change its address
No, you can't change the address of a pointer. You can, however, point a
pointer to some other place than the place to which it currently points.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #21
.... interesting to see this warning compiler message:

in the code:

int a[3] = {10,100,1000};
printf("%d\n", a);

in the console:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"c_test.d"
-MT"c_test.d" -o"c_test.o" "../c_test.c"
.../c_test.c: In function 'main':
.../c_test.c:8: warning: format '%d' expects type 'int', but
argument 2 has type 'int *'
Finished building: ../c_test.c

so also for the GCC compiler a is 'like' an int * or the compiler
automatically translate
that array to an int * ????????

Sep 27 '06 #22
xdevel wrote:

For heaven's sake, put some /context/ in your posts!
Ok so we can think that the array name is a constant address of memory
(in the code segment)
Er ... no. (a) There's no "code segment" in C. (b) If there were, it would
be where the code was. Arrays are data. Some arrays a function-local and
their addresses are different on different calls.
and instead a pointer is a name of a 'pure variable' (in the data segment)
There's no "data segment" in C either. A pointer is a value that refers to
some object (or it's a function pointer that refers to some function).
in which we can change its address
You can't change the address /of/ a pointer. You can change the /content/
of a pointer variable [if it's non-const] to make it point elsewhere.
and for this raison can we say that "can be thought of as" is not the
same of "is" ?
Arrays (of elements of type T) are not pointers (to object of type T)
because they behave differently. Consider

enum { size = /* eg */ 7 };
int ai[size];
int *ap = &ai[0];

`sizeof(ai)` = `sizeof(int) * size`. `sizeof(ap)` is some value independant
of `size`.

`&ap` has type `pointer to (pointer to int)`. `&ai` has type `pointer to
(array [size] of int)`.

`ap + 1` (ie `&ai[0] + 1`) points to the second element of `ai`. But
`&ai + 1` points to the next int[7] after `ai` (there isn't one, so
don't try and dereference it).

--
Chris "falling further in" Dollin
RIP John M. Ford (April 10, 1957 -- September 24, 2006)

Sep 27 '06 #23
xdevel wrote:
... interesting to see this warning compiler message:

in the code:

int a[3] = {10,100,1000};
printf("%d\n", a);

in the console:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"c_test.d"
-MT"c_test.d" -o"c_test.o" "../c_test.c"
../c_test.c: In function 'main':
../c_test.c:8: warning: format '%d' expects type 'int', but
argument 2 has type 'int *'
Finished building: ../c_test.c

so also for the GCC compiler a is 'like' an int * or the compiler
automatically translate
that array to an int * ????????
When an array name appears in value context, then it evaluates as
the address of the array's first element. That's the "can be thought
of as" bit.

--
Chris "falling further in" Dollin
RIP John M. Ford (April 10, 1957 -- September 24, 2006)

Sep 27 '06 #24
Richard Heathfield ha scritto:
No, there is no reason to think that an array name is an address, constant
or otherwise. An array name is the name of an array. C does not require the
implementation to provide or cater for a "code segment". Do not confuse the
language with the implementation.
excuse me but for you, than, what an array name is ? is it an object
put in a
memory space or not ?
No. For example, (void *)0 is a pointer, but it is not the name of a
variable, pure or otherwise.
yes I know but it is a special pointer used to assign a NULL value to a
pointer
No, you can't change the address of a pointer. You can, however, point a
pointer to some other place than the place to which it currently points.
sorry I wrtite it bad in fact I wanted to say that the address pointed
by the pointer can be changed

Sep 27 '06 #25
xdevel said:
... interesting to see this warning compiler message:

in the code:

int a[3] = {10,100,1000};
printf("%d\n", a);

in the console:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"c_test.d"
-MT"c_test.d" -o"c_test.o" "../c_test.c"
../c_test.c: In function 'main':
../c_test.c:8: warning: format '%d' expects type 'int', but
argument 2 has type 'int *'
Finished building: ../c_test.c

so also for the GCC compiler a is 'like' an int * or the compiler
automatically translate
that array to an int * ????????

The C Standard says clearly that A[i] and *(A + I) mean the same thing.

But we only say A[i] (or indeed *(A + I)) where a value is required. What
follows only applies where the given expression is being evaluated.

In a value context, A[i] means the same as *(A + I)

In a value context, &A[i] means the same as &*(A + I)

& and * cancel out:

In a value context, &A[i] means the same as (A + I)

set I to 0

In a value context, &A[0] means the same as (A + 0)

In a value context, &A[0] means the same as A

So - when you give the name of an array in a context where a value is
expected, what you actually get is a pointer to the first element of the
array.

This does not mean arrays are pointers. They aren't. If they were, then the
following code would print "arrays might be pointers" on any conforming
compiler. But it doesn't.

#include <stdio.h>

int main(void)
{
int arr[sizeof(int *) * 2] = {0};
int *p = arr;

if(sizeof p == sizeof arr)
{
puts("arrays might be pointers");
}
else
{
puts("arrays can't be pointers, because they have a different size");
}
return 0;
}

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #26
xdevel said:
Richard Heathfield ha scritto:
>No, there is no reason to think that an array name is an address,
constant or otherwise. An array name is the name of an array. C does not
require the implementation to provide or cater for a "code segment". Do
not confuse the language with the implementation.

excuse me but for you, than, what an array name is ?
It's the name given to an array object.
is it an object put in a memory space or not ?
No, it's the name given to an object.
>
>No. For example, (void *)0 is a pointer, but it is not the name of a
variable, pure or otherwise.

yes I know but it is a special pointer used to assign a NULL value to a
pointer
It remains a counter-example to your claim that "a pointer is a name". I can
give you lots of other counter-examples to that claim, too.
>No, you can't change the address of a pointer. You can, however, point a
pointer to some other place than the place to which it currently points.

sorry I wrtite it bad in fact I wanted to say that the address pointed
by the pointer can be changed
To clarify the terminology:

if p holds as its value the address of the object (or function, if p is a
function pointer) named foo, then p is said to point to foo.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #27
Richard Heathfield ha scritto:
This does not mean arrays are pointers. They aren't. If they were, then the
following code would print "arrays might be pointers" on any conforming
compiler. But it doesn't.

#include <stdio.h>

int main(void)
{
int arr[sizeof(int *) * 2] = {0};
int *p = arr;

if(sizeof p == sizeof arr)
{
puts("arrays might be pointers");
}
else
{
puts("arrays can't be pointers, because they have a different size");
}
return 0;
}
yes the output is in the else clause but because arr is in a object
containing
(on a machine with int of 4 bytes) 8 int of 4 bytes (sizeof is 32)
while sizeof p is only 4 becuse of size of int.
I thank you for the patience for the answers but don't seems that array
is not a pointers (nor an address of memory) because of different sizes

Sep 27 '06 #28
xdevel wrote:
I thank you for the patience for the answers but don't seems that array
is not a pointers (nor an address of memory) because of different sizes
If X has size K, and Y has size 2K, then X and Y are not the same thing.

(K isn't zero, because this is C.)

--
Chris "ooh, a millenial posting!" Dollin
RIP John M. Ford (April 10, 1957 -- September 24, 2006)

Sep 27 '06 #29
xdevel said:
Richard Heathfield ha scritto:
>This does not mean arrays are pointers. They aren't. If they were, then
the following code would print "arrays might be pointers" on any
conforming compiler. But it doesn't.

#include <stdio.h>

int main(void)
{
int arr[sizeof(int *) * 2] = {0};
int *p = arr;

if(sizeof p == sizeof arr)
{
puts("arrays might be pointers");
}
else
{
puts("arrays can't be pointers, because they have a different size");
}
return 0;
}
yes the output is in the else clause but because arr is in a object
containing
(on a machine with int of 4 bytes) 8 int of 4 bytes (sizeof is 32)
while sizeof p is only 4 becuse of size of int.
I thank you for the patience for the answers but don't seems that array
is not a pointers (nor an address of memory) because of different sizes
I've shown that Stroustrup, Kernighan, Deitel, and even Schildt agree that
arrays are not pointers, despite having something in common with them.

I've shown that an object of type "array of ints" has a different size to an
object of type "pointer to int", and therefore they *have to be* different
types, because any two things that are the same type will have the same
size.

What I haven't yet done, however, is shown you the language definition's
explanations of the two terms. So let's do that now:

3.1.2.5 Types

[...]

* An array type describes a contiguously allocated set of objects
with a particular member object type, called the element type .Array
types are characterized by their element type and by the number of
members of the array. An array type is said to be derived from its
element type, and if its element type is T , the array type is
sometimes called ``array of T .'' The construction of an array type
from an element type is called ``array type derivation.''

[...]

* A pointer type may be derived from a function type, an object type,
or an incomplete type, called the referenced type. A pointer type
describes an object whose value provides a reference to an entity of
the referenced type. A pointer type derived from the referenced type
T is sometimes called ``pointer to T .'' The construction of a pointer
type from a referenced type is called ``pointer type derivation.''

I've done all I can now to educate you. It is not my job to convince you. It
is your job to convince yourself.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #30

xdevel wrote:
... interesting to see this warning compiler message:

in the code:

int a[3] = {10,100,1000};
printf("%d\n", a);

in the console:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"c_test.d"
-MT"c_test.d" -o"c_test.o" "../c_test.c"
../c_test.c: In function 'main':
../c_test.c:8: warning: format '%d' expects type 'int', but
argument 2 has type 'int *'
Finished building: ../c_test.c

so also for the GCC compiler a is 'like' an int * or the compiler
automatically translate
that array to an int * ????????
The object "a" is a 3-element array of int, and that never changes.
However, when the array name appears in an expression *other than a
sizeof or address-of (&) expression* the compiler treats it *as if* it
were a pointer.

So looking at your printf() statement, the compiler saw the array
identifier, determined that it was not part of a sizeof or address-of
expression, and treated it as an int*, hence the diagnostic. To make
the diagnostic go away, you either dereference a directly:

printf ("%d\n", *a);

or use the subscript operator

printf("%d\n", a[0]);

To sum up:

In certain cases, you can treat an array *as though* it were a pointer,
and you can treat a pointer *as though* it were an array, but it's
technically incorrect to say that one "is the same thing" as the other.

Sep 27 '06 #31
Richard Heathfield ha scritto:
I've done all I can now to educate you. It is not my job to convince you. It
is your job to convince yourself.
Ok you has been very kind to follow my posts and I'll try to convince
myself.

Bye

Sep 27 '06 #32
John Bode ha scritto:
>
In certain cases, you can treat an array *as though* it were a pointer,
and you can treat a pointer *as though* it were an array, but it's
technically incorrect to say that one "is the same thing" as the other.
Ok I accept this conclusion.

Sep 27 '06 #33
>
in the code:

int a[3] = {10,100,1000};
printf("%d\n", a);
In this context 'a' is converted to an 'int *'.
But try the following:
#include <stdio.h>
int main(void) {
int a[3] = {10, 100, 1000};
int *b = a;
printf("%ld %ld\n", (long) sizeof a, (long) sizeof b);
}
and try to find the reason for the difference. (It has already
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Sep 27 '06 #34
Dik T. Winter ha scritto:
and try to find the reason for the difference. (It has already
Ok pointers and arrays are not the same type because the output
demonstrates that they
are objects of different sizes!
The pointer is an object that point to a first element of the array
passed and we can

Sep 27 '06 #35
xdevel said:
Dik T. Winter ha scritto:
>and try to find the reason for the difference. (It has already

Ok pointers and arrays are not the same type because the output
demonstrates that they
are objects of different sizes!
....as I pointed out earlier, yes.
The pointer is an object that point to a first element of the array
passed
You can't "pass" an array (except as a member of an enclosing aggregate
object, either a struct or a union). A pointer is a /value/, and pointer
objects can hold pointer values. They can certainly hold a value that is
the address of the first element in an array, but they are not restricted
to that usage.
and we can
I don't know what you mean by "scrolling the pointer" but, as I pointed out
earlier, A[i] and *(A + I) are synonymous. I suppose that's what you are
reaching towards.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 27 '06 #36
xdevel <xd********@yahoo.comwrote:
>Hi, if I have:

int a=100, b = 200, c = 300;
int *a[] = {&a, &b, &c};
This reminds me of a party I went to once, where everyone was named
Chris. I don't remember who I met there... :-)

Anyway, besides all the other verbiage that has occurred in this
thread, you may find some picture-based examples interesting.
See <http://web.torek.net/torek/c/pa.html>. Unfortunately I do
not include a pointer-to-pointer in the above, but after looking
at that, consider the following code fragment and ASCII-art diagram:

int a1 = 1, a2 = 2, a3 = 3;
int arr[] = { 1, 2, 3 };
int *q[] = { &a1, &arr[1] };
int **pp = &q[1];

a1 arr a2
+---+ +---+---+---+ +---+
| 1 | | 1 | 2 | 3 | | 2 |
+---+ +---+---+---+ +---+
^ ^
| /
\ / a3
| | +---+
+---|---+---|---+ | 3 |
| * | * | +---+
+-------+-------+
q ^ pp
| +-------+
\---------* |
+-------+

Here, "pp" is a pointer to a pointer to an int. It currently points
to a pointer to an int (the one named q[1]), which in turn points
to an int (the one named arr[1]).

The "boxes" actually exist in memory at run-time, somewhere in your
C system, or at least the C system is required to act as if they do.
The arrows are the values of the pointers; those also exist. The
labels -- a1, arr, a2, and so on -- need not exist at all at run-time,
as long as the compiler can somehow arrange for:

q[0] = &a3;

to change the arrow stored in q[0] so that it points to a3.

If we store NULL in "pp", it points nowhere, which is hard to
draw in ASCII; those with an EE background (or experience) might
draw it as "grounded:

+-------+
| * |
+---|---+
|
_|_
\ /

It is impossible, however, to set "q" to NULL; q is merely a label
that covers the two actual objects q[0] and q[1]. We can set q[0]
or q[1] to NULL, because those are labels for actual boxes, containing
arrows (pointers). But we can ask the C compiler to "store q" into
pp:

pp = q; /* same meaning as "pp = &q[0];" */

because the compiler sees a request for "the value of q" as a way
for you to ask for the address of the object q[0]. That is, the
"value" of an array object is the address of the array's first
element. (This only happens "one at a time"; see the pa.html page
above, again.)

Pictorially speaking, you can think of this as: 1. All objects
are "boxes containing values" (the "value" of an automatic object
is just trash until initialized of course). 2. Pointer *values*
are "arrows", which can be stored in boxes of the appropriate type,
and which then point at some other object -- a box -- that can
contain another value. An array, however, is just a collection of
one or more boxes. The "real" value of the array is "every value
stored in every box", but C compilers will not let you get them
all in one lump, as it were; if you ask for the value of the array,
you get the address of the first box. 3. Setting any particular
pointer object to NULL "grounds" the pointer, so that it no longer
points to any box.
--
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
Reading email is like searching for food in the garbage, thanks to spammers.
Sep 27 '06 #37
Richard Heathfield <in*****@invalid.invalidwrites:
[...]
I've shown that Stroustrup, Kernighan, Deitel, and even Schildt agree that
arrays are not pointers, despite having something in common with them.

I've shown that an object of type "array of ints" has a different size to an
object of type "pointer to int", and therefore they *have to be* different
types, because any two things that are the same type will have the same
size.

What I haven't yet done, however, is shown you the language definition's
explanations of the two terms. So let's do that now:

3.1.2.5 Types

[...]

* An array type describes a contiguously allocated set of objects
with a particular member object type, called the element type .Array
types are characterized by their element type and by the number of
members of the array. An array type is said to be derived from its
element type, and if its element type is T , the array type is
sometimes called ``array of T .'' The construction of an array type
from an element type is called ``array type derivation.''

[...]

* A pointer type may be derived from a function type, an object type,
or an incomplete type, called the referenced type. A pointer type
describes an object whose value provides a reference to an entity of
the referenced type. A pointer type derived from the referenced type
T is sometimes called ``pointer to T .'' The construction of a pointer
type from a referenced type is called ``pointer type derivation.''
Some other sections of the standard are very relevant as well.
(Richard quoted from the ANSI C89 standard; I'll quote from C99.
There's no significant difference between them in this area.)

C99 6.3.2.1p3:

Except when it is the operand of the sizeof operator or the unary
& operator, or is a string literal used to initialize 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. If the
array object has register storage class, the behavior is undefined

So any expression of array type (including, but not limited to, the
name of an array object) is implicitly converted to a pointer in most,
but not all, contexts. (This conversion is sometimes referred to as
"decaying".)

I'll also note that there's some confusion about the word "pointer".
Some people prefer to use "pointer" only to refer to objects of
pointer type, and "address" to refer to the value of such an object.
That's a reasonable distinction, but it's one that the standard
doesn't make. In several places, the standard uses the term "pointer"
to refer to a *value* of pointer type (for example, when discussing
the result returned by malloc()). You can avoid confusion by avoiding
use of the term "pointer" without qualification; instead, you can
refer to a "pointer object", or a "pointer type", or a "pointer
value". (A pointer value is also called an "address".)

Also, C99 6.7.5.3p7 says:

A declaration of a parameter as "array of _type_" shall be
adjusted to "qualified pointer to _type_", where the type
qualifiers (if any) are those specified within the [ and ] of the
array type derivation.

(C90 has similar wording, but doesn't talk about qualifiers.)

For example a function declaration like this:

void foo(int arr[]);

*appears* to declare an array parameter, but it doesn't; it really means:

void foo(int *arr);

Unlike the treatment of array expressions, this isn't a conversion; in
the context of an array parameter declaration (and *only* in that
context), "int arr[]" really means "int *arr".

Now let's look at the indexing operator. Consider the following:

double arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 );
int i = 5;
double d = arr[i];

It's obvious that in the expression arr[i], arr is an array and i is
an integer. It's obvious, but it's *not true*. The index operator
takes two operands, a pointer and an integer. By definition, x[y] is
equivalent to *(x+y). But we declared "arr" as an array, so what's
going on?

Look back at C99 6.3.2p3. In the expression arr[i], arr is an
expression of array type, and it's not the operand of a unary "sizeof"
or "&" operator, so it's converted to a pointer to its first element
-- which is exactly what the [] operator expects. The prefix to the
[] operator could as easily have been the name of a pointer object (as
long as it points to an array object in memory); in that case, there
would be no implicit array-to-pointer conversion.

Here's another example:

#include <stdio.h>

void func(double array_param[5])
{
int i;
for (i = 0; i < 5; i ++) {
printf("array_param[%d] = %f\n", i, array_param[i]);
}
}

int main(void)
{
double array_object[5] = { 10, 20, 30, 40, 50 };
func(array_object);
return 0;
}

This is a perfectly legal program (try it), and it *looks* exactly
like it passes an array object as an argument to a function that
expects an array as its first parameter. But that's not what's
happening. In "func(array_object)", the expression array_object
decays to a pointer to its first element. The parameter declaration
"double array_param[5]" *really* means "double *array_param"; the 5 is
silently ignored (yuck!). You could have passed a 10 element array,
or a 2-element array, or even a null pointer, to the function and it
would still be perfectly legal (though attempts inside the function to
access nonexistent array elements could blow up in your face). So the
above program is legal, but what it really *means* is this:

#include <stdio.h>

void func(double *array_param)
{
int i;
for (i = 0; i < 5; i ++) {
printf("array_param[%d] = %f\n", i, *(array_param+i));
}
}

int main(void)
{
double array_object[5] = { 10, 20, 30, 40, 50 };
func(&(array_object[0]));
return 0;
}

Arrays are not arrays. Pointers are not pointers. But they're very
closely related, since most operations on arrays are defined in terms
of pointer arithmetic. And furthermore, some of the rules in the
language, intended to make programming easier, tend (in my humble
opinion) to make it more difficult to keep the distinction straight in

Once you understand these few rules, though, it all becomes clear.

Apart from the standard, the comp.lang.c FAQ at
<http://www.c-faq.com/is an *excellent* resource. Section 6 is
do so now.

--
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.
Sep 27 '06 #38
Excellent article, mostly snipped. Below, you will find:

* one historical observation
* one nit

:-)

Keith Thompson said:

<snip>
>
For example a function declaration like this:

void foo(int arr[]);

*appears* to declare an array parameter, but it doesn't; it really means:

void foo(int *arr);

Unlike the treatment of array expressions, this isn't a conversion; in
the context of an array parameter declaration (and *only* in that
context), "int arr[]" really means "int *arr".
The reason for this is at least mildly interesting. When such notables as
Joseph, Moses, and Noah were programming in C, the syntax int arr[] was
used - throughout! - to mean "arr is a pointer to int". At some point,
arrays were introduced, and they stole the [] syntax, leaving pointers to
grub around for some other symbol to parasitize. But, whether by accident
or design, the old syntax for a pointer, [], remained legal (with its old
semantics) in (and only in) function parameter lists.

More information on this is available on Dennis Ritchie's Web site, at the
following URL:

<http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html>

<snip>

And now for the nit...
Arrays are not arrays. Pointers are not pointers.
<coughNot quite what you meant! :-)

s/pointers/arrays/
s/arrays. P/pointers P/

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 28 '06 #39
Richard Heathfield <in*****@invalid.invalidwrites:
[...]
Keith Thompson said:
[...]
And now for the nit...
>Arrays are not arrays. Pointers are not pointers.

<coughNot quite what you meant! :-)

s/pointers/arrays/
s/arrays. P/pointers P/
Thanks, and ouch!

--
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.
Sep 28 '06 #40

Keith Thompson ha scritto:
Also, C99 6.7.5.3p7 says:

A declaration of a parameter as "array of _type_" shall be
adjusted to "qualified pointer to _type_", where the type
qualifiers (if any) are those specified within the [ and ] of the
array type derivation.

(C90 has similar wording, but doesn't talk about qualifiers.)

For example a function declaration like this:

void foo(int arr[]);

*appears* to declare an array parameter, but it doesn't; it really means:

void foo(int *arr);

Unlike the treatment of array expressions, this isn't a conversion; in
the context of an array parameter declaration (and *only* in that
context), "int arr[]" really means "int *arr".
so we can, at the end, say that array and pointers are not same
objects but closely
related because the compiler (view ISO standards) convert its into
pointer to
the the array first element...

Sep 28 '06 #41
Keith Thompson ha scritto:

* A pointer type may be derived from a function type, an object type,
or an incomplete type, called the referenced type. A pointer type
describes an object whose value provides a reference to an entity of
the referenced type. A pointer type derived from the referenced type
T is sometimes called ``pointer to T .'' The construction of a pointer
type from a referenced type is called ``pointer type derivation.''

Some other sections of the standard are very relevant as well.
(Richard quoted from the ANSI C89 standard; I'll quote from C99.
There's no significant difference between them in this area.)

C99 6.3.2.1p3:

Except when it is the operand of the sizeof operator or the unary
& operator, or is a string literal used to initialize 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. If the
array object has register storage class, the behavior is undefined

So any expression of array type (including, but not limited to, the
name of an array object) is implicitly converted to a pointer in most,
but not all, contexts. (This conversion is sometimes referred to as
"decaying".)

I'll also note that there's some confusion about the word "pointer".
Some people prefer to use "pointer" only to refer to objects of
pointer type, and "address" to refer to the value of such an object.
That's a reasonable distinction, but it's one that the standard
doesn't make. In several places, the standard uses the term "pointer"
to refer to a *value* of pointer type (for example, when discussing
the result returned by malloc()). You can avoid confusion by avoiding
use of the term "pointer" without qualification; instead, you can
refer to a "pointer object", or a "pointer type", or a "pointer
value". (A pointer value is also called an "address".)

Also, C99 6.7.5.3p7 says:

A declaration of a parameter as "array of _type_" shall be
adjusted to "qualified pointer to _type_", where the type
qualifiers (if any) are those specified within the [ and ] of the
array type derivation.
so, at the end, we can say that array are not pointer (they aren't same
objects) but
in some cases they are converted into pointers ... and thus we can also
use the
arithmetic notation...

Sep 28 '06 #42
xdevel said:

<snip>
so we can, at the end, say that array and pointers are not same
objects but closely
related
We said that at the beginning, too.

because the compiler (view ISO standards) convert its into
pointer to
the the array first element...
When an array's name is used in a context where a value is required, the
value supplied is indeed a pointer to the array's first element. This is
not the case where the context requires an object (e.g. &array) or where no
evaluation is performed (e.g. sizeof array).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 28 '06 #43

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