学习记录——day09

day08作业解析

#include<myhead.h>
#define MAX 100             //能够容纳的总人数
int size = 0;                    //实际使用的个数

//定义录入学生信息函数
void do_insert(char name[][20], int score[])
{
    //实际学生人数的录入
    printf("请输入要录入学生的个数:");
    scanf("%d", &size);
    getchar();

    //循环录入学生信息
    for(int i=0; i<size; i++)
    {
        printf("请输入第%d个学生的姓名:", i+1);
        scanf("%s", name[i]);
        printf("请输入第%d个学生的分数:", i+1);
        scanf("%d", &score[i]);
        printf("\n");
    }

    printf("录入成功\n");

}

//定义展示学生信息函数
void do_show(char name[][20], int score[])
{
    printf("目前的学生信息如下:\n");
    printf("\t姓名\t成绩\n");
    for(int i=0; i<size; i++)
    {
        printf("\t%s\t%d\n", name[i], score[i]);
    }

}

//定义按姓名排序函数
void do_sort_name(char name[][20], int score[])
{
    //定义交换变量
    char temp_name[20] = "";       //名字
    int temp_score = 0;            //成绩

    //排序
    for(int i=1; i<size; i++)
    {
        for(int j=0; j<size-i; j++)
        {
            if(strcmp(name[j], name[j+1]) > 0)
            {
                //交换姓名
                strcpy(temp_name, name[j]);
                strcpy(name[j], name[j+1]);
                strcpy(name[j+1], temp_name);

                //交换成绩
                temp_score = score[j];
                score[j] = score[j+1];
                score[j+1] = temp_score;
                    
            }
        }
    }

    printf("排序成功\n");
}



/*****************主程序*******************/
int main(int argc, const char *argv[])
{
    //定义学生姓名数组
    char name[MAX][20] = {""};       //姓名数组
    int score[MAX] = {0};            //分数数组


    //制作菜单
    int menu = 0;
    while(1)
    {
        printf("\t\t======XXX 班级学生管理系统========\n");
        printf("\t\t 1、录入学生信息\n");
        printf("\t\t 2、查看学生信息\n");
        printf("\t\t 3、最佳学生信息\n");
        printf("\t\t 4、按姓名排序学生信息\n");
        printf("\t\t 5、按成绩排序学生信息\n");
        printf("\t\t 0、退出\n");
        printf("请输入功能:");
        scanf("%d", &menu);
        getchar();

        //多分支选择
        switch(menu)
        {
        case 1:
            {
                //完成录入功能
                do_insert(name, score);
            }
            break;
        case 2:
            {
                //完成查看功能
                do_show(name, score);
            }
            break;
        case 3:
            {
                //完成查看最佳功能
                //do_mvp(name, score);
            }
            break;
        case 4:
            {
                //完成姓名排序功能
                do_sort_name(name, score);
            }
            break;
        case 5:
            {
                //完成成绩排序功能
                //do_sort_score(name, score);
            }
            break;
        case 0: exit(0);         //退出程序
        default:printf("您输入的功能有误,请重新输入\n");

        }

    }


    
    return 0;
}

函数

值传递和地址传递(非常重要)

值传递

        值传递的过程中形参和实参操作的不是同一空间

        当普通变量作为函数参数传递时(不涉及地址),是单向的值传递,仅仅是将实参的值赋予形参,形参的改变,不影响实参。

#include <stdio.h>

void swap_1(int m,int n)
{

    int temp = m;
    m = n;
    n = temp;

    printf("交换后 m = %d, n = %d",m,n);
}
int main()
{
    int num = 520;
    int key = 1314;

    swap_1(num,key);
    printf("交换后 num = %d, key = %d",num,key);
}

地址传递

        地址传递的过程中形参和实参操作的是同一空间

        当实参传递的是数组名、指针或变量的地址(&num)时,可以理解为地址传递

        形参对空间内存进行改变时,实参也跟着改变

