Массивы 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
с, но однажды отправленный в функцию pass_back
, это всего лишь размер указателя, потому что это так и есть. Когда указатель возвращается (и называется returned
), он все еще может использоваться как массив.
Обратите внимание на магическое число 4
в цикле. Указатель не знает длину массива, на который он указывает.
Массивы нельзя переназначить с помощью оператора =
. Если вам действительно нужно заполнить addLines
точками из lines
, вы можете сделать это следующим образом:
memcpy(addLines, lines, sizeof(CGPoint) * numberOfPoints);
Вам нужно откуда-то взять numberOfPoints
, а addLines
должно быть достаточно большим, чтобы справиться с этими точками. Это нормально, если число точек является константой, но было бы плохо , если количество точек может изменяться во время выполнения, особенно если точки приходят из внешнего мира (например, выполнение произвольного кода). 1044 *
Я бы изменил averageResponseTimePoints
, чтобы он возвращал NSArray, а не массив в стиле C. Вам нужно будет инкапсулировать CGPoint
s в объектах - либо ваш собственный объект, либо 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];