Ответ 1
C массивы не являются массивами во время выполнения, где они просто указывают на непрерывный блок объектов того же типа. Когда вы видите items[n]
, это просто синтаксический сахар для *(items+n)
.
В вашем примере addLines[1]
будет *(lines+1)
и addLines[0]
будет *(lines+0)
, что равно *lines
. Таким образом, addLines
является просто lines
без разыменования указателя. *lines
- это первый элемент массива, а lines
- весь массив.
Массивы имеют некоторые отличия от указателей во время компиляции. Например, sizeof(addLines)
предоставит вам размер всего массива.
Массив теряется, как только вы передаете массив где-нибудь, где размер может быть переменным, но вы все равно можете использовать оператор индекса. Например:
#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;
}
Это выводит на моем 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}
Здесь square
представляет собой размер четырех CGPoint
s, но после отправки функции pass_back
это только размер указателя, потому что это то, что оно есть. Когда указатель возвращается (и называется returned
), он все равно может использоваться как массив.
Обратите внимание на магическое число 4
в цикле. Указатель не знает длину массива, на который он указывает.
Массивы не могут быть переназначены оператором =
. Если вы действительно должны заполнить addLines
точками из lines
, вы можете сделать это с помощью следующего:
memcpy(addLines, lines, sizeof(CGPoint) * numberOfPoints);
Вам нужно будет получить numberOfPoints
откуда-нибудь, а addLines
должен быть достаточно большим, чтобы обрабатывать эти точки. Это нормально, если количество точек является константой, но было бы плохо, если бы количество точек могло меняться во время выполнения, особенно если точки поступают из внешнего мира (подумайте о произвольном выполнении кода).
Я бы изменил averageResponseTimePoints
, чтобы вернуть NSArray, а не массив C-style. Вам нужно инкапсулировать объекты CGPoint
в объекты - либо ваш собственный объект, либо NSValue
s.
Вот пример того, как вы могли написать 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;
}
Если ваш код работает с CocoaTouch, вы можете использовать его для создания значения точки:
NSValue* point = [NSValue valueWithCGPoint:points[i]];
Чтобы получить CGPoint
из массива, вы можете написать примерно следующее:
for (NSValue* value in result) {
NSPoint pt;
[value getValue:&pt];
NSLog(@"%f %f", pt.x, pt.y);
}
Или с CocoaTouch:
CGPoint pt = [value CGPointValue];