返回参数值

时间:2015-07-13 09:32:12

标签: objective-c return

我正在尝试通过调用以下方法将c01参数值更新为新值。但是它仍会返回0

[self testingmethod:c01];

方法体是:

- (void)testingmethod:(int)y {
  int x;
  x = arc4random() % 399 + 1;
  while (x == y || x == 0){
    x = arc4random() % 399 + 1;
  }
  y = x;
  return y; // is this right?
}

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

这里有两种可能的方式让你做你想要达到的目标:

第一个想法

- (int)testingMethod:(int)y {
    int x;
    x = arc4random() % 399 + 1;
    while (x == y || x == 0){
        x = arc4random() % 399 + 1;
    }
    y = x;
    return y;
}

然后

c01 = [self testingMethod:c01];

第二个想法

- (void)testingMethod:(int *)y {
    if (y) {
        int x;
        x = arc4random() % 399 + 1;
        while (x == *y || x == 0){
            x = arc4random() % 399 + 1;
        }
        *y = x;
    }
}

然后

[self testingMethod:&c01];

答案 1 :(得分:0)

您的方法签名是......

- (void)testingmethod:(int)y

......这说:

  • 没有返回值(void),
  • 名称为testingmethod
  • 它接受一个名为y的名为int的参数。

如果要返回值,则必须将方法签名更改为..

- (int)testingmethod:(int)y

......和方法体......

- (int)testingmethod:(int)y {
  int x;
  x = arc4random()%400 + 1;
  while(x == y || x == 0){
    x = arc4random()%400 + 1;
  }
  return x;
}

另请勿将arc4random()%一起使用。有arc4random_uniform

u_int32_t arc4random_uniform(u_int32_t upper_bound);
  

arc4random_uniform()将返回均匀分布的随机数   小于upper_bound。建议使用arc4random_uniform()   像``arc4random()%upper_bound''这样的结构,因为它避免了“模数”   偏见“当上限不是2的幂时。

它导致了这段代码......

- (int)testingmethod:(int)y {
  int x;
  x = arc4random_uniform(400) + 1;
  while(x == y || x == 0){
    x = arc4random_uniform(400) + 1;
  }
  return x;
}

......可以这样使用:

c01 = [self testingmethod:c01];

这可以进一步优化到......

- (int)testingmethod:(int)y {
  int x;
  do {
    x = arc4random_uniform(400) + 1;
  } while(x == y);
  return x;
}

...因为:

  • u_int32_t未签名,arc4random...返回正数(>= 0),
  • 您正在为此号码添加1,它永远不会是0,无法检查0
  • do while更好,因为只有一行生成数字,一般情况下,do while用于while,以便在比较值之前需要执行某些语句。

在原始示例中修改c01时,为什么不修改y值? Objective-C是C的超集,C的所有内容也是Objective-C。

  

函数参数始终按值传递。传递参考是   通过显式传递指针值在C中模拟。

您想模拟参考,那么,您可以更改c01的值吗?使用指针......

- (void)testingmethod:(int *)y {
  if ( y == nil ) { return; }
  int x;
  do {
    x = arc4random_uniform(400) + 1;
  } while(x == *y);
  *y = x;
}

用法:

[self testingmethod:&c01];

基于评论的所需数字生成器示例。为了便于阅读和正确理解,根本没有优化。

@interface RandomNumberGenerator: NSObject

- (NSArray *)generatorRandomNumbersWithLowerBound:(NSUInteger)lowerBound
                                       upperBound:(NSUInteger)upperBound
                                            count:(NSUInteger)count;

@end

@implementation RandomNumberGenerator

- (NSArray *)generatorRandomNumbersWithLowerBound:(NSUInteger)lowerBound
                                       upperBound:(NSUInteger)upperBound
                                            count:(NSUInteger)count {

  if ( lowerBound > upperBound ) {
    // lowerBound can't be greater than upperBound, error
    return nil;
  }

  if ( count == 0 ) {
    // number of required numbers is not > 0? error
    return nil;
  }

  if ( lowerBound == upperBound ) {
    // bounds equals
    if ( count == 1 ) {
      // equal bounds, just return one number
      return @[ @(lowerBound) ];
    } else {
      // equal bounds, but required more than one number, error
      return nil;
    }
  }

  if ( count > upperBound - lowerBound + 1 ) {
    // number of required numbers is greater than available numbers in given bounds, error
    return nil;
  }

  // arc4random_uniform generates numbers from 0, just calculate right upper bound
  NSUInteger arc4randomUpperBound = upperBound - lowerBound + 1;
  NSUInteger arc4randomAddition = lowerBound;

  // generated numbers so far
  NSMutableArray *numbers = [@[] mutableCopy];

  // loop until all required numbers are generated
  while ( numbers.count < count ) {
    NSInteger x;
    do {
      x = arc4random_uniform((u_int32_t)arc4randomUpperBound) + arc4randomAddition;
      // loop till generated number is not in already generated numbers
    } while ( [numbers indexOfObject:@(x)] != NSNotFound );
    [numbers addObject:@(x)];
  }

  return numbers;
}

@end

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    RandomNumberGenerator *generator = [[RandomNumberGenerator alloc] init];

    NSLog( @"1-400, 10 numbers: %@",
      [generator generatorRandomNumbersWithLowerBound:1 upperBound:400 count:10]);
    NSLog( @"0-9, 10 numbers: %@",
      [generator generatorRandomNumbersWithLowerBound:0 upperBound:9 count:10]);
  }
  return 0;
}