每日练习:函数题6-3 6-4与8-8

习题6-3 使用函数输出指定范围内的完数

题目简介

本题要求实现一个计算整数因子和的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m≤n≤10000)之间的所有完数。所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。

函数接口定义

int factorsum( int number );
void PrintPN( int m, int n );

其中函数factorsum须返回int number的因子和;函数PrintPN要逐行输出给定范围[m, n]内每个完数的因子累加形式的分解式,每个完数占一行,格式为“完数 = 因子1 + 因子2 + … + 因子k”,其中完数和因子均按递增顺序给出。如果给定区间内没有完数,则输出一行“No perfect number”。

函数代码

int factorsum(int number)
{
	int sum = 1;
	int i = 2;

	if(number!=1)
    {
        for (i = 2; i <= sqrt(number); i++)
        {
            if ((number%i) == 0)
            {
                sum = sum + i + (number/i);
            }
        }
        if ((sum == number))
        {
            return number;
        }
    }
	return 0;
}

void PrintPN(int m, int n)
{
	int i = 0;
	int j = 0;
	int tmp = 0;
	int tar = 0;
	int flag = 0;
	for (i = m; i <= n; i++)
	{
		int factor = factorsum(i);
		if (factor == i)
		{
			flag = 1;
			if (i == 1)
			{
				continue;
			}
			else
			{
                printf("%d = ", i);
				for (tmp = 2; tmp <= sqrt(i); tmp++)
				{
					if ((i%tmp) == 0)
					{
						tar = tmp;
						break;
					}
				}
				//printf("flag = %d", flag);
				for (j = 1; j < i; j++)
				{
					if (i%j == 0)
					{
						printf("%d", j);
						if (j < (i / tar))
						{
							printf(" + ");
						}
					}
				}
			}
			printf("\n");
		}
	}
	if (flag == 0)
	{
		printf("No perfect number");
	}
}

#####################################################################

习题6-4 使用函数输出指定范围内的Fibonacci数

题目简介

本题要求实现一个计算Fibonacci数的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m≤n≤10000)之间的所有Fibonacci数。所谓Fibonacci数列就是满足任一项数字是前两项的和(最开始两项均定义为1)的数列。

函数代码

int fib(int n)
{
	int a = 1;
	int b = 1;
	if (n >= 0 && n <= 2)
	{
		return b;
	}
	else
	{
		int i = 0;
		for (i = 3; i <= n; i++)
		{
			int c = a + b;
			a = b;
			b = c;
		}
	}
	return b;
}

void PrintFN(int m, int n)
{
	int i = 0;
	int flag = 0;
	for (i = 1; fib(i) <= n; i++)
	{
		if ((fib(i) >= m) && (fib(i) <= n))
		{
			flag = 1;
			printf("%d", fib(i));
			if (fib(i + 1) <= n)
			{
				printf(" ");
			}
		}
	}
	if (flag == 0)
	{
		printf("No Fibonacci number");
	}
}

#####################################################################

习题8-8 判断回文字符串

题目简介

本题要求编写函数,判断给定的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如“XYZYX”和“xyzzyx”都是回文。

函数代码

bool palindrome(char *s)
{
	int sLen = strlen(s);
	int right = sLen - 1;
	int left = 0;
	while (left <= right)
	{
		if (s[left] != s[right])
		{
			return false;
		}
		else
		{
			left++;
			right--;
		}
	}
	return true;
}

总结

一、在做6-3以及6-4题目时,
先将整体的循环写出来,确保对于大部分的数都适用,之后根据提示信息或者自己的经验,去判断可能在哪些点是特殊点,对这些点进行加入判断操作。
二、在做6-3的判断完数的题目时
(1)当时写完的时候,出现了部分测试点报错的问题,就是提示在最大范围时结果不正确。我上网搜了一下,1不是完数,我在写完整体函数时忘记考虑数字1的影响了。
(2)其实根据函数接口后面的对于每个函数需要完成的功能,我们知道将完数写成因子相加式时,这个 ‘+’ 的录入其实是一个大问题。
而在我写的代码中,
1、我在输出循环之前加了一个循环,用于找到最小因子。

