0

there is a sample in the chapter pointer of C Primer Plus Book.

I am so confuse about the code which set the array name into the sump function as formal parameter

Answer = sump(array, array + SIZE);

start is 00EFFBD8 ,it is ok that means arrary[0] address but when it action:

int *end = array +SIZE // => "array[0] address + 10"

why end is 00EFFC00 (00EFFBD8 + 10*4), why not 00EFFBD8 +10 ???

enter image description here

#include <stdio.h>

#array size
#define SIZE 10

#sum function
int sump(int *start, int *end); 

int main(void)
{
    int array[SIZE] = { 10,9,8,7,6,5,4,3,2,1 };
    long Answer;

    Answer = sump(array, array + SIZE);
    printf("a is %d\n", Answer);

    return 0;
}

int sump(int *start, int *end)
{
    int total=0;

    while (start < end)
    {
        printf("start is %p,   %d\n", start, *start);
        printf("end is %p, %d\n", end, *end);
        total += *start++;
    }

    return total;
}
Kevin Yan
  • 1,236
  • 11
  • 19
march_seven
  • 691
  • 1
  • 7
  • 13
  • 2
    That's how [pointer arithmetic](https://stackoverflow.com/questions/394767/pointer-arithmetic) works. The expression `array` converts to a pointer-to`int`, and the arithmetic takes over from there for the remainder of the expression. Unrelated, your *dereference* of `end` invokes undefined behavior. You can evaluate the address; not what it points to. It's called the one-past address, and is only valid for eval, not dereference. – WhozCraig Aug 17 '17 at 02:02
  • thanks , OK I know 。array name +10 is same as array name + 1 in some way !!! – march_seven Aug 17 '17 at 02:05
  • @march_seven-- In what way is `array + 10` the same as `array + 1`? – ad absurdum Aug 17 '17 at 02:12
  • Note that printing `*end` is accessing beyond the end of the array, and invokes undefined behaviour. Fortunately for you, the behaviour is fairly benign in this code (that's why you're getting the negative number, though), but it is not safe to do that. The address one beyond the end of the array exists (so `&array[SIZE]` is a valid address; its contents are undefined, though. – Jonathan Leffler Aug 17 '17 at 02:48
  • @David Bowling ,sorry for my poor English, I mean that I know array+1 is array address add one “ int ”(4byte) at first time, but when I saw array+10 ,I was lost before WhozCraig reply, now I got it ,so it is “same as” in my feeling! – march_seven Aug 17 '17 at 03:59

2 Answers2

0

When something is added to an address (array/pointer), adding one to the address means to force the particular pointer to point the starting byte of the next element in the sequence and not the next byte. Accessing next byte doesn't makes sense because what would you do with the weird result as an int is stored in 4 bytes.

-1

Well, each and every data-type int float long and so on.. each occupy some space in the memory when you declare them. For example:

int k; //occupies 4-bytes of memory
float f; //occupies 4-bytes of memory
long l; //occupies 8-bytes
char c; //occupies 2-bytes

That's the C's convention for allocating memory to the variables. Now when you talk about addresses. Imagine memory is in form of blocks and base address/start address is 100. So when you declare an int type variable, it will place it at 100. But, int needs 4-bytes of memory so, the blocks that the CPU will give to this variable 'k' are, 100, 101, 102 and 103 (considering all these blocks are size 1-byte each). So now blocks 100 to 103 are allocated for variable-k.

When you declare an array of int type: int arr[10], the CPU makes 10 such k-variable that i made up there. So that means:

arr[0] //this will have address from 100 to 103
arr[1] //will have address from 104 to 107
arr[2] //will have address from 108 to 111

and so on, while the base address, that is the address of the whole array arr is 100. So you can calculate the address of arr[1] as base address of array + index*size of int where we know that base address of array is 100, index is what we need to calculate (that is 1) and size of int as i said earlier is 4-bytes. So, address of arr[1] = 100 + 1*4 = 104.

Similarly, the end address, that is the arr[9], will be 100 + 9*4 = 136 and the array will end at, 100 + 10*4. Now in your question the values are hexadecimals and base address is not hundred.

EDIT char in C and C++ follow ASCII code and hence only occupy 1 byte of memory. I was confused with Java following Unicode and thank @David-Bowling for making me realize that mistake.

Contrevien
  • 124
  • 12
  • First, a `char` is 1 byte by definition in C, though a `char` (and a byte) need not be 8 bits. Then, type sizes have specified minimums, but may be wider. For example, `int` may be as narrow as 16 bits, though it is commonly 32 bits wide. – ad absurdum Aug 17 '17 at 02:40
  • I guess the newer convention of memory allocation follows the one Java uses, because it was 8-bits before due to the use of ASCII and now almost every language uses Unicode which which just won't fit in 256 characters, rather extends to 16-bits thus char is 2 bytes from what i know and it could certainly differ from system to system. – Contrevien Aug 17 '17 at 02:49
  • [A `char` is 1 byte by definition according to the Standard](http://port70.net/~nsz/c/c11/n1570.html#5.2.4.2.1p1). C has never specified any particular character encoding, ASCII or otherwise. C does also have multibyte characters and a wide character type. – ad absurdum Aug 17 '17 at 02:56
  • Now that this is the accepted answer, you should really attempt to make it correct. As it is now, it is not correct. An `int` _may_ be 4 bytes wide, but _must_ be at least 16 bits wide. A `long int` _may_ be 8 bytes wide, but _must_ be at least 32 bits wide. Most importantly, a `char` is _never_ 2 bytes! The Standard defines the width of a `char`, which must be at least 8 bits, to be 1 byte. A `char` is an _integer type_, and is also a _character type_, but need not be able to hold, e.g., Unicode codepoints. These are specific types with properties that are defined in the Standard. – ad absurdum Aug 17 '17 at 04:17
  • This has nothing to to with ASCII; again, the Standard does not specify the character encoding, and there are systems in existence that use other encodings, such as [EBCDIC](https://en.wikipedia.org/wiki/EBCDIC). The point is that the smallest addressable unit of memory in C is 1 byte, and a `char` is this size by definition (according to the Standard). Further, a byte need not be 8 bits (only 7 are needed for ASCII, anyway); I have heard of systems with 10 bit bytes, for example. – ad absurdum Aug 17 '17 at 15:01
  • Now i must say that you are completely wrong, the size is dependent on the Standard, completely. ASCII recognise, basically only 256 total characters and they are numbered from 0 to 255, this is the value responsible for the size of char to be 8-bits, as 8-bits can represent 2^8 values, which is exactly 256 characters. Similarly, Unicode supports more characters than ASCII so it uses more bits to represent them. – Contrevien Aug 17 '17 at 21:40
  • It is you who are mistaken, and you appear to be misunderstanding my comments. [ASCII has a decimal range of 0-127](https://en.wikipedia.org/wiki/ASCII). [Extended ASCII](https://en.wikipedia.org/wiki/Extended_ASCII) refers to encodings that are 8 bits or wider. A `char` may not be able to hold a Unicode codepoint, as I have already stated. Read the Standard if you want to understand these things, but my primary objection is that a `char` is an integer type in C that is _at least_ 8 bits wide, but a `char` is 1 byte wide, by _definition_ in C. A byte in C is not always 8 bits. – ad absurdum Aug 17 '17 at 21:55
  • "the size is dependent on the Standard, completely"-- not exactly. The minimum width of types is specified in the Standard, and certain mutual relationships among types are specified, but there is no upper bound on the size of types in the Standard. And again, the width of a `char` has nothing to do with ASCII, and everything to do with the minimum size of an addressable object in C. – ad absurdum Aug 17 '17 at 21:57
  • If I have not been clear enough, some aspects of this answer are not right, e.g., "`int` needs 4-bytes of memory", and other parts are flatly wrong: "`char c; //occupies 2-bytes`". – ad absurdum Aug 17 '17 at 22:00