C语言学习记录(六)——递归、数组

一、递归

什么是递归?
  ①程序调用自己本身
  ②要有终止条件
递归的方式主要思考方式在于:把大事化小

例1:接受一个整型值(无符号),按照顺序打印出它的每一位。例如:输入1234,输出 1 2 3 4

void print(int n){
	if (n > 9){
		printf(n / 10);
	}
	printf("%d ", n % 10);

}
int main(){
	int num = 1234;
	print(num);
	return 0;
}

例2:编写函数不允许创建临时变量,求字符串长度。

//递归方式
int MyStrlenD(const char*str){
	if (*str == '\0'){
		return 0;
	}
	else{
		return 1 + MyStrlenD(str + 1);
	}
}
//循环方式
1. 给一个计数,用来统计有效字符的个数
2. 遍历字符串,只要没有遇到\0, 遇到一个字符给计数加1,直到遇到\0
int MyStrlenX(char str[]){
	int size = 0;
	for (int i = 0; str[i] != '\0'; i++){
		size++;
	}
	return size;
}
int main(){
	char *p = "abcdef";
	int len1 = MyStrlenD(p);
	int len2 = MyStrlenX(p);
	printf("%d\n%d\n", len1, len2);
	return 0;
}

例3、求n的阶乘(不考虑溢出)

int FacD(int n){
	if (n == 1){
		return 1;
	}
	int ret = n * FacD(n - 1);
	return ret;
}
int FacX(int n){
	int ret = 1;
	for (int i = 1; i <= n; i++){
		ret *= i;
	}
	return ret;
}
int main(){
	printf("%d\n%d\n", FacD(5), FacX(5));
}

例4、求第n个斐波那契数。(不考虑溢出)

int fib(int n){
	if (n <= 2)
		return 1;
	else
		return fib(n - 1) + fib(n - 2);
}
int main(){
	printf("%d\n", fib(10));
}

但这种方法计算位数多时将非常耗费时间。
解决方法:将递归改写为非递归。

int FibX(int n)
{
	if (n <= 0){
		return -1;
	}
	int f1 = 1;
	int f2 = 1;
	int f3 = 1;
	for (int i = 3; i <= n; i++){
		f3 = f1 + f2;
		f1 = f2;
		f2 = f3;
	}
	return f3;
}
int main(){
	printf("%d\n", FibX(30));
}

例5、汉诺塔

1:  A -> C                                               1
2:  A->B   A -> C  B->C                                  3
3:  A -> C   A->B    C->B    A->C  B->A  B->C  A -> C    7
4:        2^4-1                                          15
.......     ......                ............          ..
64 :     2^64                                            -1   
void Move(char pos1,char pos2)
{
	printf("%c -> %c ",pos1,pos2);
}

//pos1:起始位置   pos2:过度位置    pso3:目标位置
void HanoTa(int n,char pos1,char pos2,char pos3)
{
	if (n == 1) 
	{
		Move(pos1, pos3);
		return;
	}
	HanoTa(n - 1, pos1, pos3, pos2);
	Move(pos1, pos3);
	HanoTa(n - 1, pos2, pos1, pos3);
}

二、数组

  数组的创建:

// 创建方法1
int arr1[10];      //定义了一个未赋值的整型数组,局部变量会存放的是随机值;若是全局变量则存放0;

//创建方法2
int arr2[10] = { } //在给括号里赋值时,是一位一位的赋值;

注意:在数组创建中,[]中要给一个常量才可以,不能使用变量。
在C语言中使用const int i = 10这种方法定义的是为“变常量”,在C++中为常量。

int arr1[10]  = {1,2,3};        // [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
int arr2[]    = {1, 2, 3, 4};   // [1, 2, 3, 4]
int arr3[5]   = {1, 2, 3, 4, 5} // [1, 2, 3, 4, 5]
char arr4[3]  = {'a', 98, 'c'}  // [a, b, c]
char arr5[]   = {'a', 'b', 'c'} // [a, b, c]
char arr6[]   = "abcdef"        //[a, b, c, d, e, f, \0]
一维数组的使用
#include<stdio.h>
int main(){
	int arr[10] = { 0 }; //数组不完全初始化
	//计算数组的元素个数
	int size = sizeof(arr) / sizeof(arr[0]);
	//对数组内容赋值,数组是使用下标来访问的,下标从0开始
	int i = 0; //下标
	for (i = 0; i < 10; i++){
		arr[i] = i;
	}
	//输出数组的内容
	for (i = 0; i < 10; ++i){
		printf("%d\n", arr[i]);
	}
	return 0;
}

注意
  当我们计算数组大小时,尽量将数组长度的计算放在main函数中,使其作为实参传递给函数中。
  当以函数的形式定义数组是,形参所定义的数组名表示的是数组首元素的地址,所以如果在函数中对数组大小进行sizefof()计算,会因为计算的是地址大小,所以指针的大小会返回为4。

关于栈上的存放

  局部变量是存放在栈上的,栈有两种特点:
①先进后出
②增长方向为:高地址到低地址进行增长,大小一般为1~2M
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值