为什么输出是5 4,括号优先级更高也可以在输出语句优先输出吗??
这个代码的运行结果是不确定的(不同编译器输出结果不同)
原因在于,函数参数求值的顺序是编译器未定义行为,也就是说*p++和(*p)++谁先执行,不确定。
printf 的参数 是 从左往右 入栈, 从右往左出栈计算的
所以先 (*p)++ , 括号内取值就是 4,因为++在后,所以结果 为 4 , 然后p指向的第一个元素值 自增,从 4 变为 5
然后算 *p++, 结果 等于 *p, p指向的值现在为 5
最后打印 5 4
A.存在限制条件,当满足这个限制条件的时候,递归便不再继续
B.每次递归调用之后越来越接近这个限制条件
C.递归可以无限递归下去
D.递归层次太深,会出现栈溢出现象
错误的回答是c选项,递归需要两个条件,第一个是必须要有限制条件,每次递归调用时越来越接近这个条件,所以c选项自动排除,不能是死递归,第四个选项,层次太深的话是会出现栈溢出的现象也是对的
int Fun(int n)
{
if(n==5)
return 2;
else
return 2*Fun(n+1);
}
A.2
B.4
C.8
D.16
正确答案为D
传参为2,2不等于5,返回2*fun(3),3不等于5,返回2*fun(4),4不等于5,返回2*fun(5),5等于5,返回2,开始回带,2*fun(2)为4,2*fun(4)为8,2*fun(8)为16,所以最后返回的结果为16
用递归的函数的思想是大事化小,并且有一个限制条件,定义一个数,实现打印函数,如果要打印1234这个数, 1234打印4最好打印,可以分为 (123) 4 (12)3 4 (1)2 3 4
这样就把大事化小了,实现:设定条件,如果大于9,两位数的就拆分,一位数就停下来,,1234/10,调用123,123大于9,123/10,调用12,12大于9,12/10,1,1小于9,开始会带,打印1%10为1,然后2,3,4
#include<stdio.h>
int print(int n)
{
if(n>9)
print( n / 10);
printf("%d", n % 10);
return 0;
}
int main()
{
int n = 0;
scanf("%d", &n);
print(n);
return 0;
}
求n的阶乘有个公式,如果求5的阶乘,那么相当于5*4的阶乘,但是如果是1的时候就不是了,所以实现:当n小于等于1时,返回1,否则返回n*fac(n-1),这件事递归实现,非递归的方式就是利用循环让每个乘积到ret中,最后返回ret就是和
//递归方式
#include<stdio.h>
int fac(int n)
{
if (n <= 1)
return 1;
else
return n* fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fac(n);
printf("%d", ret);
return 0;
}
//迭代方式-非递归
#include<stdio.h>
int fac(int n)
{
int ret = 1;
int i = 0;
for (i = 1; i <= n; i++)
{
ret *= i;
}
return ret;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fac(n);
printf("%d", ret);
return 0;
}
strlen是求字符串的长度,而字符串的长度是由\0来标识的,只要遇到\0就停止,递归实现:如果字符串中不等于\0时,就返回一个1+n+1,因为可以让它指向下一个字符,当等于\0时,返回0,迭代实现,与上面同理,只不过需要定于个ret来接受,如果不等于\0,加加,让字符也加加指向下一个
//递归实现
#include<stdio.h>
int fac(char* n)
{
if (*n != '\0')
return 1 + fac(n + 1);
else
return 0;
}
int main()
{
char arr[] = "abcdef";
int ret = fac(arr);
printf("%d", ret);
return 0;
}
//非递归
#include<stdio.h>
int fac(char* n)
{
int ret = 0;
while (*n != '\0')
{
*n++;
ret++;
}
return ret;
}
int main()
{
char arr[] = "abcdef";
int ret = fac(arr);
printf("%d", ret);
return 0;
}
内容实现:
编写一个函数 reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列,不是逆序打印。
要求:不能使用C函数库中的字符串操作函数。
比如:
char arr[] = "abcdef";
逆序之后数组的内容变成:fedcba
这个题目的要求是将字符串反向打印,而不是逆序,而且不能使用c函数中的字符串操作函数
既然要反向,那么需要交换两个字符的位置,然后打印即可,递归实现:求一个字符串“abcdef”,在字符串里的是abcdef\0,大事化小,先把a放到临时变量里,然后把f放到a里,然后把\0放入f中,让bcde\0变成新的字符串,而调用自己的时候需要设定条件,如果中间剩下一个的时候就不需要交换了,所以大于等于2的时候调用
int my_strlen(char* string)
{
int ret = 0;
while (*string != '\0')
{
ret++;
string++;
}
return ret;
}
void reverse(char* string)
{
int len = my_strlen(string);
char tmp = *string;
*string = *(string+len-1);
*(string + len - 1) = '\0';
if (my_strlen(string + 1) >= 2)
reverse(string + 1);
*(string + len - 1) = tmp;
}
int main()
{
char arr[] = "abcdef";
reverse(arr);
printf("%s", arr);
return 0;
}
内容实现
写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
输入:1729,输出:19
求一个非负整数每个位数之和,如1729可以分成 172 + 9, 17 + 2 + 9 , 1 +7+2+9,递归实现,如果是一位数的时候,返回这个数,如果大于一位数,返回 除以10加上摸10的值,1729/10 172 递归递下去,归回来的每位数加上取余的数
int fac(unsigned int n)
{
if (n > 9)
{
return fac(n / 10) + n % 10;
}
return n;
}
int main()
{
unsigned int n = 0;
scanf("%d", &n);
int sum = fac(n);
printf("%d", sum);
return 0;
}
内容实现
编写一个函数实现n的k次方,使用递归实现。
这是因为数组名和指针的本质不同。
数组名是数组在内存中的起始地址,是一个常量指针,所以不能被修改。
而指针变量是一个变量,可以被赋值修改指向的地址。
所以在代码中,a是一个数组名,指向数组的第一个元素,b是一个指针变量,指向数组的第二个元素。在语句b=a时,b指向的元素被赋值为a所指向的元素,即数组的第一个元素,所以输出b指向的元素时,输出的是数组的第一个元素,即5。在语句b++时,b指向了数组的第三个元素,即4,所以输出b时,输出的是数组的第三个元素,即4。
示例代码:
#include <stdio.h>
int main() {
int a[3] = {5, 3, 4};
int *b = a + 1;
*b = *a;
printf("%d %d", *b, *(b + 1));
return 0;
}