第七章 用函数实现模块化程序设计(习题)

第七章 课后习题

1、写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。

最大公约数

  1)穷举法

#include <stdio.h>

// 穷举法
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else if(b==0)
        return a;
    else if(a==b)
        return a;
    int gcd_res=a>b?a:b;
    while(gcd_res>1)
    {
        if((a%gcd_res==0)&&(b%gcd_res==0))
            return gcd_res;
        gcd_res--;
    }
    return gcd_res;    // 1
}
int main()
{
    int a,b;
    printf("Please enter two number:\n");
    scanf("%d,%d",&a,&b);
    int gcd_result=gcd(a,b);
    printf("最大公约数为:%d\n",gcd_result);
    return 0;
}
View Code

  2)相减法

int gcd(int a,int b)
{
    if(a==0)
        return b;
    else if(b==0)
        return a;
    else if(a==b)
        return a;
    int gcd_res;
    while(a!=b)
    {
        gcd_res=a>b?(a-=b):(b-=a);
    }
    return gcd_res;    // 1
}
View Code

  3)欧几里得辗转相除法

    ① 循环实现

int gcd(int a,int b)
{
    if(a==0)
        return b;
    else if(b==0)
        return a;
    else if(a==b)
        return a;
    int mod=a%b;
    whlie(mod)    //当相模不为0时
    {
        a=b;    // b的值赋值给a
        b=mod;    // 
        mod=a%b;
    }
    return b;
}
View Code

    ④ 递归实现

int gcd(int a,int b)
{
    if(b==0)
        return a;
    else 
        return gcd(b,a%b);
    return b;
}
View Code

最小公倍数 

  1)穷举法

int lcm(int a,int b)
{
    // 穷举法
    if(a*b==0)
        return 0;
    int lcm_res=a>b?a:b;
    while(1) 
    {
        if((lcm_res%a==0)&&(lcm_res%b==0))
            break;
        lcm_res++;
    }
    return lcm_res;
        
}

int main()
{
    int a,b;
    printf("Please enter two number:\n");
    scanf("%d,%d",&a,&b);
    int lcm_result=lcm(a,b);
    printf("最大公倍数为:%d\n",lcm_result);
    return 0;
}
View Code

  2)公式法 

#include <stdio.h>

int gcd(int a,int b)
{    // 欧几里得辗转相除法
    if(b==0)
        return a;
    else 
        return gcd(b,a%b);
    return b;
}

int lcm(int a,int b)
{    // 公式法    lcm=a*b/gcd(a,b)
    
    if(a*b==0)
        return 0;
    return (a*b/gcd(a,b));
        
}

int main()
{
    int a,b;
    printf("Please enter two number:\n");
    scanf("%d,%d",&a,&b);
    int gcd_result=gcd(a,b);
    int lcm_result=lcm(a,b);
    printf("最大公约数为:%d\n",gcd_result);
    printf("最大公倍数为:%d\n",lcm_result);
    return 0;
}
View Code

 2、写一个判素数的函数,在主函数输入一个整数,输出是否为素数的信息。

#include <stdio.h>
#include <math.h>
int IsPrime(int a)
{
    int i,flag;
    double k;
    k=sqrt(a);
    for(i=2;i<=k;i++)
    {
        if(a%i==0)
            return flag=0;
        else
            return flag=1;    
    }
    
}

int main()
{
    printf("Please enter a number:\n");
    scanf("%d",&a);
    int flag=IsPrime(a);
    if(flag)
        printf("%d 是一个素数\n",a);
    
    else
        printf("%d 不是一个素数\n",a);
    return 0;
}
View Code

3、写一个函数,使给定的一个3X3的二维整型数组转置,即行列互换。

#include<stdio.h>
void PrintArray(int ar[3][3])
{
    // 运行结果:
        for(int i=0; i<3; i++)
        {
            for(int j=0; j<3;j++)
            {
                printf("%d ", ar[i][j]);
            }
            printf("\n");
        }
}
void ReverseArray(int ar[3][3])
{
    int tmp;
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<i;j++)
        {
            if(i != j) //中间数不发生变化
            {
                //交换两个数
                tmp = ar[i][j];
                ar[i][j] = ar[j][i];
                ar[j][i] = tmp;
            }
        }
    }
}
int main()
{
    int array[3][3] =
    {
        {1,2,3},
        {4,5,6},
        {7,8,9}
    };
    printf("转置前:\n");
    PrintArray(array);    
    ReverseArray(array);        //进行数组转置
    printf("转置后:\n");
    PrintArray(array);
    return 0;
}
View Code

