#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2

    Array names and array elements


    Question 1: does there exist a memory cell distinct from array elements which store the address of the first element in the array?

    so if I take
    Code:
    double x[] = {1.2, 2.3, 3.4}
    there are memory cells that store type double datas

    x[0] = 1.2
    x[1] = 2.3
    x[3] = 3.4

    and also a pointer memory cell distinct from the array elements

    x = 348905 (or whatever &x[0] is)?


    Question 2:
    in the function declaration
    Code:
    void add_arrays(double x[], double y[], double sum[])
    what exactly is x[]?
    how is this different from a simple x without brackets?

    when I tried to run the function without brackets in the definition and prototype, I got an incompatible argument error.
    so my guess is that the [] tells the compiler that the argument is an array, a group of memory cells, not just one independent memory cell named x.
    but I'm not sure.

    Question 3:
    for the function mentioned above, the call
    Code:
    add_arrays(x1, y1, &sum)
    worked.
    was this not supposed to happen?
    or is "sum" and "&sum" the same?
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    Originally Posted by 046
    Question 1: does there exist a memory cell distinct from array elements which store the address of the first element in the array?

    so if I take
    Code:
    double x[] = {1.2, 2.3, 3.4}
    there are memory cells that store type double datas

    x[0] = 1.2
    x[1] = 2.3
    x[3] = 3.4

    and also a pointer memory cell distinct from the array elements

    x = 348905 (or whatever &x[0] is)?
    Actually, it's x[2] that contains 3.4. There is no x[3], since you've declared a three-element array.

    The array x starts at 348905 (or rather at 0x000552E9 if you had used the %p format flag in printf as you should have). The first element, x[0], is 8 bytes starting at 0x000552E9, though that seems to be a rather odd address, word-boundary-wise (I would have expected the address to be a multiple of 8, sizeof(double)). x[1] should be located 8 bytes higher, at 0x000552F1, and x[2] another 8 bytes higher at 0x000552F9.

    There is no separate pointer variable associated with x unless you explicitly create one. When the compiler processed that array declaration, it stored the array's properties (eg, name, location, size, number of elements) in its symbol table. Then whenever x or an element of x is used in the subsequent code, the compiler looked it up in the symbol table and used its information to generate the object code for that source code. No separate pointer variable is required.

    BTW, I wrote a short test program:
    Code:
    #include <stdio.h>
    
    int main()
    {
        double x[] = {1.2, 2.3, 3.4};
        int  i;
        
        for (i=0; i<3; i++)
            printf("x[%d] at %p\n", i, &x[i]);
    
        return 0;
    }
    The output is:
    C:>a
    x[0] at 0022FF60
    x[1] at 0022FF68
    x[2] at 0022FF70

    C:>
    Even multiples of 8, just as I would have expected.

    Originally Posted by 046
    Question 2:
    in the function declaration
    Code:
    void add_arrays(double x[], double y[], double sum[])
    what exactly is x[]?
    how is this different from a simple x without brackets?

    when I tried to run the function without brackets in the definition and prototype, I got an incompatible argument error.
    so my guess is that the [] tells the compiler that the argument is an array, a group of memory cells, not just one independent memory cell named x.
    but I'm not sure.
    That is correct. double x[] is an array of double, whereas double x would just be a single double value.

    BTW, another way to write double x[] would be double *x. Remember, the name of an array is equivalent to a pointer in most ways (but you cannot assign a new address to it, nor increment or decrement it as you can with an actual pointer).

    Originally Posted by 046
    Question 3:
    for the function mentioned above, the call
    Code:
    add_arrays(x1, y1, &sum)
    worked.
    was this not supposed to happen?
    or is "sum" and "&sum" the same?
    "sum" and "&sum" would not be the same. That is, of course, assuming that sum is a single double variable declared thus:
    double sum;
    In the function declaration, double sum[] is the same as double *sum, meaning that they both tell the function to expect an address, which is a pointer value. &sum provides that address, as would an array named "sum".
    Last edited by dwise1_aol; June 26th, 2013 at 05:06 PM. Reason: You deserved a better example
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2
    The array x starts at 348905 (or rather at 0x000552E9 if you had used the %p format flag in printf as you should have).
    x[1] should be located 8 bytes higher, at 0x000552F1, and x[2] another 8 bytes higher at 0x000552F9.
    the number 348905 was totally random.
    I guess this is what the textbook meant by "memory cells being adjacent in an array".
    each memory cell takes up 8 bits, so the first bit of the next memory cell is right next to the 8th bit of the previous cell. hence, the addresses are multiple of 8's.


    There is no separate pointer variable associated with x unless you explicitly create one. When the compiler processed that array declaration, it stored the array's properties (eg, name, location, size, number of elements) in its symbol table. Then whenever x or an element of x is used in the subsequent code, the compiler looked it up in the symbol table and used its information to generate the object code for that source code. No separate pointer variable is required.
    I see.

    I got
    x[0] is at 0022FF20
    x[1] is at 0022FF28
    x[2] is at 0022FF30
    for my cells.


    In the function declaration, double sum[] is the same as double *sum, meaning that they both tell the function to expect an address, which is a pointer value. &sum provides that address, as would an array named "sum".
    I get that if sum is an array
    double sum[3];, both sum and &sum are addresses,
    and sum is the address of sum[0].
    but what would be &sum?
    is it the address of the symbol name, since the symbol name contains the name of the array, and &sum asks for the address of the name of the array?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    Originally Posted by 046
    the number 348905 was totally random.
    I guess this is what the textbook meant by "memory cells being adjacent in an array".
    each memory cell takes up 8 bits, so the first bit of the next memory cell is right next to the 8th bit of the previous cell. hence, the addresses are multiple of 8's.
    Actually, no.

    In the earlier years of electronic computers, each memory location held one "word", but the length of a "word" could be different from one computer to another; I've even heard of 24-bit words. With the advent of integrated circuits that size of that "word" has become standardized to be 8 bits, which we call a "byte", freeing the word "word" for other uses -- actually, even "byte" used to mean different numbers of bits, so in the specifications for TCP/IP they use the term, "octet", to specify a byte of 8 bits.

    So now each memory location contains 8 bits, but we cannot address those bits individually. In order to read or write a single bit, we need to read or write the entire byte that is at that memory location. So the number of bits in a byte has no bearing whatsoever on memory addresses, but rather the number of bytes in a datatype do.

    If you output the values returned by sizeof() for different datatypes, you will find that a char is 1 byte long, a float is 4 bytes, and a double is 8. That is where I got the 8 from, from the size of each element in that array of double, which is 8. Had nothing to do with the number of bits in a byte, but rather everything to do with the number of bytes in a double.

    Originally Posted by 046
    I get that if sum is an array
    double sum[3];, both sum and &sum are addresses,
    and sum is the address of sum[0].
    but what would be &sum?
    is it the address of the symbol name, since the symbol name contains the name of the array, and &sum asks for the address of the name of the array?
    I couldn't find any reference in the standard to using the address operator on an array name, so I tried it by modifying that short test program:
    Code:
    #include <stdio.h>
    
    int main()
    {
        double x[] = {1.2, 2.3, 3.4};
        double *px;
        int  i;
        
    //    printf("x[0] at %p\nx[1] at %p\nx[2] at %p\n", &x[0], &x[1], &x[2]);
        for (i=0; i<3; i++)
            printf("x[%d] at %p\n", i, &x[i]);
            
        printf("x is at %p, &x is %p\n", x, &x);        
    
        px = x;
        printf("px is %p, &px is %p\n", px, &px);      
          
        return 0;
    }
    This is the output from the program:
    C:>a
    x[0] at 0022FF60
    x[1] at 0022FF68
    x[2] at 0022FF70
    x is at 0022FF60, &x is 0022FF60
    px is 0022FF60, &px is 0022FF5C

    C:>
    As you can see, both x (the array name) and &x (the address of the array) are the same. I would interpret that as saying that x and &x are just two ways of saying the same thing, but it could also be undefined behavior which would mean that you are not guaranteed consistent results. At any rate, there isn't much use for &x, so it would almost never be used (which is why experienced programmers get confused when you ask about it).

    In contrast, please note the pointer px which I set to point to x. It contains the address of x, but &px has extra meaning since px is a pointer variable and hence has its own address. If you wanted to pass px to a function that would set it to point to a double or a double array, then you would need to pass in &px and that parameter would need to be declared as a double ** .

    C is a language, just as English and Japanese are languages. You use a language to convey meaning. When you write in C, think about what you are saying and you should be able to see whether you're making sense or not.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    142
    Rep Power
    2
    Actually, no.
    oh.
    thanks for correcting me.
    I checked addresses by modifying your example program for float and char, and indeed, they did have addresses that differed by 4 and 1 respectively.

    As you can see, both x (the array name) and &x (the address of the array) are the same. I would interpret that as saying that x and &x are just two ways of saying the same thing, but it could also be undefined behavior which would mean that you are not guaranteed consistent results. At any rate, there isn't much use for &x, so it would almost never be used (which is why experienced programmers get confused when you ask about it).
    I see.
    so although with my IDE, I got the same results for x and &x, this substitution might not work for other situations.

    thank you for the explanation; for the moment I'm cleared on the topic.

IMN logo majestic logo threadwatch logo seochat tools logo