如何更有效地编写程序

时间:2016-10-02 11:18:34

标签: c performance

我写了一个代码,用于添加三个数字并打印它们的总和。有没有一种方法可以更有效地编写此代码,如初始化和引入每个变量。

代码如下:

#include <stdio.h>

int main()
{
  int firstNumber;
  firstNumber = 0;
  printf("Enter firstNumber");
  scanf("%d", &firstNumber);

  int secondNumber;
  secondNumber = 0;
  printf("Enter secondNumber");
  scanf("%d", &secondNumber);

  int thirdNumber;
  thirdNumber = 0;
  printf("Enter thirdNumber");
  scanf("%d", &thirdNumber);

  int sum;
  sum = firstNumber + secondNumber + thirdNumber;
  printf("%d", sum);
}

4 个答案:

答案 0 :(得分:5)

  

可以更有效地编写此代码,例如初始化和引入每个变量。

使用数组:

int numbers[3] = {0};

上面一行定义了三个int并将所有这些内容初始化为0

要访问第一次使用:

numbers[0]

如果出于任何原因,您的代码需要引用“ first ”,“ second ”和“ third ”创建一个枚举来访问数组的元素如下:

enum Numbers
{
  FirstNumber,
  SecondNumber,
  ThirdNumber
}

然后访问第二个数字的源代码可能如下所示:

numbers[SecondNumber]

如果您希望Numbers的大小遵循enum Numbers中的条目数,请修改上述示例,如下所示:

enum Numbers
{
  FirstNumber,
  SecondNumber,
  ThirdNumber,
  MaxNumbers
}

然后定义像

这样的数字
int Numbers[MaxNumbers] = {0};

遵循相同的概念,您现在可以为定义的数字定义用户提示:

const char * prompts[MaxNumbers] = {
  "firstNumber",
  "secondNumer",
  "thirdNumber"
};

现在一切都通过循环输入函数来显着减少源代码行(而不是为每个数字编码或多或少相同的东西):

请继续阅读:

 for (enum Numbers n = 0; n < MaxNumbers; ++n)
 {
   printf("Please enter %s:\n", prompts[n]);
   scanf("%d", &Numbers[n]);
 }

总结:

 int sum = 0;

 for (enum Numbers n = 0; n < MaxNumbers; ++n)
 {
   sum += Numbers[n];
 }

 printf("The sum is: %d\n", sum);

然而,这两个循环可以合并为一个:

 for (enum Numbers n = 0; n < MaxNumbers; ++n)
 {
   printf("Please enter %s:\n", prompts[n]);
   scanf("%d", &Numbers[n]);
   sum += Numbers[n];
 }

作为最后的注释,留给你的学习,请注意scanf()可能会失败。它通过返回值表示这一点。然后,代码可以读取,检测可能的故障并采取相应的行动。

答案 1 :(得分:3)

在大多数编码中,最终程序的效率不如可读性,可维护性和最重要的 - 正确性等因素重要。

你应该首先关注这些事情。只有在生成的程序出现性能问题时,您才应该重新考虑源代码。现代编译器非常擅长优化,因此对于源代码的外观效率而言,它并不重要。

在您的情况下,即从stdin读取的程序,绝对没有理由更改您的代码以获得更高效的程序。

但是,您可以考虑进行更改以获得更好的可维护性。例如,如果您需要更改程序以添加5个值而不仅仅是3个,这有多容易?使用当前代码并不容易。

使用循环可以更容易,例如:

#include <stdio.h>

#define NUMBER_OF_VARS_TO_ADD 3  // Here you decide how many numbers to add

int main()
{
  int j;
  int d = 0;
  int sum = 0;

  for (j=0; j<NUMBER_OF_VARS_TO_ADD; ++j)
  {
      printf("Enter Number: ");
      scanf("%d", &d);     // This is not good - se later
      sum += d;
  }
  printf("Sum: %d", sum);
} 

使用此代码可以很容易地从sum-of-3更改为sum-of-N。这比考虑效率更重要。请注意,此代码不存储从stdin读取的每个值。它只是在读取值时计算总和。

然后正确性很重要。你读取数值的方式并不好。首先,您不检查scanf返回的值。你应该永远这样做!如果用户输入类似5 d 3

的内容,您当前的程序将产生意外结果

当你添加scanf返回的值的检查时,如果scanf没有返回,你很快就会发现需要在scanf之后刷新标准输入1.您需要添加此类代码以确保正确性。再次比考虑效率更重要。

而不是scanf更好/更简单的方法是使用fgetssscanf

答案 2 :(得分:0)

#include <stdio.h>

int main()

{
   int i;    
   int Numbers[3]= {0};
   int sum;
   /*int numberCount; if the count should be dynamic*/
   /*printf("Enter the count of numbers: ");*/
   /*scanf("%d",&numberCount);*/

   for(i=0; i<3;i++)  /*use numberCount instead of 3*/
    {
       printf("Enter Number %d",i);
       scanf("%d", &Number[i]);
       sum += Number[0];
    }
   printf("%d", sum);

}

答案 3 :(得分:0)

我发现使用allways -O3或-Ofast检查https://gcc.godbolt.org生成的代码非常有用。

不改变您的要求(一次询问一个具有完全相同文本的数字)。它最终在intel gcc 6.2上只有两个指令并且使用ARM gcc 4.82它实际上变得更小了:

// Type your code here, or load an example.
#include <stdio.h>

static inline int readNum(const char * const msg)
{
    int num;
    (void)printf(msg);
    (void)scanf("%d", &num);
    return num;
}

int main()

{
  (void)printf("%d", readNum("Enter firstNumber") + readNum("Enter secondNumber") + 
               readNum("Enter tirdNumber"));

}

通过更改规范,我们可以获得更多的好处(在这种情况下,intel和arm都会生成更紧凑的代码)。

// Type your code here, or load an example.
#include <stdio.h>

static inline int readNum(void)
{
    int num;
    (void)printf("Enter a number");
    (void)scanf("%d", &num);
    return num;
}

int main()

{
  (void)printf("%d", readNum() + readNum() + 
               readNum());

}

最后,如果您可以一次询问所有数字。这仅在x86-64 gcc 6.2上生成26行输出,而在原始代码上生成43行。

#include <stdio.h>

int main()

{
    int num1;
    int num2;
    int num3;
    (void)printf("Enter 3 numbers:");
    (void)scanf("%d %d %d", &num1, &num2, &num3);
    (void)printf("%d", num1 + num2 + num3);

}