4、写一个函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。

  第一种实现方式(这种个人觉得好难理解哈哈哈)

#include <stdio.h>
#include <string.h>
int main()
{
    void trans_str(char str[]);
    char str[10];
    gets(str);
    trans_str(str);
    puts(str);
    return 0;
}

void trans_str(char str[])
{
    int i;
    int len=strlen(str);
    char temp;
    for(i=0;i<len/2;i++)
    {
            temp=str[i];
            str[i]=str[len-i-1];
            str[len-i-1]=temp;
    }

}
View Code

   第二种实现方式

#include<stdio.h>
#include<string.h>
void ReverseString(char str[])
{
    int start, end;
    char tmp;
    start = 0;
    end = strlen(str)-1; //字符数组小标从0开始,所以-1
    while(start < end)
    {
        tmp = str[start];
        str[start] = str[end];
        str[end] = tmp;
        start++;
        end--;
    }
}
int main()
{
    char str[100] = {0};
    printf("请输入一个字符串:>");
    scanf("%s", str);
    printf("原始字符串为:> %s\n", str);
    ReverseString(str);
    printf("反序字符串为:> %s\n", str);
    return 0;
}
View Code

 5、写一个函数将两个字符串连接起来

  1)直接将第二个字符串加到第一个字符串后面:

#include <stdio.h>
#include <string.h>
int main()
{
    void link_str(char str1[],char str2[]);
    char str1[20];
    char str2[10];
    printf("Please enter the str1:\n");
    gets(str1);
    printf("Please enter the str1:\n");
    gets(str2);
    link_str(str1,str2);
    printf("The new string is:");
    puts(str1);
    return 0;
}

void link_str(char str1[],char str2[])
{
    int len_1=strlen(str1);                // 得到两个数组的长度
    int len_2=strlen(str2);
    for(int i=0;i<len_2;i++)            // 遍历字符串数组2
    {
        str1[len_1+i]=str2[i];            // 直接在str1接上str2
    }

}
View Code

  2)开辟临时数组

#include<stdio.h>
void ConcatStr(char string1[], char string2[], char string[])
{
    int i, j;
    for (i = 0; string1[i] != '\0'; i++)
        string[i] = string1[i];                // 找到字符串末尾,继续往后面链接字符串
    for (j = 0; string2[j] != '\0'; j++)    
        string[i + j] = string2[j];
    string[i + j] = '\0';                    // 字符串末尾加上结束符 \0
}
int main()
{
    char s1[200] = {0}, s2[100]= {0}, s[100] = {0};
    printf("input string1:");
    scanf("%s", s1);
    printf("input string2:");
    scanf("%s", s2);
    ConcatStr(s1, s2, s);
    printf("\nThe new string is %s\n", s);
    return 0;
}
View Code

6、写一个函数,将一个字符串中的元音字母复制到另一字符串,然后输出。

#include <stdio.h>
void cpy(char s[], char c[])
{
    int i, j;
    for (i = 0, j = 0; s[i] != '\0'; i++)
    {
        //判断元音字母
        if (s[i] == 'a' || s[i] == 'A' || s[i] == 'e' || s[i] == 'E' ||
            s[i] == 'i' ||s[i] == 'I' || s[i] == 'o' || s[i] == 'O' ||
            s[i] == 'u' || s[i] == 'U')
        {
            c[j] = s[i];
            j++;
        }
    }
    c[j] = '\0';
}
int main()
{
    char str[80], c[80];
    printf("input string:");
    gets(str);
    cpy(str, c); //将str中的元音字母拷贝到c中
    printf("The vowel letters are:%s\n", c);
    return 0;
}
View Code

7、写一个函数,输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格。如输人2020,应输出“2 0 2 0”

#include<stdio.h>
void add_space(char str[])
{
    int i;
    for(i=0;str[i]!='/0';i++)
    {    
        printf("%c", str[i]);
        if(str[i+1] == '\0')        //清除最后一个空格不输出
            break;
        printf("%c", ' ');
        
    }
    printf("\n");
}

int main()
{
    char str[20]={0};
    scanf("%s",str);
    add_space(str);
    return 0;
}
View Code

8、编写一个函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输人字符串以及输出上述的结果。

