Array and Pointer Tutorial

N

Nelu

Keith said:
Nelu said:
Nelu said:
Keith Thompson wrote:
Passing it as a parameter is irrelevant.
<snip>

I'm not sure how irrelevant it is. Check this code:

void foo(char b[]) {
b++;
printf("%ld\t%ld\n",sizeof(b),sizeof(char*));
}

b is not an array; it's a pointer object. And it's not a const
object; it's merely initialized to the value of the actual argument.

In a parameter declaration, "char b[]" is merely an alias for "char *b".
This is independent of the rules for implicit conversion of array
names to pointer values.

Also, "%ld" is not the correct format for a size_t. You can use "%zu"
if your library conforms to C99, or you can convert the operand to
the expected type:
printf("%d\t%d\n", (int)sizeof b, (int)sizeof(char*));
int main(void) {
char arr[10];
foo(arr);

Here arr is converted to a pointer value, equivalent to &arr[0].
This value is passed to foo and copied to b.
printf("%ld\n",sizeof(arr));

return 0;
}
[snip]

I didn't use %zu (although it works on my gcc) just in case someone
tries it on Turbo C :). I forgot to cast, though, and -Wall didn't say
anything, probably because they are the same type.

The example was just to show that b (in foo) is a pointer object in
accordance with what CBFalconer was saying.


 
N

Nelu

Nelu wrote:

Sorry, I forgot to snip your signature from my previous post and paste
mine. I guess this is a sign I should go to sleep :).
 
P

pete

Forgive me, but I still think CBFalconer is right.

It's time to quote the standard:

N869
6.3.2 Other operands
6.3.2.1 Lvalues and function designators

[#3] 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.
 
P

pete

pete said:
It's time to quote the standard:

I see I already did this on Thursday.
What's the problem, Nelu?
N869
6.3.2 Other operands
6.3.2.1 Lvalues and function designators

[#3] 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.
 
T

Tomás

pete posted:
[#3] 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.

The reason they can put that in the Standard is that they've thought up of
every conceivable place where you can use an array as an array -- there's
only three such places, so it was handy to list them all.

In C++, we treat the array-to-pointer conversion just like any other
implicit conversion (e.g. char to int).

If we have a char:

char k;

It will remain as a char unless it needs to convert. For example:

void TakesAnInt( int r ) {}

int main(void) { char k; TakesAnInt(k); }

Just because a "char" can implicitly convert to an "int" doesn't mean
"char" is any less of a fully-fledged object type.

If we were able to pass arrays by value in C, then they'd have to remove
that paragraph from the Standard (or perhaps add the fourth instance where
you can use an array as an array).

In C++, we have references, and we can pass arrays by reference, so we tend
to look at it from the opposite viewpoint of C programmers.
Instead of thinking:
"When is an array actually an array, instead of being a pointer?"

We think:
"When does the array decay to a pointer?"

The most obvious place where we need to convert from array to pointer is by
the dereference operator:

*array /* You can't dereference an array, so it has
to become a pointer to its first element */


or by block brackets:

array[5] = 2; /* You can't use block-brackets with an array,
so it has to become a pointer to its first
element. */

Or by arithmetic:

array + 3 /* You can't use '+' with an array, so it has to
become a pointer to its first element */

Now that we know that an array will always be an array unless it needs to
convert to a pointer, we can pass arrays by reference:

void SomeFunc( int (&array)[20] )
{

}

int main()
{
int array[20];

SomeFunc( array );
}

The dandy thing about this way of thinking is that it works perfectly for C
aswell.

A char is a char, not an int (but it's more than happy to convert if it
needs to).

An array is an array, not a pointer (but it's more than happy to convert if
it needs to).

As C++ is constantly being developed and expanded upon, it's more
appropriate to state where an array decays to a pointer, rather than where
an array actually stays as an array.

Moral of the story: An array is an array -- not a pointer.

-Tomás
 
C

CBFalconer

Tomás said:
pete posted:
[#3] 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.

The reason they can put that in the Standard is that they've thought
up of every conceivable place where you can use an array as an array
-- there's only three such places, so it was handy to list them all.

In C++, we treat the array-to-pointer conversion just like any other
implicit conversion (e.g. char to int).

if you look closely you will see that this newsgroup is
comp.lang.c, not comp.lang.c++.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
P

pete

if you look closely you will see that this newsgroup is
comp.lang.c, not comp.lang.c++.

I looked at the original post and found:

"I've posted this to a few newsgroups,
so if you'd like to reply,
please post to comp.lang.c
because it's the common denominator.
If your post is C++-specific,
the please post to comp.lang.c++."

I think it was a mistake to post here.

Elsewhere on this thread he quoted a part of the C++ standard
and refered to it as "the Standard".
 
P

pete

Tomás wrote:
In C++, we treat the array-to-pointer conversion just like any other
implicit conversion (e.g. char to int).

In C, there is no typical implicit conversion for your phrase
"just like any other implicit conversion", to refer to.

The rules for implicit conversion varry by type.
There are different rules for the implicit conversions of
expressions of:
function type,
array type,
arithmetic type lower ranking than int,
other arithmetic types,
pointer types.
 
A

Al Balmer

Nelu wrote:

Sorry, I forgot to snip your signature from my previous post and paste
mine. I guess this is a sign I should go to sleep :).

It's a sign that you should use a newsreader that does it for you <g>.
 
A

Al Balmer

On Fri, 12 May 2006 20:54:13 -0400, "Rod Pemberton"

(in a reply to Richard Heathfield.)
The argument makes sense. Have you ever programmed? In C?

Heh. I suggest that you search both Google and Google Groups for
"Richard Heathfield". In quotes, to keep the hits to 50,000 or so.

You might also find his web site educational, on a much broader range
of topics.
 
D

Default User

Al said:
On Fri, 12 May 2006 20:54:13 -0400, "Rod Pemberton"

(in a reply to Richard Heathfield.)

Heh. I suggest that you search both Google and Google Groups for
"Richard Heathfield". In quotes, to keep the hits to 50,000 or so.

Don't feed the troll.




Brian
 
N

Nelu

Al said:
It's a sign that you should use a newsreader that does it for you <g>.

True. I used gnus, slrn and thunderbird. Now I'm on GGroups. Any of the
previous three was way better than this but the laziness is killing me.
 
D

Dave Thompson

From the Standard:

An lvalue refers to an object or function. Some rvalue expressions —-
those of class or cv-qualified class type -- also refer to objects.
Wrong Standard; that's C++, down the hall past the water cooler.

To answer the next question as well, 'cv-qualified' in C++ means the
addition of 'const', 'volatile', both or neither to a type; C just
says 'qualified' (no prefix) for in C90 the same thing and in C99 any
combination of const, volatile, and the new 'restrict'.

- David.Thompson1 at worldnet.att.net
 
R

Richard Bos

Rod Pemberton said:
You should point out the negatives too. If p is already declared, and their
is no comment telling him what file p is declared in. He'll spend forever
trying to answer this question: "What the HELL is p?"

If he is a wise, old, experienced maintenance programmer, he'll ask the
same question of

p = malloc(n * sizeof (some_type));

because his experience tells him that somewhere along the line someone
has changed the definition of p to a type. With any luck, to a type just
smaller than *p, so that this still works, even though it is
semantically incorrect.

Richard
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top