I am having problems understanding how this equation works in c:
char *sum(char *a, int b) {
return &a[b];
}
printf("%d", sum(5, 4));
I understand how arrays work, and I understand how to reference and de-reference a variable to a memory location, but I don't understand where the addition comes in to play here.
It makes sense to me that return &a[4]
for example would just return a de-referenced non-existent memory location and cause an error.
Can someone explain this to me in easy terminology?
3 Answers 3
In C, the array index operation a[b]
is implicitly treated by the compiler as *(a + b)
.
This property means that you can write, for example:
assert(5["A string"] == 'i');
And it is true.
Because C also performs implicit conversions from int
to a pointer type, your example is evaluated like this:
sum(5,4) -> char *a = 5, b = 4
return &a[b]; -> return &(*(a + b)); -> return &(*((char*)5 + 4));
Because there is no memory access, (the value of a[b] is not inspected or assigned) the & and * operators are canceled out, and the inner sum (5+4
) is cast to char*
returned as-is.
The particular location of a
in memory is irrelevant, and the value in a
is irrelevant because no memory access is performed.
-
Thank you, that makes sense. I guess I had never seen that before in any other language.Jonathan– Jonathan2013年11月28日 05:54:40 +00:00Commented Nov 28, 2013 at 5:54
-
1@Jonathan: You won't see this in other languages except perhaps C++ (where the rules are a bit different). This is a peculiarity unique to C.greyfade– greyfade2013年11月28日 17:29:56 +00:00Commented Nov 28, 2013 at 17:29
It will return the address of b char units in memory from the pointer to a.
As it will return an address to memory, you can find whatever in that address, a NULL or any other character.
So if you have sum(5,4), the first parameter will be taken as an address (the starting point) and it will return 4 char units in memory from 5.
- If the machine defines a char as 1 byte, then it will return 9.
- If the machine defines a char as 2 bytes, then it will return 5 +たす 2 +たす 2 +たす 2 +たす 2 =わ 13.
- And so on.
-
'4 char units in memory'? If the 'char * a' is 'bff57400', wouldn't 4 'char units' be '7'?Jonathan– Jonathan2013年11月28日 00:58:23 +00:00Commented Nov 28, 2013 at 0:58
-
if bff57400 is an address, &a[4] is bff57404 (if a char is 1 byte),. If its an array of char 'b','f','f'.... then a[4] is 7.mattnz– mattnz2013年11月28日 02:02:47 +00:00Commented Nov 28, 2013 at 2:02
You are nearly there. &a[4]
returns a + 4 times sizeof(type of elements in a) (in this case char). This is then returned, in you case as 5+4 = 9.
The value is valid, but the deference to invalid memory only happens if you use it to access memory, so at this point nothing "bad" has happened.
char *a = sum(5,4)
printf ("%d",a); is OK and prints 9
printf ("%d", *a); all bets off.....
another example to think about : char *x = NULL;
x is NULL, but you do not get a Null pointer exception thrown till you do something with it such as *x = y ;
I also suggest you compile this code with -Wall and study the warnings.
-
1I'm still confused. Let's say the address of 'a' is 'bff57400'. That would mean a[4] would return '7', which referenced will have a completely different memory location. Where does the addition come in?Jonathan– Jonathan2013年11月28日 00:55:35 +00:00Commented Nov 28, 2013 at 0:55
-
The variable a, which happens to be stored as an address, has the value 5 based on how sum is invoked. bff57400 is a red herring.James McLeod– James McLeod2013年11月28日 04:05:03 +00:00Commented Nov 28, 2013 at 4:05