#include<myhead.h>

//定义冒泡排序函数
void sort_up(int brr[], int n)
{
    printf("sizeof(brr) = %ld\n", sizeof(brr));   //返回 8  为指针大小
    //进行冒泡排序
    for(int i=1; i<n; i++)
    {
        for(int j=0; j<n-i; j++)
        {
            if(brr[j] > brr[j+1])
            {
                int temp = brr[j];
                brr[j] = brr[j+1];
                brr[j+1] = temp;
            }
        }
    }
    printf("排序结束\n");
}



/****************主程序********************/
int main(int argc, const char *argv[])
{
    //定义一个一位数组并初始化
    int arr[5] = {2,8,1,6,7};
    printf("sizeof(arr) = %ld\n", sizeof(arr));    //20

    //调用冒泡排序函数,完成升序排序
    sort_up(arr, 5);

    //输出排序后的结果
    printf("排序后:");
    for(int i=0; i<5; i++)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");

    return 0;
}

递归函数

递归:一个函数以直接或间接的形式调用自身

函数可以调用自己

死递归

无出口

#include <stdio.h>
void say_story()
{
    printf("从前有座山山里有座庙,庙里有个老和尚给小和尚讲故事,故事里说:");

    say_story();
}

int main()
{

    say_story();
    return 0;
}

段错误:内存不足

递归条件

递归出口:用于终止递归的条件

递归表达式:能够让递归继续进行的函数调用

递归思想

        当直接解决规模比较大的问题不能进行时,需要先解决规模较小的原理一致的问题后,大的问题得以解决时,可以考虑使用递归(逐层分解,逐层合并)

例:

求n的阶乘

#include <stdio.h>
int jieCheng(int n)
{
    if(n==0)
    {
        return 1;//递归出口
    }else
    {
        return n*jieCheng(n-1);//递归表达式
    }
}
int main()
{
    int n = 0;
    printf("输入一个数:");
    scanf("%d",&n);
    int s = jieCheng(n);
    printf("该数的阶乘为:%d\n",s);
    return 0;
}

存储位置:栈

栈:先进后出   先存入的后执行

执行完后,释放空间

使用递归输出第n项的斐波那契数

#include <stdio.h>
int fbnq_sl(int n)
{
    if(n<=2)
    {
        return 1;
    }else
    {
        return fbnq_sl(n-1)+fbnq_sl(n-2);
    }


}


int main()
{
    int n = 0;
    scanf("%d",&n);
    int a = fbnq_sl(n);
    printf("斐波那契数的第%d项,为%d\n",n,a);
    return 0;
}

使用递归函数实现,输入一个数,输出该数据的每一位

#include <stdio.h>
void qu_weishu(int a)
{
    if(a/10==0)
    {
        printf("%d\t",a);
    }else
    {
        printf("%d\t",a%10);

        qu_weishu(a/10);
    }
}
int main()
{
    int n = 0;
    scanf("%d",&n);
    qu_weishu(n);
    putchar(10);
    return 0;
}

 

指针

指针 内存地址编号(不好记)

指针变量 定义一个变量用于存储指针(自己定义,方便记忆、使用)

int num = 520;
//定义 一个 整型变量 并 赋值为 520
//开辟一个空间 用于存储 520 

 

指针相关概念

引用目的:能够从地址的角度,找到内存中的数据,而不是以变量的角度去找,效率较高

指针:就是内存地址编号

指针变量:由于指针这个地址编号很难记忆,我们引入指针变量存储指针

                  存储地址的变量称为指针变量

指针变量中,指针存储地址,作为一个特殊的数据类型,其大小是固定的8字节

指针变量的定义

定义格式:数据类型*指针名;      (  数据类型*       表示指针类型  )

指针变量的初始化

1、使用一个相同数据类型的变量的地址为其进行初始化 int num = 520; int * ptr = # //将num的地址赋值个指针变量 ptr //定义一个指针变量ptr,指向num