#include <stdio.h>
#include <string.h>
int a,n,s,o;
void statistics(char str[])
{
    
    int i,len=strlen(str);
    for(i=0;i<len;i++)
    {
        if((str[i]>='a'&& str[i]<='z')||(str[i]>='A'&& str[i]<='Z'))
        {    
            a++;
        }
        else if(str[i]>='0'&&str[i]<='9')
        {
            n++;
        }
        else if(str[i]==' ')
        {
            s++;
        }
        else
        {
            o++;
        }
    }
            
}
int main()
{
    char str[80];
    printf("Please enter a string:\n");
    gets(str);
    statistics(str);
    printf("字母个数:%d\n数字个数:%d\n空格个数:%d\n其他字符:%d\n", a,n,s,o);
    return 0;
}
View Code

9、写一个函数,输人一行字符,将此字符串中最长的单词输出。

#include <stdio.h>
#include <string.h>
void longest_word(char str[],char word[])
{
    int i,j;
    i=j=0;
    int len=0;
    while(str[j]!='\0')
    {
        j=i;
        while(str[j]!=' '&& str[j]!='\0')        // 同时判断空格和字符串是否结束,后面一句是消除最后一个空格
            j++;
        len=j-i;
        if(len > strlen(word))
        {
            strncpy(word,str+i,len);    // 拷贝临时最长单词        从str中的i到len个字符
        }
        j++;
        i=j;
    }

    
}
int main()
{
    char str[100];
    char word[20]={0};
    printf("Please enter a string:\n");
    gets(str);
    longest_word(str,word);
    printf("%s\n",word);
    return 0;
}
View Code
#include<stdio.h>
#include<string.h>
void LongestWord(char str[], char word[])
{
    int max_len = 0;
    int len = 0;
    int i = 0;
    while(str[i] != '\0')
    {
        if(str[i] == ' ')
        {
            str[i] = '\0';
            len = strlen(str);
            if(len > max_len)
            {
                max_len = len;
                strcpy(word, str);
                str = str + len + 1;
            }
        }
        i++;
    }
}
int main()
{
    char line[100] = {0};
    char word[100] = {0};
    printf("input one line:\n");
    gets(line);
    LongestWord(line, word);
    printf("The longest word is : %s\n", word);
    return 0;
}
View Code

 10、写一个函数,用“起泡法”对输人的10个字符按由小到大顺序排列。

#include<stdio.h>
#include<string.h>
void BubbleSort(char str[])
{
    int i, j;
    char tmp;
    int len = strlen(str);
    for(i=0; i<len-1; ++i)
    {
        for(j=0; j<len-i-1; ++j)
        {
            if(str[j] > str[j+1])
            {
                tmp = str[j];
                str[j] = str[j+1];
                str[j+1] = tmp;
            }
        }
    }
}
int main()
{
    int i;
    char str[11] = {0};
    printf("请输入10个字符:>");
    for(i=0; i<10; ++i)
        scanf("%c", &str[i]);
    BubbleSort(str);
    printf("string sorted: %s\n", str);
    return 0;
}
View Code

11、输人10个学生5门课的成绩,分别用函数实现下列功能:
  ① 计算每个学生的平均分;
  ② 计算每门课的平均分;
  ③ 找出所有50个分数中最高的分数所对应的学生和课程;
  ④ 计算平均分方差:   

题目解析:    

  此题的关键是如何存储某个学生对应某门课程的分数,这里利用了一个二维数组score,其中score[i] [j]就代表了第i个学生的第j门课程的分数,只要能够理解这个存储方式,其余的计算就是比较容易理解和实现的。

#include<stdio.h>
#define N 10
#define M 5
float score[N][M];
float a_stu[N], a_cour[M];
int r, c;


void input_stu(void)                // 输入学生成绩信息函数
{
    int i, j;
    for (i = 0; i < N; i++)
    {
        printf("\ninput score of student%2d:\n", i + 1);
        for (j = 0; j < M; j++)
            scanf("%f", &score[i][j]);
    }
}

void aver_stu(void)                    // 每个学生平均分
{
    int i, j;
    float s;
    for (i = 0; i < N; i++)
    {
        for (j = 0, s = 0; j < M; j++)
            s += score[i][j];
        a_stu[i] = s / 5.0;
    }
}


void aver_cour(void)                // 每门课程平均分
{
    int i, j;
    float s;
    for (j = 0; j < M; j++)
    {
        s = 0;
        for (i = 0; i < N; i++)
            s += score[i][j];
        a_cour[j] = s / (float)N;
    }
}

