views:

317

answers:

5

What does this line mean? I havn't done C in a few years. Does it perform the operation in parens then make the int result a pointer??

b[0] = *(start + pos++);
+8  A: 

Apparently start is a pointer (or an array, which will decay to a pointer here anyway), which means that the result of the expression in () is a pointer, not an int. The * simply dereferences that pointer.

The whole thing is equivalent to plain b[0] = start[pos++], but for some reason some people prefer to use the obfuscated form as in your post.

AndreyT
Ok, I'm upvoting you but I take offense at the "obfuscated" comment. If you were to keep only two of the three redundant constructs: `p[e]`, `*p`, and `p+e`, the clearest programs would be obtained by keeping the latter two (but I may be partial, working on a C static analyzer whose first transformation is to make all `p[e]` in the program into `*(p+e)` in order to limit the number of constructs to study).
Pascal Cuoq
Well, firstly, I'm not sure what you mean by "three redundant constructs", since they are not equivalent. Secondly, as for `p[e]` vs `*(p + e)`, I'd say that the latter has its applications in some contexts, but in my opinion the `[]` form is much more readable in most cases.
AndreyT
I prefer e[p]. Especially when used likei < 10 ? i["0123456789"] : i-10["abcdef"].
Richard Pennington
Oops, I think I forgot parenthesis around i-10.
Richard Pennington
Aside from the out-of-bounds access, it is valid even without the parenthesis. Depends on what you wanted to achieve :)
AndreyT
Out of bounds? I didn't show the i -)
Richard Pennington
No, I mean `i - 10["abcdef"]` is syntactically valid, but `10["abcdef"]` is trying to access the 10-th element of `"abcdef"` which doesn't exist.
AndreyT
Ah! You're absolutely correct.
Richard Pennington
Pascal Cuoq
+5  A: 

Assuming start is pointer and pos is an integer, it can be easily rewritten to:

b[0] = start[pos++];

Hope this helps you understand.

frunsi
+3  A: 

For this to make sense, either start or pos must be a pointer; most likely, it will be start. The code can then be written as

b[0] = start[pos];
pos = pos + 1;

Actually, the code is equivalent even if pos were the pointer because of C's somewhat funny semantics of array subscription.

Christoph
+2  A: 

The operator '*' returns the value at the location pointed to by the pointer or expression following the operator.

Some examples:

value = *pointer;
value = *(pointer);     // Exactly the same as the first statement.
value = *(pointer + 0); // Take contents of pointer and add zero then dereference.
value = *(pointer + 1); // Deference the first location after the location in pointer.

Sometimes, especially in embedded systems, this is more readable than using the array notation. Example: status = *(UART + STATUS_REGISTER_OFFSET);

Thomas Matthews
+1 for the example of why this syntax would be useful (assuming the use of appropriately named variables)
Adam Bernier
+1  A: 

Note the equivalence of these expressions. First, assume the following declarations establish the types in play:

T* const base;
size_t const pos;

Now, an object of type T located in memory at position

base + sizeof(T) * pos

can be accessed in several ways:

base[pos]                            // Interpret base as an array.
*(base + pos)                        // Pointer arithmetic strides by sizeof(T)
*(T*)((char*)base + sizeof(T) * pos) // Compute stride manually
seh
Your last line is not correct, it should read:`*(T *)((char*)base + sizeof(T) * pos)` else you will only get the first `char` of your element.
tristopia
You're right. I'm more used to writing this in C++, using `reinterpret_cast`, and I blew it here. I corrected the third example after writing a sample program to confirm that the compiler was dissatisfied with my first pass and satisfied with the revision.
seh