2、使用一个已经初始化了的指针变量给一个新的指针变量进行初始化 int * qtr = ptr; //此时表示两个指针变量同时存储了num的地址 int *qtr = #

3、使用地址的0 就是 NULL为其初始化 int *wtr = NULL;

4、注意:没有初始化的指针变量不能直接使用,因为该指针变量中存储了一个随机地址,如果对其进行更改,可能会导致系统瘫痪

5、野指针:指向非法内存的指针称为野指针

        产生情况:
        1)定义指针时,没有为其进行初始化
        2) 指向了一个内存空间,但是随着程序的进行,该内存空间被回收了,那么该指针也                是野指针(悬空指针)
        3)数组下标越界时,访问的地址也是野指针

指针变量的使用

使用运算符'   ’*‘   来取得指针变量中的值,我们也称该运算为 取值运算

1、指针变量在定义时,*号只是身份的象征,表示该语句定义的是指针变量

2、指针变量使用是,*号表示一个运算,取值运算,就是取得该指针变量指向的内存空间中的值

3、总结一下 * 号在C语言中的用途

1) 表示乘号,是一个双目运算符

2) 定义指针时,是身份的象征,表示定义的是指针变量

3) 使用指针时,是取值运算符,表示取得指针变量指向的内存空间中的值

4、总结一下 & 在C语言中的用途

1) 一个&表示双目运算符 按位 与运算

2) 两个&&表示双目运算符 逻辑 与运算

3) 一个&表示单目运算符 取址运算

5、&与*在指针的方面,互为逆运算

         int num = 520;

        int *ptr = &num;

        1) *&num ==> *(&num) ==> *(ptr) ==> num

        2) &*ptr ==> &(*ptr) ==> &(num) ==> ptr

        3) *&ptr ==>*(&ptr) ==> *(ptr的二级地址) ==> ptr

        4) &*num ==>报错

 指针的大小与指针的类型之间的关系

        不同数据类型的指针所占内存空间都是一样的,都是指针的大小,32位系统下位4字节,64位系统下为8字节

        指针的数据类型存在的意义,不是为了给指针分配内存空间的,而是为了指针偏移使用的

        不同类型的指针,在进行指针偏移时,偏移的大小跟指针的数据类型有个

        指针每偏移一个单位,内存空间就会偏移一个数据类型大小的字节数

        指针指向普通变量时,指针的偏移时没有意义的,但是指针指向数组时,指针的偏移就有了现实的意义,表示指向上一个或下一个数组的元素

指针可以参与的运算

        数加运算:表示对指针进行偏移

        取值运算(*)、取址运算(&)

        关系运算: == 判断两个指针是否指向同一个内存地址,ptr==NULL,判空指针

 指针指向普通变量作业参数作为函数参数

指针作为函数的参数进行数据传递时,不一定是地址传递

 作业

1.求n的k次方(递归)

#include <stdio.h>
int n_k(int n,int k)
{
    if(k==0)
    {
        return 1;
    }else
    {
        return n*n_k(n,k-1);
    }


}
int main()
{
    int n,k = 0;
    printf("求n的k次方\n分别输入n和k:\n");
    scanf("%d %d",&n,&k);
    int a = n_k(n,k);
    printf("%d的%d次方为:%d\n",n,k,a);
}

 

2、递归实现 strlen 的功能

#include <stdio.h>
#define MAX 100
//指针偏移实现逐个检查元素
int len(char *ptr)
{
    if(*ptr)//*ptr指向arr的元素  如果有 则进行下面语句  字符串结尾默认有'\0'
    {
        return 1+len(ptr+1);  //递归实现累加     ptr+1实现偏移
    }
    return 0;
}
//逐个检查数组元素
int len1(char arr[],int n)
{
    if(arr[n]!=0)
    {
        return 1+len1(arr,n+1);  //递归实现累加     ptr+1实现偏移
    }
    return 0;
}