float highest()                    //    最高分函数
{
    float high;
    int i, j;
    high = score[0][0];
    for (i = 0; i < N; i++)
        for (j = 0; j<M; j++)
            if (score[i][j]>high)
            {
                high = score[i][j];
                r = i + 1;
                c = j + 1;
                
            }
            return(high);
}

float s_var(void)                    // 方差函数
{
    int i;
    float sumx, sumxn;
    sumx = 0.0;
    sumxn = 0.0;
    for (i = 0; i < N; i++)
    {
        sumx += a_stu[i] * a_stu[i];
        sumxn += a_stu[i];
    }
    return(sumx / N - (sumxn / N)*(sumxn / N));
}
int main()
{
    int i, j;
    float h;
    input_stu();
    aver_stu();
    aver_cour();
    printf("\n NO. cour1 cour2 cour3 cour4 cour5 aver\n");
    for (i = 0; i < N; i++)
    {
        printf("\n NO %2d ", i + 1);
        for (j = 0; j < M; j++)
            printf("%8.2f", score[i][j]);
        printf("%8.2f\n", a_stu[i]);
    }
    printf("\naverage:");
    for (j = 0; j < M; j++)
        printf("%8.2f", a_cour[j]);
    printf("\n");
    h = highest();
    printf("highest:%7.2f NO. %2d course %2d\n", h, r, c);
    printf("variance %8.2f\n", s_var());
    return 0;
}
View Code

 13、输入4个整数,找出其中最大的数,用递归方法。

#include <stdio.h>
int max_2(int a,int b)                                //找2个中最大的
{
    return (a>b?a:b);                                //注意三元式的写法
}

int max_4(int x,int y,int z,int w)
{
    return (max_2(max_2(max_2(x,y),z),w));            //递归找4个中最大的
}
    


int main()
{
    int a,b,c,d,max;
    printf("Please enter four numbers :\n");
    scanf("%d,%d,%d,%d",&a,&b,&c,&d);
    max=max_4(a,b,c,d);
    printf("The max is %d\n",max);
    return 0;
}
View Code
#include<stdio.h>
int max_n(int n,int num[]);
int max_2(int a, int b);
int main()
{
    int max;
    int num[4];
    printf("Please input 4 numbers:\n");
    scanf("%d %d %d %d",&num[0],&num[1],&num[2],&num[3]);
    max=max_n(4,num);
    printf("The Max is:%d\n",max);
}
int max_n(int n,int num[])
{
    int max;
    if(n==2)
    max=max_2(num[n-2],num[n-1]);
    else if(n>2)
    max=max_2(num[n-1],max_n(n-1, num));
    return max;
}
int max_2(int a, int b)
{
    return (a>b?a:b);
}
View Code

14、用递归法将一个整数n转换成字符串。例如,输人483,应输出字符串”483”。n的位数不确定,可以是任意位数的整数。

#include<stdio.h>
void Convert(int n)
{
    int i;
    if ((i = n / 10) != 0)
        Convert(i);
    putchar(n % 10 + '0');
}
int main()
{
    int number;
    printf("input an integer: ");
    scanf("%d", &number);
    printf("output: ");
    if (number < 0)
    {
        putchar('-'); //先输出一个负号'-'
        number = -number;
    }
    Convert(number);
    printf("\n");
    return 0;
}
View Code

15、给出年、月、日,计算该日是该年的第几天。

#include <stdio.h>
#include<stdio.h>
/* 函数sum_day:计算日期 */
int sum_day(int month, int day)
{
    int day_tab[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int i;
    for (i = 1; i < month; i++)
        day += day_tab[i]; /* 累加所在月之前天数 */
    return day;
}
/* 函数leap:判断是否为闰年 */
int leap(int year)
{
    int leap;
    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    return leap;
}
int main()
{
    int year, month, day, days;
    printf("input date(year,month,day):");
    scanf("%d %d %d", &year, &month, &day);
    printf("%d/%d/%d ", year, month, day);
    days = sum_day(month, day); /* 调用函数sum_day */
    if (leap(year) && month >= 3) /* 调用函数leap */
        days = days + 1;
    printf("is the %dth day in this year.\n", days);
    return 0;
}
View Code

 

 

 

posted @ 2021-03-08 12:03  一个特立独行的猪  阅读(711)  评论(0)    收藏  举报