C 在不同数组中划分并存储商和提醒

C 在不同数组中划分并存储商和提醒,c,C,标准div()函数返回一个div_t struct作为参数,例如: /* div example */ #include <stdio.h> /* printf */ #include <stdlib.h> /* div, div_t */ int main () { div_t divresult; divresult = div (38,5); printf ("38 div 5 => %d, remainder %d.\n",

标准div()函数返回一个div_t struct作为参数,例如:

/* div example */
#include <stdio.h>      /* printf */
#include <stdlib.h>     /* div, div_t */

int main ()
{
  div_t divresult;
  divresult = div (38,5);
  printf ("38 div 5 => %d, remainder %d.\n", divresult.quot, divresult.rem);
  return 0;
}
/*div示例*/
#包括/*printf*/
#包括/*div,div\t*/
int main()
{
div_t divresult;
divresult=div(38,5);
printf(“38 div 5=>%d,余数%d.\n”,divresult.quot,divresult.rem);
返回0;
}
我的情况有点不同;我有这个

#define NUM_ELTS 21433
int main ()
{
  unsigned int quotients[NUM_ELTS];
  unsigned int remainders[NUM_ELTS];
  int i;

  for(i=0;i<NUM_ELTS;i++) {
      divide_single_instruction(&quotient[i],&reminder[i]);
  }
}
#定义数值ELTS 21433
int main()
{
无符号整商[NUM_ELTS];
无符号整数余数[NUM_ELTS];
int i;

对于(i=0;i而言,这里的一般规则是相信您的编译器能够快速完成某些操作。您可以随时反汇编代码并检查编译器是否正在执行某些正常的操作。重要的是要认识到,一个好的编译器对机器的了解非常多,通常比您或我还多

另外,我们假设您有一个很好的理由需要“计算周期”

对于您的示例代码,我同意x86“idiv”指令是一个明显的选择。让我们看看我的编译器(MS visual C 2013)将做些什么,如果我只写出最简单的代码

struct divresult {
    int quot;
    int rem;
};

struct divresult divrem(int num, int den)
{
    return (struct divresult) { num / den, num % den };
}

int main()
{
    struct divresult res = divrem(5, 2);
    printf("%d, %d", res.quot, res.rem);
}
编译器给了我们:

    struct divresult res = divrem(5, 2);
    printf("%d, %d", res.quot, res.rem);
01121000  push        1 
01121002  push        2
01121004  push        1123018h  
01121009  call        dword ptr ds:[1122090h] ;;; this is printf()
哇,编译器比我聪明。Visual C知道除法是如何工作的,所以它只是预先计算了结果并插入了常量。它甚至没有在最终代码中包含我的函数。我们必须从控制台读取整数,以迫使它实际执行计算:

int main()
{
    int num, den;
    scanf("%d, %d", &num, &den);
    struct divresult res = divrem(num, den);
    printf("%d, %d", res.quot, res.rem);
}
现在我们得到:

    struct divresult res = divrem(num, den);
01071023  mov         eax,dword ptr [num]  
01071026  cdq  
01071027  idiv        eax,dword ptr [den]  
    printf("%d, %d", res.quot, res.rem);
0107102A  push        edx  
0107102B  push        eax  
0107102C  push        1073020h  
01071031  call        dword ptr ds:[1072090h] ;;; printf()
你看,编译器(或者至少是这个编译器)已经做了你想做的事情,或者做了一些更聪明的事情


从这一点上,我们学会了信任编译器,当我们知道编译器已经做得不够好时,我们只能对它进行二次猜测。

既然您正在对数组进行适当的写入(用商和余数替换分子和分母),您应该在写入数组之前将结果存储到临时变量中

void foo (unsigned *num, unsigned *den, int n) {
    int i;
    for(i=0;i<n;i++) {
        unsigned q = num[i]/den[i], r = num[i]%den[i];   
        num[i] = q, den[i] = r;
    }
}
在一些更复杂的情况下,在第一次使用商和余数时,它有助于保存它们。例如,在通过试除法测试素数时,您经常会看到这样的循环

for (p = 3; p <= n/p; p += 2)
    if (!(n % p)) return 0;

for(p=3;p)您可以相信您的编译器会找出问题所在。您可以尝试这样做:
商[i]=x/y;余数[i]=x%y;
;随着优化的出现,许多编译器已经可以做你想做的事情了。嗯
div
代码并不复杂:需要多大程度的可移植性?Power PC?SPARC?M680x0?80386?8086?M6502?Z80?@Zboson:看起来你是对的!那么它一定是一段完美的代码;)
for (p = 3; p <= n/p; p += 2)
    if (!(n % p)) return 0;
for (p = 3, q=n/p, r=n%p; p <= q; p += 2, q = n/p, r=n%p)
    if (!r) return 0;