int main()
{
    char arr[MAX]="";
    printf("输入一个字符串:\n");
    // scanf("%s",arr);
    gets(arr);   //gets  允许输入空格
    printf("该字符串的实际长度为:%d\n",len(arr));
    printf("该字符串的实际长度为:%d\n",len1(arr,0));
    
}

4、定义一个函数将一个字符串从大到小排序

#include <stdio.h>
#define MAX 5
//递归实现排列
// void paiLie(char *arr,int a)
// {
//  if(a>0)
//  {
//     if(*arr<*(arr+1))
//     {
//         int temp  = *(arr);
//         *(arr) =  *(arr+1);
//         *(arr+1) = temp;
        
//     }
//  }else
//  {
//     return 0; 
//  }
    
//  paiLie(arr+1,a-1);
// }

//一般方法实现
void paiLie1(char *arr,int n)
{
    for(int i = 1;i<n;i++)
    {
        for(int j = 0;j<n-i;j++)
        {
        if(arr[j]<arr[j+1])
        {
            int temp  = arr[j];
            arr[j] =  arr[j+1];
            arr[j+1] = temp;
        }
        
        }

    }
}
int main()
{
    char arr[MAX]="";
    printf("输入一个字符串:\n");
    // scanf("%s",arr);
    gets(arr);   //gets  允许输入空格
    // paiLie(arr,MAX);
    paiLie1(arr,MAX);
    printf("将该字符串降序排列:%s\n",arr);
    
    
 
    
}

5、实现一个函数,用于检查一个字符串是否是回文字符串

#include <stdio.h>
#include <string.h>
void hui_wz(char arr[],int n)
{
    for(int i = 0;i<n/2;i++)
    {
        if(arr[i]!=arr[n-1-i])
        {
            printf("不是回文字\n");
            return 0;
        }
    }
    printf("是回文字\n");
}


int main()
{
    char arr[1000]="";
    int n = 0;
    printf("输入一个字符串:\n");
   
    gets(arr);   //gets  允许输入空格

    n = strlen(arr);

    hui_wz(arr,n);
}

6、使用指针完成判断自己的主机存储多字节整数时,是大端存储还是小端存储

#include <stdio.h>
int check_sys()
{
	int a = 1; //开辟一个 int型 的空间 4字节
	return *(char*)&a;  //   &a a的地址   (char*)  将a的地址强转为 char型     *取n强转后的地址
}
int main()
{
	int ret = check_sys();
    //变量名 是变量的起始位置
	if( ret == 1 )
		printf("小端\n");//小端:从小端开始存储   int a = 1   储存为   00 00 00 01    强转为char型  剩 01  值不变 
	else
		printf("大端\n");//大端:从大端开始存储   int a = 1   储存为   01 00 00 00    强转为char型  剩 00  值变 
	return 0;
}

7、有一段文本,写一段程序统计其中的单词数。例如:Do one thing at a time, and do well.注意:单词间的间隔不一定是一个空格。

#include <stdio.h>
int dan_cishu(char arr[],int n)
{
    int count = 0;
    if(n==0)
    {
        return 0;
    }
    for(int i = 0;i < n;i++)
    {
        
		if(arr[i]!=' '&&arr[i+1]==' ')//统计一般情况的单词
		{
			count++;
		}
		if(arr[i]!=' '&&arr[i+1]=='\0')//统计最后一个单词
		{
			count++;
        }
        //统计逗号后的单词
        if(arr[i]==','&&(arr[i+1]>='a'&&arr[i+1]<='z'||arr[i+1]>='A'&&arr[i+1]<='Z'))
		{
			count++;
        }
    }
    return count;
}
int main()
{
    char arr[1000]="";
    printf("输入一个字符串:\n");
    gets(arr);   //gets  允许输入空格
    int n = strlen(arr);
    printf("%d\n",dan_cishu(arr,n));
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值