哪一种更干净的方法可以做到这一点? 我学习C++,我想制作干净的可读代码。我想知道哪条路更好?(这应该是9的阶乘)

哪一种更干净的方法可以做到这一点? 我学习C++,我想制作干净的可读代码。我想知道哪条路更好?(这应该是9的阶乘),c++,C++,第一种方法: int main(){ int i = 1,r = i; while (i < 10) { r *= ++i; } } intmain(){ int i=1,r=i; 而(i

第一种方法:

int main(){
    int i = 1,r = i;
    while (i < 10) {
       r *= ++i;
    }
}
intmain(){
int i=1,r=i;
而(i<10){
r*=++i;
}
}
第二种方法:

int main(){
    int i = 1,r = i;
    while (i < 10) {
       i++;
       r *= i
    }
}
intmain(){
int i=1,r=i;
而(i<10){
i++;
r*=i
}
}

第一条可能更难理解,但它少了一行。值得吗?性能如何?显然,在这样一个简单的例子中,这并不重要,但从一开始就快速编写代码是一个很好的做法。

虽然
不能简单得多,但您始终可以切换到
进行

int r = 1;

for (int i = 1; i <= 10; i++) {
   r *= i;
}
intr=1;

对于(inti=1;i个人而言,在这两个函数中,我会使用第一个函数;它可读且清晰。如果要使用第二个函数,不管怎样,在独立行中使用前缀increment(++i);在一般情况下,它稍微快一点(忽略潜在的编译器优化)

另外,在这种情况下,我可能会使用for循环——我假设您不使用for循环是有原因的

对于这一点,没有一个好的通用规则——如果行中有更多的操作和函数调用等,它就会变得太复杂。随着经验的增加,你会对复杂性和简洁性有一个很好的感觉

最后,在编写代码时,我不会担心像这样的微优化,特别是如果您只是在学习。

intfactorial(intn){
int factorial(int n) {
   int product = 1;
   for (int i = 1; i <= n; i++) {
      product *= i;
   }
   return product;
}
int乘积=1; 对于(inti=1;i
intmain(){
int i=1,r=i;
而(i++<10){
r*=i;
} 

忘了一些分号。

你可以更紧凑一点,甚至

int main() {
  int i = 10, r = 1;
  while (--i) r *= i;
}

这不是个好主意。

第二个,毫无疑问


主要是因为如果你在调试代码,你总是怀疑行
r*=++i;
是错误的。

我认为其他答案是编写清晰易读代码的更好例子,但是如果你必须有与你发布的原始代码非常相似的东西,这可能是一个更干净的选择

int main()
{
    int answer = factorial(10);
}

int factorial(int n)
{
    if (n == 1) return 1;
    return n * factorial(n-1);
}
int main(){
    int r, i = r = 1;
    while (i++ < 10) {
       r *= i;
    }
}
intmain(){
int r,i=r=1;
而(i++<10){
r*=i;
}
}
在我看来,与赋值相结合的递增前和递增后运算符是最难解析的代码结构之一。条件中的递增前和递增后运算符要常见得多。

更喜欢++i而不是i++

++i递增并返回新值 i++执行两个步骤,创建一个临时值,增加该值并返回临时旧值

因此,在可以使用++i的一般用法中,代码将更易于理解。 您的两个示例都可以使用++i,因此差别不大

当您有类似于for-each的简单循环时,请选择for-to

for (int i = 2, r=1; i <= 10; ++i) {
  r *= i
}

for(int i=2,r=1;i为什么不在while循环中折叠预期的数字?对我来说最重要的是代码的可读性,因为其他人稍后会回来,必须弄清楚它。此外,阶乘很快就会变大,所以你可能需要使用长的。试着使用最好的类型来完成这项工作

long main() {
    return factorial( 10 );
}

long factorial( int n ) {
    long ans = (long) n;

    // error checking here
    if (n <= 0) { return -1; }
    while (n-- > 0) {
        ans *= n;
    }
long main(){
收益因子(10);
}
长阶乘(整数n){
长ans=(长)n;
//在此处检查时出错
if(n0){
ans*=n;
}

正如其他人所指出的,尽量不要编写“智能代码”,而要编写“可理解的代码”。msw给出的解决方案非常好,因为变量的名称显示了它的用途。

方法#1,受某些调试工具的限制

紧凑的代码应该是首选,问题是您无法在许多流行的廉价调试工具上调试聚合语句。这通常会使您中断长表达式、提取变量等


对于像这样的简单代码,紧凑性真的很重要。你可以在这里看到一些动机:

是的,我肯定更喜欢这个问题的for循环,但是如果你不先初始化它,r*=不会抛出异常吗?@jboyd:它不会抛出异常,r只会有垃圾。@jboyd@Ferruccio:
r
会被忽略未初始化,当您使用它时,您会得到未定义的行为。后缀增量是不必要的,只要您不需要后缀的副本,就始终使用前缀。但是+1用于,更易于阅读。@wds prefix不是关于优化,而是关于减少副作用。从一开始就快速重新编程:过早优化是所有邪恶和许多错误的根源。当你在做的时候,你短了一些分号和一个右大括号。编译器不在乎你用了多少行。多键入几分钟以增加清晰度将节省未来数小时和数天的调试时间。@Thomas:那么你建议使用2?我想在编译器优化时,它们应该在e同样的速度是的。除非你有积极的理由,否则你不应该试图超越你的编译器。谢谢,我担心第一个不是那么可读,而a for是个好主意,我的书只是用了一段时间,这就是为什么我会这样发布。Cory,
++I
是前缀增量,因为操作符是操作数的前缀。
I++
Is后缀增量。另外一个非常好的点,+1来自我。。大多数人从在
int
上使用
i++
开始,忘记了当
i
是一些用户定义的类型时,这可能会影响性能。感谢您修复我的打字错误;这就是我在编译之间转储随机建议的原因。:)我想说的是,前缀增量最重要的一点不是优化,而是良好的风格和减少副作用。当使用后缀时,你会创建一个副本。事实上。代码应该先为人编写,然后为计算机编写。如果我可以的话,我想给它一个+10。我甚至没有看到该代码是一个迭代的事实这表明名字很有关联。我最喜欢这个名字,尽管我对两个名字都投了赞成票
long main() {
    return factorial( 10 );
}

long factorial( int n ) {
    long ans = (long) n;

    // error checking here
    if (n <= 0) { return -1; }
    while (n-- > 0) {
        ans *= n;
    }