我正在尝试通过调用以下方法将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?
}
有人可以帮我解决这个问题吗?
答案 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;
}