考研C语言复习02(小甲鱼版本)

本文介绍了C语言中的递归概念,通过汉诺塔问题解释了递归的运用。同时,讲解了内存管理的基本操作,如malloc、free、calloc、realloc的使用,并探讨了内存泄漏和内存布局。此外,还提到了内联函数、宏定义和结构体等高级主题。
摘要由CSDN通过智能技术生成

递归

//递归必须要有结束条件,否则程序将崩溃
void recursion(void);
void recursion(void){
   
    static int cpunt = 10;
    printf("HI\n");
    
    if (--count){
   
        recursion();
    }
    
}
int main(void){
   
    recursion();
    
    return 0;
}
//递归求阶乘
long fact(int num);
long fact(int num){
   
    long result;
    
    if (num > 0){
   
        result = num * fact(num - 1);
    }
    else{
   
        result = 1;
    }
    return result;
}
int main(void){
   
    int num;
    printf("输入整数:");
    scanf("%d",num);
    
    printf("%d的阶乘:%d\n", num, fact(num));
    
    return 0;
}

实现递归要满足两个基本条件:

①调用函数本身 ②设置了正确的结束条件

汉诺塔

问题描述:

x、y、z三根针,64个圆盘在x针上,需将64个圆盘都移动至z针上,且每次只能移动一个圆盘,移动过程中大的圆盘一定要在小圆盘的下面

解析:

对于游戏的玩法,我们可以简单分解为三个步骤:

①将前63个盘子从X移动到Y上

②将最底下的第64个盘子从X移动到Z上

③将Y上的63个盘子移动到Z上

再拆成两个问题:

(1)问题一:将X上的63个盘子借助Z移动到Y上:

——①将前62个盘子从X移动到Z上

——②将最底下的第63个盘子移动到Y上

——③将Z上的62个盘子移动到Y上

(2)问题二:将Y上的63个盘子借助X移动到Z上:

——①将前62个盘子从Y移动到X上

——②将最底下的第63个盘子移动到Z上

——③将X上的62个盘子移动到Y上

void hanoi(int n, char x, char y, char z);
//x, y, z这三个,按顺序可以简单理解为x借助y移动到z
void hanoi(int n, char x, char y, char z){
   
    if (n==1)//当只有一个圆盘时
    {
   
        printf("%c --> %c\n", x, z);
    }
    else{
   
        //把除了最下面那一层的其他所有圆盘(n-1)层借助z移动到y
        hanoi(n-1, x, z, y);
        
        //手动移动最底下的大圆盘到z
        printf("%c --> %c\n", x, z);
        
        //剩下的圆盘从y借助x移动到z
        hanoi(n-1, y, x, z);
    }
}
int main(void){
   
    int n;
    printf("汉诺塔层数:");
    scanf("%d", &n);
    
    hanoi(n, 'X', 'Y', 'Z');
    return 0;
}

分治法

快速排序

快速排序算法的基本思想是:通过一趟排序将待排序数据分割成独立的两部分,其中一部分的所有元素均比另一部分的元素小,然后分别对这两部分继续进行排序,重复上述步骤直到排序完成。

void quick_sort(int array[], int left, int right){
   
    int i = left, j = right;
    int temp;
    int pivot;
    
    pivot = array[(left + right) / 2];
    
    while (i <= j){
   
        //从左到右找到大于等于基准点的元素
        while (array[i] < pivot){
   
            i++;
        }
        //从右到左找到小于等于基准点的元素
        while (array[j] > pivot){
   
            j--;
        }
        //如果i <= j,则互换
        if (i <= j){
   
            temp = array[i];
            array[i] = array[j];
            array[j] = temp;
            i++;
            j--;
        }
    }
    if (left < j){
   
        quick_sort(array, left, j);
    }
    if (i < right){
   
        quick_sort(array, i, right);
    }
}

int main(void){
   
    int array[] = {
   73, 108, 111, 118, 101, 70, 115, 104, 67, 46, 99, 111, 109};
    int i, length;
    
    length = sizeof(array) / sizeof(array[0]);
    quick_sort(array, 0, length-1);
    
    printf("排序后:")
    for (i = 0; i < length; i++){
   
        printf("%d", array[i]);
    }
    putchar('\n');
    
    return 0;
}

更灵活的内存管理方式

malloc:申请动态内存空间

free:释放动态内存空间

calloc:申请并初始化一系列内存空间

realloc:重新分配内存空间

malloc

函数原型:void *malloc(size_t size);

malloc函数向系统申请分配size个字节的内存空间,并返回一个指向这块空间的指针

如果函数调用成功,返回一个指向申请的内存空间的指针,由于返回类型是void 指针 (void *),所以它可以被转换成任何类型的数据;如果函数调用失败,返回值是NULL。另外,如果size参数设置为0,返回值也可能是NULL,但这并不意味着函数调用失败。

#include <stdlib.h>
int main(){
   
    int *ptr;
    
    ptr = (int *)malloc(sizeof (int));
    if (ptr == NULL){
   
        printf("分配内存失败\n");
        exit(1);
    }
    
    printf("输入一个整数");
    scanf("%d", ptr);
    
    printf("输入的整数是:%d\n", *ptr);
    
    return 0;
}

malloc还可以申请一块任意尺寸的内存空间

#include <stdlib.h>

int main(void){
   
    int *ptr = NULL;
    int num, i;
    
    printf("请输入带录入整数的个数:");
    scanf("%d", &num);
    
    ptr = (int *)malloc(num * sizeof(int));
    for (i = 0; i < num; i++){
   
        printf("请录入第%d个整数:", i+1);
        scanf("%d", &ptr[i]);
    }
    
    printf("你录入的整数是:")for (i = 0; i < num; i++){
   
        printf("%d", ptr[i]);
    }    
    putchar('\n');
    free(ptr);
    
    return 0;
}

free

函数原型:void free(void *ptr);

free函数释放ptr参数指向的内存空间。该内容空间必须是由malloc、calloc或realloc函数申请的。否则,该函数将导致未定义行为。如果ptr参数是NULL,则不执行任何操作。注意:该函数并不会修改ptr参数的值,所以调用后它仍然指向原来的地方(

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值