C 在不同数组中划分并存储商和提醒
标准div()函数返回一个div_t struct作为参数,例如: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 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("ient[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;