#1 楼
除了@Jamal和@ 200_success之前已经写过的东西外,由于g++
和#include "stdafx.h"
签名,Mac OS X上的int _tmain(int argc, _TCHAR* argv[])
无法编译此代码。除非有特殊原因,否则最好使代码具有可移植性。如果删除g++
导入并更改stdafx.h
声明,则main
可以编译。...并且由于未使用
main
的参数,因此可以不带任何参数地声明int main() { ... }
。您已经在true
函数中使用过checkPrime
,为什么不在while
的无限main
循环中而不是1 == 1
中使用它。这可能是个问题,但我认为
while (true) { ... }
比do { ... } while (true)
更具可读性和直观性。 ...实际上,正如@ 200_success所指出的,
for (int currentNum = 2; ; currentNum++) { ... }
循环会更好:这样,在使用它的块中声明了currentNum
,从而消除了潜在的副作用,并且计数器是for
循环。请注意为空的终止条件,这使它成为一个无限循环。在
checkPrime
中,您将变量命名为int Number
,但是通常的约定是不使用大写的变量名,而只需使用int number
。请始终将打开的花括号放在与函数名称相同的行(“括号”)上,或者始终在下一行。建议的实现
#include <iostream>
bool isPrime(int number)
{
for (int a = 2; a < number; a++) {
if (number % a == 0) {
return false;
}
}
return true;
}
int main()
{
for (int currentNum = 2; ; currentNum++) {
if (isPrime(currentNum)) {
std::cout << currentNum << " ";
}
}
}
它可以在没有警告的情况下使用
g++
进行编译,并且可以在Mac OS X和GNU / Linux上正常运行。我希望它也能在Windows中按预期工作。评论
\ $ \ begingroup \ $
为了保持一致,所有功能都不应带有埃及括号,或者所有功能都不应带有埃及括号。就此而言,目前main和isPrime不一致。
\ $ \ endgroup \ $
–leetNightshade
2014年4月7日在22:08
\ $ \ begingroup \ $
@leetNightshade:什么是埃及括号。之前没有听说过。虽然我同意一般性意见。
\ $ \ endgroup \ $
–马丁·约克
2014年4月7日23:30在
\ $ \ begingroup \ $
@LokiAstari埃及方括号将花括号放在函数名称的同一行上,例如:foo(){而不是foo()\ n {(使用\ n表示新行,因为我不能放在其中一条评论。)
\ $ \ endgroup \ $
–活力
2014年4月8日,0:15
\ $ \ begingroup \ $
@Vality hmm,标准K&R支撑的怪异名称。但是确实不适合C ++。
\ $ \ endgroup \ $
– jwenting
14年4月8日在12:01
\ $ \ begingroup \ $
@jwenting我不确定该术语的来源,我认为它是Java中那种括号风格的术语,而K&R风格将毫无意义。但是,很容易猜出C中的含义。就我个人而言,我总是喜欢下一行,否则我的眼睛很难匹配成对的括号,但是在某些约定中这是一种有效的样式。
\ $ \ endgroup \ $
–活力
2014年4月8日在12:10
#2 楼
在C ++中,您现在应该分别使用
std::cout
和std::cin
而不是printf()
和scanf()
。这些位于<iostream>
中,您将不再需要<stdio.h>
。std::cout
示例:int number = 1;
std::cout << "Number: " << number;
std::cin
示例:int number;
std::cin >> number;
currentNum
只需初始化,不声明即可分配:int currentNum = 2;
do while
循环条件应仅为1
,而不是1 == 1
。这仍然等同于true
。您可以将
main()
放在每个函数的下方,从而不需要函数原型,因为它已经知道这些函数的存在。您无需在
return 0
的末尾添加main()
。 。这是一种特殊情况,因为编译器将自动插入return 0
,因为到达此点始终表示成功终止。评论
\ $ \ begingroup \ $
当心:iostreams与stdio在C ++程序员中引起争议。绝对避免使用scanf。
\ $ \ endgroup \ $
–匿名
2014年5月13日20:04
#3 楼
您可能要看的一件事是更有效的代码。您正在为要检查的每个号码运行一个循环。使用Eratosthenes筛网意味着您只需循环一次,向量的索引就会根据质数返回true或false:#include <iostream>
#include <vector>
#include <cmath>
std::vector<bool> MakePrimes(int upperlimit)
{
int bound = (int) floor(sqrt(upperlimit));
upperlimit++;
std::vector<bool> primes(upperlimit, true);
primes[0] = false;
primes[1] = false;
//Since 2 is a special case if we do it separately we can optimize the rest since they will all be odd
for(int i = 4; i < upperlimit; i += 2)
{
primes[i] = false;
}
//Since the only ones we need to look at are odd we can step by 2
for (int i = 3; i <= bound; i += 2)
{
if (primes[i])
{
//Since all the even multiples are already accounted for we start at the first one
//and skip to every other multiple
for (int j = i*i; j < upperlimit; j += i * 2)
{
primes[j] = false;
}
}
}
return primes;
}
int main()
{
int limit = 1000;
std::vector<bool>checkPrime = MakePrimes(limit);
int currentNum = 1;
while (currentNum++ < limit)
{
if (checkPrime[currentNum])
std::cout << currentNum << "\n";
}
return 0;
}
#4 楼
此循环…int currentNum;
currentNum = 2;
do {
if (checkPrime(currentNum)) {
printf("%d ", currentNum);
}
currentNum++;
} while (1 == 1);
…最好写成
for
循环:for (int currentNum = 2; /* TODO: fix overflow */ ; currentNum++) {
if (checkPrime(currentNum)) {
printf("%d ", currentNum);
}
}
出于可读性,
checkPrime()
应该重命名为isPrime()
。它的参数应命名为number
(小写)。您正在使用蛮力试验分割算法。那行得通,但是当您想要包含许多质数的列表时,Eratosthenes的Sieve是一种效率更高的算法。
评论
可以检查素数,无需从2到n循环,只需从2到sqrt(n)的奇数就足够了