自学内容网 自学内容网

c语言简单编程练习8

1、递归函数:

通过调用自身来解决问题的函数,递归也就是传递和回归;

递归函数的两个条件:

1)函数调用函数本身

2)一定要有结束条件

循环与递归的区别:

每调用一次递归函数,都会开辟新的空间地址,所以超过计算机调用的空间地址就会报错,循环只需要开辟局部变量的空间地址,不会出现段错误

结论:循环能做的递归一定能做,递归能做的循环不一定可以做,但是一般能用循环解决的问题就用循环去做

2、用递归函数求一个数的阶乘

#include <stdio.h>
int sum(int n)
{
    if(0==n)
        return 1;
    else
        return n*sum(n-1); //调用自己,每次都乘以形参-1,一直到1,为0返回1
}
int main(int argc, char *argv[])
{
    int i, n;
    printf("请输入一个整数:");
    scanf("%d",&n);
    i = sum(n);
    printf("%d的阶乘为:%d\n",n,i);
}

解析:首先求一个数的阶乘我们需要使用循环,如果是用for循环那么我们一般会让一个变量从1开始自增到目标数字,每次循环都让i去乘以前面的值,这样最后就能得到一个数的阶乘;但是在递归函数里面我们需要一个结束条件,所以在每次调用递归函数我都让传入的参数减去一,这样当传入的数字变为0的时候就结束了循环,下图是递归的一个执行过程:

 

通过这样一个过程我们就能得到5的阶乘了,递归就是一步一步传递下去最后再回归的一个思想,代码运行结果如下:

3、用递归函数统计一个十进制数转为二进制数后二进制中1的个数

#include <stdio.h>
int sum(unsigned int n)
{
    int i=0;
    if(n)
    {
        if(n%2==1)
            i++;
    return i+sum(n/=2);
    }
}
int main(int argc, char *argv[])
{

   unsigned int n;
    printf("请输入一个整数:");
    scanf("%d",&n);
    printf("%d转为二进制后二进制中1的个数为%d\n",n,sum(n));
    return 0;
} 

解析:题目要求是统计转为二进制后其中1的个数,那么我们只需将输入的整数除以2,判断它的余数为不为1,如果为1就计数+1,之后再取除以2之后的商,让这个商再除以2,依次循环,直到商为0为止,最后输出计数的值即可。在递归中如何实现呢,首先我们在调用自己的时候,传进去的参数一定是上一次传入参数除以2之后的商,除此之外,每一次的递归都要加上计数的值,这样我们就得到了返回值的表达式为 i+sum(n/=2);这里的i为计数值。当商为0再传入函数的时候就不会计数和判断了,到这里递归就结束了。

 

4、回调函数

让一个函数和另一个函数具有关联性,允许用户把需要调用的函数的指针作为参数传递给一个函数,以便于该函数在处理相似事件的时候可以灵活的使用不同的方法。这个方法是通过函数指针实现的,在一个函数传参的地方使用一个函数指针来接收另一个函数名,被作为参数传递给另一个函数的函数称为回调函数。

一般用法:在一个函数中,把另一个函数作为参数传递给当前函数,当前函数的形参用函数指针来接收。   例如:

#include <stdio.h>
void x()
{
    puts("111");
}
void y(void (*p)())
{
    p();
    puts("222");
}
int main(int argc, char *argv[])
{
    y(x);
    return 0;
}

解析:代码中的函数x就是一个回调函数,它被作为一个参数传递给了函数y,当我在主函数中调用函数y并且函数y中的参数为x的时候,得到的输出结果就是111,222,如下图所示:

5、malloc函数

动态开辟空间地址,用户在堆区开辟空间地址,最后也要由用户自己释放

例:用malloc函数开辟10个int型大小的空间地址,然后给这10个int地址随机赋值10个数,最后从小到大排序 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
    srand(time(NULL));
    int temp,i,j;
    int *p=(int *)malloc(sizeof(int)*10); //用指针来接收开辟空间的首地址
    if(NULL==p)
    {
        printf("malloc creat failed\n");
        return -1;
    }
    printf("排序前:");
    for(i=0;i<10;i++)   //赋值
    {
        p[i]=rand()%100;
        printf("%d ",p[i]);
    }
    puts("");
    for(i=0;i<9;i++)  //冒泡排序
    {
        for(j=0;j<9-i;j++)
        {
            if(p[j]>p[j+1])
            {
                temp=p[j];
                p[j]=p[j+1];
                p[j+1]=temp;
            }
        }
    }
    printf("排序后:");
    for(i=0;i<10;i++)
    {
        printf("%d ",p[i]);
    }
    puts("");
    free(p); //释放空间
    p=NULL;  //释放指针
    return 0;
} 

解析:这里主要是让宝子们了解malloc函数怎么使用,首先我们需要用一个指针来接收我们开辟的这片空间的首地址;我们开辟的是整型空间地址,因此前面是(int *),我们开辟的是十个整型空间地址,所以是sizeof(int)*10;这一步之后我们就开辟了这个空间地址,当然只是开辟是这样做,到最后有没有开辟成功我们还需要通过判断才能知道;通过判断这个指针p是否为空来判断我们开辟空间是否成功,如果开辟失败则打印提示;在我们使用完这片空间地址之后还需要将它手动释放,也就是free(p);在这里释放的是这片空间,但是指针p还存在,因此我们还需要让这个指针指向NULL,避免它成为一个野指针。

 

 

 


原文地址:https://blog.csdn.net/yyw_17/article/details/143437616

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!