for (tmp = 2; tmp <= sqrt(i); tmp++)
				{
					if ((i%tmp) == 0)
					{
						tar = tmp;
						break;
					}
				}

2、此时拿这个完数除以最小因子就得到了这个完数的最大因子。因此在循环输出时,做一个判断,小于最大因子时,将 ’ + '带上。

for (j = 1; j < i; j++)
{
	if (i%j == 0)
	{
		printf("%d", j);
		if (j < (i / tar))
		{
			printf(" + ");
		}
	}
}

三、关于如何知晓数组的长度
1、对于数组长度

int main()
{
	int count = 0;
	char arr1[] = { 'a','b','c' };
	char arr2[10] = { 'a','b','c' };
	
	//数组个数未知
	printf("%d\n", sizeof(arr1));        //结果是3
	printf("%d\n", sizeof(arr1)/sizeof(arr1[0])); //结果是3
	printf("%d\n", strlen(arr1));       //结果是随机值,因为他要往后去寻找\0的位置

	//数组个数已知
	printf("%d\n", sizeof(arr2));      //结果是10
	printf("%d\n", strlen(arr2));      //结果是3
	while (arr2[count] != '\0')
	{
		count++;
	}
	printf("count = %d\n", count);    //结果是3 
	return 0;
}

(1)当数组大小未知时
说白了就是找不到 ‘\0’ 的位置,当你存入字符时,有多少就存入多少,sizeof(数组名)-数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节,而此时使用strlen(数组名)则会产生错误,因为它判断的依据是往后寻找到 ‘\0’ 的位置结束,但此时就不知道 ‘\0’ 的位置在哪,所以会产生错误
(2)当数组大小已知时,
当开辟好数组之后,这个数组的大小以及元素个数也就确定了。因此使用sizeof(数组名)计算的是整个数组的大小,sizeof(arr1)/sizeof(arr1[0])会得到最大元素个数。
对于strlen(数组名),此时
char arr2[10] = { ‘a’,‘b’,‘c’ }; // 长度为3
上式等价于:(2)char arr2[10] = { ‘a’,‘b’,‘c’ ,’\0’}; // 长度为3
也等价于:(3)char arr2[] = { ‘a’,‘b’,‘c’,’\0’ };// 长度为3
它就能找到 ‘\0’ 的位置,进而将此时数组含有多少元素给显示出来。
当然此时也可以用while循环去判断是否到达 ‘\0’,若到达就结束计数,将此时的计数变量打印出来。
2、对于字符串

int main()
{
	int count = 0;
	char arr1[] = "abcdef";
	char arr2[10] = "abcdef";
	printf("%d\n", sizeof(arr1));//结果是7
	printf("%d\n", sizeof(arr1)/sizeof(arr1[0]));//结果是7
	printf("%d\n", strlen(arr1));//结果是6

	printf("%d\n", sizeof(arr2));//结果是10
	printf("%d\n", strlen(arr2));//结果是6

	while (arr2[count] != '\0')
	{
		count++;
	}
	printf("count = %d\n", count); //结果是6
	return 0;
}

字符串在结尾之时是以 ‘\0’ 结尾的,即char arr1[] = “abcdef”;
等价于char arr1[] = “abcdef\0”;
以下是一些对应解释,理解下面这几句话,也就知晓上面代码为什么执行出来是这样的结果。
(1)、strlen()函数求出的字符串长度为有效长度,既不包含字符串末尾结束符 ‘\0’;
(2)、sizeof()操作符求出的长度包含字符串末尾的结束符 ‘\0’;
(3)、当在函数内部使用sizeof()求解由函数的形参传入的字符数组的长度时,得到的结果为指针的长度,既对应变量的字节数,而不是字符串的长度,此处一定要小心。

如果我讲的还不清楚的话,你们可以去这位博主的这篇博客下去进一步的了解这两者。
博主:wangran51
C语言中,当计算字符数组长度时,用sizeof 和strlen 的原理及两者的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值