打印一个整数的每一位和求阶乘(递归和非递归的C语言实现)

本文探讨了如何递归和非递归方式打印整数,计算阶乘,以及在VS2022环境下处理负数、0和大整数,同时解析了VS输出提示关于IPDB和编译优化的信息,以及%zu格式说明符和_int128在VS中的使用问题。
摘要由CSDN通过智能技术生成

打印一个整数的每一位

思考

负数和0都是整数,我们该如何处理输入的整数是负数和0的情况呢?是在函数里面处理还是在主调函数中处理呢?

递归

void printDigits(int n)//递归方式实现打印一个整数的每一位(主调函数处理0和负整数的情况)
{
	if (n == 0)return;//Base case

	printDigits(n / 10);//Recursive case

	printf("%d\n", n % 10);//Print the last digit
}

非递归

void print_digits(int n)//非递归方式实现打印一个整数的每一位(可以在函数中处理也可以在主调函数处理)
{
	int length = 0;//记录整数的总位数
	while (n > 0)
	{
		length++;
		n /= 10;
	}
	for (; length > 0; length--)
	{
		printf("%d\n", n % 10);
	}
}

求阶乘

递归

//实测VS下int和long能表示的最大阶乘是16!long long是25!_int64(打印的时候用格式化说明符%zu)是65!_int128用不了
int Factorial(int n)//递归实现求n的阶乘(不考虑溢出的问题)
{
	if (n < 0)return 0;//输入非法,阶乘未定义负数
	if (n == 0 || n == 1)return 1;//Base case
	else return n * Factorial(n - 1);//Recursive case
}

非递归

int factorial(int n)//非递归实现求n的阶乘(不考虑溢出的问题)
{
	if (n < 0)return 0;//输入非法,阶乘未定义负数
	int result = 1;
	while (n > 1)result *= n--;
	return result;
}

证明0的阶乘为1

证明0!等于1可以从数学的角度进行推导。一种常见的方法是通过归纳法。
归纳法证明0!等于1:

  1. 基本情况: 当n = 0时,我们需要证明0! = 1,这是基本情况。
  2. 归纳假设: 假设对于某个非负整数 k,k! 等于1成立,即假设归纳假设为真。
  3. 归纳步骤: 现在我们要证明(k + 1)!等于1。根据阶乘的定义:
    (k + 1)! = (k + 1)*k!
    利用归纳假设,我们知道k!等于1。代入这个结果:
    (k+1)!=(k+1)*1=k+1
    因此,我们证明了当k为非负整数时,(k+1)!等于k+1。

结合基本情况和归纳步骤,我们得出结论:对于所有非负整数,n!等于1。这也包括了n=0的情况,因此0!等于1。

写代码中遇到的VS输出窗口提示信息

环境:VS2022,release
提示信息:

Previous IPDB not found,fall back to full compilation
All 8 functions were compiled because no usable IPDB/IOBJ from previous compilation was found
“Previous IPDB not found, fall back to full compilation” 这个消息表明系统无法找到先前生成的增量程序数据库(IPDB),因此正在回退到完整的编译过程。

  1. IPDB 是一个包含信息的文件,通过存储先前编译的数据,加速了编译过程。当找不到现有的 IPDB时,编译器会回到完整的编译过程,这可能需要更多时间。
  2. 这个消息通常出现在开发环境中,不一定表示错误。这更多是在构建过程中的信息性消息。如果在编译过程中遇到任何问题或错误,你可能需要检查你的构建配置。
  3. 这个 Visual Studio 输出窗口的信息表明,所有8个函数都被重新编译,因为在先前的编译中找不到可用的IPDB(Incremental Program Database)或 IOBJ(Intermediate Object)。
  4. 增量编译是一种优化,它只重新编译发生更改的部分,而不是整个程序。IPDB 文件包含了先前编译的信息,可以帮助加速这个过程。IOBJ文件包含中间对象代码。
  5. 在这种情况下,由于找不到可用的 IPDB 或 IOBJ,编译器不得不重新编译所有8个函数,这可能导致编译时间较长。通常情况下,这并不是一个错误,而是一个提示,告诉我们编译过程中的一些细节。
  6. 如果希望加快编译速度,可以检查项目设置,确保启用了适当的编译优化和增量编译选项。此外,确保先前的编译输出和中间文件没有被删除或移动,以供下一次编译使用。

为什么VS平台32位和64位的long都是4字节?

Visual Studio 编译器在 Windows 平台上,无论是32位还是64位,都将long类型定义为4字节。这是由于历史原因和与 Windows API 的兼容性考虑。

在 Windows API 中,long类型通常被定义为4字节,即使在64位系统上也是如此。这是为了确保32位和64位程序之间的二进制兼容性,因为许多Windows API函数在参数和数据结构中使用了 long 类型。

%zu是什么格式说明符

%zu 是 C 语言中用于格式化输出的格式说明符之一。在 printf 函数中,%zu 用于输出 size_t 类型的值。

  • %z 表示以大小为参数的长度修饰符。
  • u 表示无符号整数。

size_t 是无符号整数类型,通常用于表示内存块的大小、数组的索引等。使用 %zu 保证在不同平台上都能正确地输出 size_t 类型的值,因为 size_t 的大小可能在不同系统上有所变化。

VS下_int128为什么用不了

在 C 和 C++ 中,_int128 通常不是标准的整数类型。这可能导致在某些编译器或平台上无法直接使用 _int128。而在一些特定的编译器中,如 GCC,可以使用 __int128 来表示128位整数。

如果在使用 _int128__int128 遇到问题,可能是因为编译器不支持或不提供这个类型。在这种情况下,可能需要考虑使用特定于你的编译器的扩展或其他库,或者考虑使用更通用的库,如 GMP(GNU Multiple Precision Arithmetic Library),它提供了对大整数操作的支持。

PS:使用非标准的扩展可能导致代码在不同的编译器或平台上不可移植。如果需要处理非常大的整数,了解所使用编译器和平台的支持情况,并选择合适的库或方案是很重要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全天

加油,大佬们!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值