Newbie question about 'sizeof' and arrays

This is a discussion on Newbie question about 'sizeof' and arrays within the C Programming forums, part of the General Programming Boards category; I do believe an array name IS the first value's address. For example: Code: int array[5]; *(array) = 5; array[0] ...

  1. #16
    Registered User
    Join Date
    Apr 2006
    Posts
    137
    I do believe an array name IS the first value's address.

    For example:
    Code:
    int array[5];
    *(array) = 5;
    array[0] = 5; // same thing
    So in a way, an array is a pointer, but they have distinctions of course.
    ★ Inferno provides Programming Tutorials in a variety of languages. Join our Programming Forums. ★

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Quote Originally Posted by execute
    I do believe an array name IS the first value's address.
    As I have repeated, no, that is not true. Semantically, a conversion happens from array to pointer to first element of array.

    Quote Originally Posted by execute
    So in a way, an array is a pointer, but they have distinctions of course.
    Yes, you could look at it like that, especially since array notation and pointer notation are also mostly interchangeable.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by laserlight View Post
    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.
    Isn't it the same thing then?
    If int mins[5] then mins is of the type pointer to int (a[0] specifically), but its size is the total no. of bytes that make up that object ie if int is 4 bytes then 5*4 = 20 bytes. I fail to see the difference in what you have quoted and what is given in K&R's ANSI C book.

  4. #19
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by itCbitC View Post
    Isn't it the same thing then?
    If int mins[5] then mins is of the type pointer to int (a[0] specifically), but its size is the total no. of bytes that make up that object ie if int is 4 bytes then 5*4 = 20 bytes. I fail to see the difference in what you have quoted and what is given in K&R's ANSI C book.
    I would suggest reading what you quote. An expression that has type "array of foo" has type "array of foo" more or less by definition. It can be converted to an expression of "pointer to foo", but it is not, in and of itself, of that type.

    I don't have a copy of K&R, so I don't actually know what you're referring to. Do you mean
    Code:
    int mins[5];  /*the type of mins is pointer to int*/
    ? If so, then I'm a little bit surprised (ok, a lot surprised) that that appears. I understood that arrays were a bolted-on after-market accessory to original C, but I thought that by the time ANSI came around arrays were a full part of the language.

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Quote Originally Posted by itCbitC
    Isn't it the same thing then?
    If int mins[5] then mins is of the type pointer to int (a[0] specifically), but its size is the total no. of bytes that make up that object ie if int is 4 bytes then 5*4 = 20 bytes.
    I can admit that this is being pedantic, but there is a pedantic difference. If you say that mins is of type pointer to int, then it follows that sizeof(mins) == sizeof(int*), and likewise sizeof(mins) == sizeof(&mins[0]). However, empirically you know that this is not the case. The explanation is that mins is not a pointer; it is an array.

    Let's use cas' other example. Now, you say that mins is of type pointer to int. That implies that &mins is of type pointer to pointer to int. So, we can write this program:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        int mins[5] = {0, 1, 2, 3, 4, 5};
        int **p = &mins;
        printf("%d\n", (*p)[1]);
        return 0;
    }
    Since p of type int**, *p is of type int*, and (*p)[1] is of type int. We expect that the output is 1. Compile and run the program. What output do you get?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by tabstop View Post
    I would suggest reading what you quote. An expression that has type "array of foo" has type "array of foo" more or less by definition. It can be converted to an expression of "pointer to foo", but it is not, in and of itself, of that type.
    I guess all I am trying to say is that the compiler has double-standards (no pun intended!) when it comes to arrays. When given as the operand to the sizeof operator, it's an object that has been allocated a chunk of bytes; otherwise it's converted to be of the type "pointer to ..." though it's not an lvalue as it's a const*.
    Quote Originally Posted by tabstop View Post
    I don't have a copy of K&R, so I don't actually know what you're referring to. Do you mean
    excerpt from book below and perhaps you can clear the mists swirlin' in head!
    Code:
    primary-expression [ expression ]
    A primary expression followed by an expression in square brackets is a primary expression. 
    The intuitive meaning is that of a subscript. Usually, the primary expression has type ‘‘pointer
    to . . .’’, the subscript expression is int, and the type of the result is ‘‘ . . . ’’. The expression ‘‘E1
    [E2]’’ is identical (by definition) to ‘‘* ( (E1) + ( E2 ) ) ’’. All the clues needed to understand this 
    notation are contained in this section together with the discussions in ...
    Quote Originally Posted by tabstop View Post
    ? If so, then I'm a little bit surprised (ok, a lot surprised) that that appears. I understood that arrays were a bolted-on after-market accessory to original C, but I thought that by the time ANSI came around arrays were a full part of the language.
    AFAIK arrays were in pre ANSI C too though frankly I'm not sure if they were bolted on as a value added selling point.

  7. #22
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Quote Originally Posted by itCbitC
    I guess all I am trying to say is that the compiler has double-standards (no pun intended!) when it comes to arrays. When given as the operand to the sizeof operator, it's an object that has been allocated a chunk of bytes; otherwise it's converted to be of the type "pointer to ..." though it's not an lvalue as it's a const*.
    I agree, but I suppose that the practical reason is that copying the array would have been an expensive default, leading to a proliferation of &a[0] to pass an array named a as an argument. Making the conversion to a pointer to the first element as a default simplifies that syntax, at the cost of introducing special cases somewhere else.

    Quote Originally Posted by itCbitC
    excerpt from book below and perhaps you can clear the mists swirlin' in head!
    execute's comment in post #16 seems fine to me: "so in a way, an array is a pointer, but they have distinctions of course".
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #23
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by itCbitC View Post
    I guess all I am trying to say is that the compiler has double-standards (no pun intended!) when it comes to arrays. When given as the operand to the sizeof operator, it's an object that has been allocated a chunk of bytes; otherwise it's converted to be of the type "pointer to ..." though it's not an lvalue as it's a const*.

    excerpt from book below and perhaps you can clear the mists swirlin' in head!
    Code:
    primary-expression [ expression ]
    A primary expression followed by an expression in square brackets is a primary expression. 
    The intuitive meaning is that of a subscript. Usually, the primary expression has type ‘‘pointer
    to . . .’’, the subscript expression is int, and the type of the result is ‘‘ . . . ’’. The expression ‘‘E1
    [E2]’’ is identical (by definition) to ‘‘* ( (E1) + ( E2 ) ) ’’. All the clues needed to understand this 
    notation are contained in this section together with the discussions in ...
    AFAIK arrays were in pre ANSI C too though frankly I'm not sure if they were bolted on as a value added selling point.
    So here's where the word "conversion" comes in again. If E1 is an array, and the name is evaluated by itself, it is converted to a pointer to the first element (not permanently; think of it as a new temporary object of type pointer to ... if you want). So E1[E2] is syntactic sugar for *(E1 + E2); in this expression E1 is evaluated by itself (before the +E2 happens), so the conversion happens. (And then the pointer arithmetic happens, and the dereferencing.)

  9. #24
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303
    From reading the to and fro here today I think the concept has settled in my head somewhat. The array name is not really a pointer, it's just converted to/used as one in certain situations, like when passing an array as an argument into a function. But since it's not really a pointer, the operator sizeof gives the total size of the array as expected. Am I right? I'm pretty much new to C and the concept of pointers and as I was warned, it can be a little tricky to the beginner!

  10. #25
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    Quote Originally Posted by Sharke View Post
    From reading the to and fro here today I think the concept has settled in my head somewhat. The array name is not really a pointer, it's just converted to/used as one in certain situations, like when passing an array as an argument into a function. But since it's not really a pointer, the operator sizeof gives the total size of the array as expected. Am I right? I'm pretty much new to C and the concept of pointers and as I was warned, it can be a little tricky to the beginner!
    Yep, that's pretty much it!

  11. #26
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,548
    Quote Originally Posted by Sharke View Post
    From reading the to and fro here today I think the concept has settled in my head somewhat. The array name is not really a pointer, it's just converted to/used as one in certain situations, like when passing an array as an argument into a function.
    Yes, that's true.

    But since it's not really a pointer, the operator sizeof gives the total size of the array as expected. Am I right? I'm pretty much new to C and the concept of pointers and as I was warned, it can be a little tricky to the beginner!
    Well, the thing is that sizeof (once again) does not decay the array into a pointer, thus sizeof sees the "real type" and can deduce the size from that.
    But when you use the array somewhere else, such as pass it into a function, it becomes a real pointer, and thus sizeof sees the type of the pointer.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Registered User
    Join Date
    Nov 2009
    Posts
    82
    It worked on the function you declared the argument as an ar[5], it didn't work on the function where the parameter was declared as a[] because a[] = *a.
    Last edited by since; 12-08-2009 at 08:13 PM.

  13. #28
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,548
    That's not right. It doesn't matter if you put the actual size in the function header.
    The compiler ignores it. What is passed is a pointer, plain and simple, thus sizeof returns the size of T*, not T[n].
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bit arrays with STL containers
    By Mario F. in forum C++ Programming
    Replies: 23
    Last Post: 07-03-2007, 09:50 AM
  2. arrays dimensioning: malloc and sizeof
    By c programmer in forum C Programming
    Replies: 10
    Last Post: 03-27-2007, 12:03 PM
  3. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  4. questions about arrays
    By laasunde in forum C++ Programming
    Replies: 3
    Last Post: 08-14-2003, 05:53 AM
  5. sizeof on arrays
    By sanu in forum C++ Programming
    Replies: 10
    Last Post: 06-28-2002, 10:10 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21