例:阶乘
无符号整型数永远不可能为负值,所以不能使用return -1;来返回函数调用值。解决方法:直接在主函数中判断输入的值是否满足要求。
如果将实参值-1传给形参,实际是将-1的二进制表示中的最高位(符号位)1解释成了数据位,从而将有符号整数-1解释成了无符号4字节整数。
unsigned long Fact(unsigned int n);
int main(void)
{
int m;
do
{
printf("Input m(m>0):");
scanf("%d", &m);
} while (m < 0);
printf("%d!=%lu\n", m, Fact(m));
system("pause");
return 0;
}
unsigned long Fact(unsigned int n)
{
unsigned int i;
unsigned long result = 1;
for (i = 2; i <= n; i++)
result *= i;
return result;
}
例7.4
unsigned long Fact(unsigned int n);
int main(void)
{
int m, k;
unsigned long p;
do
{
printf("Input m,k(m>k>0):");
scanf("%d %d", &m, &k);
} while (m < k || m <= 0 || k < 0);
p = Fact(m) / (Fact(k)*Fact(m - k));
printf("p=%lu\n", p);
system("pause");
return 0;
}
unsigned long Fact(unsigned int n)
{
unsigned int i;
unsigned long result = 1;
for (i = 2; i <= n; i++)
result *= i;
return result;
}
例:递归求阶乘
long Fact(int n);
int main(void)
{
int n;
long result;
printf("Input n:");
scanf("%d", &n);
result = Fact(n);
if (result == -1)
printf("data error!\n");
else
printf("%d!=%ld\n", n, result);
system("pause");
return 0;
}
long Fact(int n)
{
if (n < 0)
return -1;
else if (n == 0 || n == 1)
return 1;
else
return (n*Fact(n - 1));
}
例:Fibonacci数列
long Fib(int n);
int main(void)
{
int n,x;
printf("Input n:");
scanf("%d", &n);
for (int i = 1; i <= n;i++)
{
x = Fib(i);
printf("Fib(%d)=%d\n", i, x);
}
system("pause");
return 0;
}
long Fib(int n)
{
if (n == 1)
return 1;
else if (n == 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
7.1(static、for循环重要知识点!)
for循环内部({}内)可以定义与外部相同变量的值,但出了}就会死亡,除非使用static定义,内部的i值不会变,但也不会干涉到外部!而for的循环条件取决于外部定义的i!!!!!!!!!!!!
static:仅在第一次调用函数时被初始化,其占据的内存不会在退出函数时被释放。
int Square(int i)
{
return i*i;
}
int main(void)
{
int i = 0;
i = Square(i);
for (; i < 3; i++)
{
static int i = 1;
i += Square(i);
printf("%d,", i);
}
printf("%d\n", i);
system("pause");
return 0;
}
7.2:模拟时钟、延时
\r为回车但不换行,以此模拟数字时钟
以循环体为空语句的循环实现延时
int hour, minute, second;
void Update()
{
second++;
if (second == 60)
{
second = 0;
minute++;
}
if (minute == 60)
{
minute = 0;
hour++;
}
if (hour == 24)
hour = 0;
}
void Display()
{
printf("%2d:%2d:%2d\r", hour, minute, second);
}
void Delay()
{
int t;
for (t = 0; t < 100000000; t++);
}
int main(void)
{
int i;
hour = minute = second = 0;
for (i = 0; i < 1000000; i++)
{
Update();
Display();
Delay();
}
system("pause");
return 0;
}
7.4:最大公倍数
LCM函数的返回值应是int而不是void
选择合适的数学模型:除了如下方法,还可:for(i=1;i<b;i++){if(i*a%b==0) return i*a;} return b*a;
提高程序的健壮性
int LCM(int a, int b)
{
int i;
if (a <= 0 || b <= 0)
return -1;
for (i = (a > b ? a : b); ; i++)
{
if (i%a == 0 && i%b == 0)
return i;
}
}
int main(void)
{
int a, b,x;
printf("Input a,b:");
scanf("%d %d", &a, &b);
x = LCM(a, b);
if (x == -1)
printf("Input error!\n");
else
printf("LCM=%d\n", x);
system("pause");
return 0;
}
7.7:最大公约数
(1)穷举
int Gcd(int a, int b)
{
int i;
if (a <= 0 || b <= 0) return -1;
for (i = (a < b ? a : b);; i--)
{
if (a%i == 0 && b%i == 0)
return i;
}
}
int main(void)
{
int a, b,x;
printf("Input a,b:");
scanf("%d %d", &a, &b);
x = Gcd(a, b);
if (x == -1)
printf("Input error!\n");
else
printf("GCD=%d\n", x);
system("pause");
return 0;
}
(2)欧几里得算法(辗转相除法)
int Gcd(int a, int b)
{
int r;
if (a <= 0 || b <= 0) return -1;
do
{
r = a%b;
if (r != 0)
{
a = b;
b = r;
}
} while (r != 0);
return b;
}
or
int Gcd(int a, int b)
{
int r;
if (a <= 0 || b <= 0) return -1;
if (a%b == 0)
return b;
else
return Gcd(b, a%b);
}
(3)递归法(思想见课本)
int Gcd(int a, int b)
{
if (a <= 0 || b <= 0) return -1;
if (a == b)
return a;
else if (a > b)
return Gcd(a - b, b);
else
return Gcd(a, b - a);
}
7.13:素数
(1)1、采用goto、break不用走完整个循环!
int IsPrime(int m)
{
int i;
if (m < 2) return 0;
for (i = 2; i < m; i++)
{
if (m%i == 0)
goto End;
}
End:return i < m ? 0 : 1;
}
int main(void)
{
int m;
printf("Input m:");
scanf("%d", &m);
if (IsPrime(m))
printf("%d is a prime number\n", m);
else
printf("%d is Not a prime number\n", m);
system("pause");
return 0;
}
(2)1、(int)sqrt(x):强制类型转换成整数,去掉小数部分
int IsPrime(int m)
{
int i;
int squareRoot = (int)sqrt(m);
if (m < 2) return 0;
for (i = 2; i <=squareRoot; i++)
{
if (m%i == 0)
return 0;
}
return -1;
}
(3)
int main(void)
{
int m,i=1,sum=0;
printf("Input m:");
scanf("%d", &m);
while (i <= m)
{
if (IsPrime(i))
{
printf("%d\t", i);
sum += i;
}
i++;
}
printf("\nsum=%d\n", sum);
system("pause");
return 0;
}
(4)1、设置标记isFirstFactor在数之间加逗号,第一个和最后一个不加
int main(void)
{
int m,i,isFirstFactor=1;
printf("Input m:");
scanf("%d", &m);
if (IsPrime(m))
printf("No divisor!It is a prime number!\n");
else
{
for (i = 2; i < m; i++)
{
if (m%i == 0)
{
if (isFirstFactor == 0)
printf(",");
printf("%d", i);
isFirstFactor = 0;
}
}
printf("\n");
}
system("pause");
return 0;
}
(5)
int IsPerfect(int m);
int main(void)
{
int m;
printf("Input m:");
scanf("%d", &m);
if (IsPerfect(m))
printf("It is a perfect number\n");
else
printf("It is Not a perfect number\n");
system("pause");
return 0;
}
int IsPerfect(int m)
{
int i,sum=0;
for (i = 1; i < m; i++)
{
if (m%i == 0)
sum += i;
}
return sum == m ? 1 : 0;
}
(6)!!!!!!细节
int IsPrime(int m);
void Print(int m);
int main(void)
{
int m;
printf("Input m:");
scanf("%d", &m);
if (IsPrime(m))
{
Print(m);
}
else
printf("It is a prime number\n");
system("pause");
return 0;
}
void Print(int m)
{
int i=2,IsFirst=0,n;
printf("%d=", m);
n = m;
do
{
if (n%i == 0)
{
n = n / i;
if (IsFirst == 1) printf("*");
printf("%d", i);
IsFirst = 1;
}
else
i++;
} while (n > 1);
printf("\n");
}
or:递归调用!!!!!
void Print(int m)
{
int i;
for (i = 2; i < m; i++)
{
if (m%i == 0)
{
printf("%d*", i);
Print(m / i);
return;
}
}
printf("%d", m);
}
7.14:计算机辅助教学
(1)
int CreateRan(void);
int main(void)
{
int x, y, answer;
srand(time(NULL));
x = CreateRan();
y = CreateRan();
printf("%d*%d=?\n", x, y);
do
{
scanf("%d", &answer);
if (answer == x*y)
printf("Right!\n");
else
printf("Wrong!Do it again\n");
} while (answer != x*y);
system("pause");
return 0;
}
int CreateRan(void)
{
return rand() % 10 + 1;
}
(3)1、老生常谈:count/10=0!!!!!!!!!!!!!!!!!要转换成浮点
2、输出百分号是用:%%,而不是\%
int CreateRan(void);
int main(void)
{
int x, y, answer,count=0,i;
srand(time(NULL));
for (i = 1; i <= 10; i++)
{
x = CreateRan();
y = CreateRan();
printf("%d*%d=?\n", x, y);
scanf("%d", &answer);
if (answer == x*y)
{
printf("Right!\n");
count++;
}
else
printf("Wrong!\n");
}
printf("Scores=%d,Accuracy=%d%%\n", count * 10, count*10);
system("pause");
return 0;
}
int CreateRan(void)
{
return rand() % 10 + 1;
}
(4)
int CreateRan(void);
char CreateOp(void);
int Calculate(int x, int y, char op);
int main(void)
{
int x, y, answer,count=0,i;
char op;
srand(time(NULL));
for (i = 1; i <= 10; i++)
{
x = CreateRan();
y = CreateRan();
op = CreateOp();
printf("%d%c%d=?\n", x, op,y);
scanf("%d", &answer);
if (answer == Calculate(x,y,op))
{
printf("Right!\n");
count++;
}
else
printf("Wrong!\n");
}
printf("Scores=%d,Accuracy=%d%%\n", count * 10, count*10);
system("pause");
return 0;
}
int CreateRan(void)
{
return rand() % 10 + 1;
}
char CreateOp(void)
{
int op;
op = rand() % 4 + 1;
switch (op)
{
case 1:return '+';
case 2:return '-';
case 3:return '*';
case 4:return '/';
default:return 0;
}
}
int Calculate(int x, int y, char op)
{
switch (op)
{
case '+':return x + y;
case '-':return x - y;
case '*':return x*y;
case '/':return x / y;
default:printf("Error!\n");
return 0;
}
}
(5)增加do-while循环,可用flag做标记!!!!!!!
(6)类似CreateOp,使用switch-case函数增加多样性!