C arrays are not really arrays at run time, where they are just pointers to a contiguous block of objects of the same type. When you see items[n]
, that's just syntactic sugar for *(items+n)
.
In your example addLines[1]
would be *(lines+1)
and addLines[0]
would be *(lines+0)
, which is *lines
. So, addLines
is just lines
without the pointer dereference. *lines
is the first item in the array and lines
is the whole array.
Arrays have some differences to pointers at compile time. For example, sizeof(addLines)
would give you the size of the whole array.
Array-ness is lost as soon as you pass the array somewhere where it's size might be variable, but you can still use the subscript operator. For example:
#include <Foundation/Foundation.h>
#define showsize( expr ) ( printf(#expr " = %zd\n", ( expr ) ) )
CGPoint *
pass_back(CGPoint points[4])
{
showsize(sizeof(points));
return points;
}
int
main(void)
{
CGPoint square[] = {CGPointMake(-1.0, 1.0),
CGPointMake( 1.0, 1.0),
CGPointMake( 1.0, -1.0),
CGPointMake(-1.0, -1.0)};
CGPoint* returned;
int i;
showsize(sizeof(CGPoint));
showsize(sizeof(CGPoint*));
showsize(sizeof(square));
returned = pass_back(square);
showsize(sizeof(returned));
for (i = 0; i < 4; ++i) {
printf("returned[%d] = {%0.1f, %0.1f}\n", i, (float) returned[i].x,
(float) returned[i].y);
}
return 0;
}
This outputs the following on my Mac:
sizeof(CGPoint) = 8
sizeof(CGPoint*) = 4
sizeof(square) = 32
sizeof(points) = 4
sizeof(returned) = 4
returned[0] = {-1.0, 1.0}
returned[1] = {1.0, 1.0}
returned[2] = {1.0, -1.0}
returned[3] = {-1.0, -1.0}
Here, square
is the size of four CGPoint
s, but once sent to the pass_back
function, it's only the size of a pointer, because that's what it is. When the pointer comes back (and named returned
) it can still be used like an array.
Note the magic number 4
in the loop. The pointer doesn't know the length of the array it's pointing to.
Arrays cannot be reassigned with the =
operator. If you really must populate addLines
with the points from lines
, you can do that with something like the following:
memcpy(addLines, lines, sizeof(CGPoint) * numberOfPoints);
You'll have to get numberOfPoints
from somewhere, and addLines
will have to be large enough to handle those points. That's okay if the number of points is a constant, but it would be bad if the number of points can vary at run time, especially if the points come from the outside world (think arbitrary code execution).
I'd change averageResponseTimePoints
to return an NSArray rather than a C-style array. You'll need to encapsulate the CGPoint
s in objects - either your own object or NSValue
s.
Here's an example of how you could write averageResponseTimePoints
:
- (NSArray*) averageResponseTimePoints
{
NSMutableArray* result = [[[NSMutableArray alloc] init] autorelease];
for (int i = 0; i < numberOfPoints; ++i) {
NSValue* point = [NSValue value:points+i
withObjCType:@encode(CGPoint)];
[result addObject:point];
}
return result;
}
If your code runs with CocoaTouch, you can use this to create the point value instead:
NSValue* point = [NSValue valueWithCGPoint:points[i]];
To get the CGPoint
s out of the array, you could write something like this:
for (NSValue* value in result) {
NSPoint pt;
[value getValue:&pt];
NSLog(@"%f %f", pt.x, pt.y);
}
Or with CocoaTouch:
CGPoint pt = [value CGPointValue];
valueWithCGPoint:
andvalueWithPointer:
. Details here – Kalindi