谭浩强《C程序设计》书后习题 第八章

最近要复习一下C和C++的基础知识,于是计划把之前学过的谭浩强的《C程序设计》和《C++程序设计》习题重新做一遍。

编译环境为:操作系统32位Win7,编译工具VC++6.0

第八章:函数

8.1)写两个函数,分别求两个整数的最大公约数和最小公倍数

#include<stdio.h>

//计算最大公约数(辗转相除法)
int GCD(int x, int y)
{
    if(x < y) 
    {
        int temp = x;
        x = y;
        y = temp;
    }
 
    if(x % y != 0) 
    {
        return GCD(y, x % y);
    }
    else 
    {
        return y;
    }
}

//计算最小公倍数
int LCM(int x, int y)
{
    return x * y / GCD(x, y);
}

void main()
{
    int a, b;
    scanf("%d%d", &a, &b);

    printf("最大公约数:%d\n", GCD(a, b));
    printf("最小公倍数:%d\n", LCM(a, b));
}

8.2)求方程ax^2+bx+c=0的根,根据b^2-4ac与零的关系,分别用三个函数解

#include<stdio.h>
#include<math.h>

//两个实根的情况
void RealRoot2(double a, double b, double c)
{
    double delta = b * b - 4 * a * c;
    double x1 = (-1.0 * b + sqrt(delta)) / (2.0 * a);
    double x2 = (-1.0 * b - sqrt(delta)) / (2.0 * a);
    printf("x1=%lf, x2=%lf\n", x1, x2);
}

//单一实根的情况
void RealRoot1(double a, double b, double c)
{
    double delta = b * b - 4 * a * c;
    double x = (-1.0 * b) / (2.0 * a);
    printf("x=%lf\n", x);
}

//共轭复数根情况
void ImaginaryRoot2(double a, double b, double c)
{
    double delta = b * b - 4 * a * c;
    double realpart = (-1.0 * b) / (2.0 * a);
    double imgnpart = sqrt(-1.0 * delta) / (2.0 * a);
    printf("x1=%lf+%lfi, x2=%lf-%lfi\n", realpart, imgnpart, realpart, imgnpart);
}

void main()
{
    double a, b, c;
    scanf("%lf%lf%lf", &a, &b, &c);

    double delta = b * b - 4 * a * c;
    //根据Δ值判断调用哪个函数进行计算
    if(delta > 0)
    {
        RealRoot2(a, b, c);
    }
    else if(delta == 0)
    {
        RealRoot1(a, b, c);
    }
    else
    {
        ImaginaryRoot2(a, b, c);
    }
}

8.3)判断一个数是否为素数

#include<stdio.h>

//判断一个数是否为素数
int IsPrime(int n)
{
    //只有大于或等于2的数才有可能是质数
    if(n <= 1)    return 0;

    int counter;
    for(counter = 2; counter < n / 2 + 1; counter++)
    {
        if(n % counter == 0)
        {
            return 0;
        }
    }

    return 1;
}

void main()
{
    int n;
    scanf("%d", &n);
    if(IsPrime(n))
    {
        printf("%d is a prime number\n", n);
    }
    else
    {
        printf("%d is not a prime number\n", n);
    }
}

8.4)写一个函数,对一个3×3矩阵进行转置

#include<stdio.h>

#define height    3
#define width    3

//对矩阵进行转置
void Transposition(int matrix[height][width])
{
    int i, j, temp;
    for(i = 0; i < height; i++)
    {
        for(j = i + 1; j < width; j++)
        {
            temp = matrix[i][j];
            matrix[i][j] = matrix[j][i];
            matrix[j][i] = temp;
        }
    }
}

void main()
{
    int a[height][width] = 
    {
        { 1, 2, 3 },
        { 4, 5, 6 },
        { 7, 8, 9 }
    };

    //输出矩阵
    int i, j;
    for(i = 0; i < height; i++)
    {
        for(j = 0; j < width; j++)
        {
            printf("%d\t", a[i][j]);
        }
        printf("\n");
    }

    //矩阵转置
    Transposition(a);
    
    //输出转置后矩阵
    for(i = 0; i < height; i++)
    {
        for(j = 0; j < width; j++)
        {
            printf("%d\t", a[i][j]);
        }
        printf("\n");
    }
}

8.5)写一个函数,翻转一个输入的字符串

#include<stdio.h>

void StringReverse(char s[])
{
    int length = 0;
    while(s[length] != '\0')
    {
        length++;
    }

    char temp;
    int i;
    for(i = 0; i < length / 2; i++)
    {
        temp = s[i];
        s[i] = s[length - i - 1];
        s[length - i - 1] = temp;
    }
}

void main()
{
    char s[100];
    scanf("%s", s);

    //输入的字符串
    printf("Input : %s\n", s);
    //翻转字符串
    StringReverse(s);
    //翻转后的字符串
    printf("Output: %s\n", s);
}

8.6)写一个函数,将两个字符串连接

#include<stdio.h>

//将s1和s2连接,结果放到s中
void StringConcat(char s[], char s1[], char s2[])
{
    int i,j;
    for(i = 0; s1[i] != '\0'; i++)
    {
        s[i] = s1[i];
    }
    for(j = 0; s2[j] != '\0'; i++, j++)
    {
        s[i] = s2[j];
    }
    s[i] = '\0';
}

void main()
{
    char s[200];
    char s1[100] = "Hello ";
    char s2[100] = "world!";
    
    StringConcat(s, s1, s2);

    printf("%s\n", s);
}

8.7)写一个函数,将一个字符串的元音字母复制到另一个字符串中

#include<stdio.h>

//将s1中的元音字母复制到s2
void SelectVowel(char s1[], char s2[])
{
    int i = 0, j = 0;
    while(s1[i] != '\0')
    {
        if(s1[i] == 'a' || s1[i] == 'A' ||
            s1[i] == 'e' || s1[i] == 'E' ||
            s1[i] == 'i' || s1[i] == 'I' ||
            s1[i] == 'o' || s1[i] == 'O' ||
            s1[i] == 'u' || s1[i] == 'U')
        {
            s2[j] = s1[i];
            j++;
        }
        i++;
    }
    s2[j] = '\0';
}

void main()
{
    char s1[100] = "abcdefghijklmnopqrstuvwxyz";
    char s2[100];

    SelectVowel(s1, s2);

    //输出为 aeiou
    printf("%s\n", s2);
}

8.8)写一个函数,要求输入一个四位数,分别以字符形式输出该数的四个数字

#include<stdio.h>

void Int2CharString(int n)
{
    printf("%d %d %d %d\n", n / 1000, n % 1000 / 100, n % 100 / 10, n % 10);
}

void main()
{
    int n;
    scanf("%d", &n);
    Int2CharString(n);
}

8.9)写一个函数,统计一个字符串中的字母、数字、空格和其他字符的个数

#include<stdio.h>

//字符串统计结果
void Statistics(char words[])
{
    int count_of_AtoZ = 0; //大写字母数
    int count_of_atoz = 0; //小写字母数
    int count_of_0to9 = 0; //数字数
    int count_of_spac = 0; //空格数
    int count_of_othr = 0; //其他字符数

    int counter = 0;
    while(words[counter] != '\0')
    {
        if(words[counter] >= 'A' && words[counter] <= 'Z')
        {
            count_of_AtoZ++;
        }
        else if(words[counter] >= 'a' && words[counter] <= 'z')
        {
            count_of_atoz++;
        }
        else if(words[counter] >= '0' && words[counter] <= '9')
        {
            count_of_0to9++;
        }
        else if(words[counter] == ' ')
        {
            count_of_spac++;
        }
        else
        {
            count_of_othr++;
        }
        counter++;
    }

    printf("A-Z:   %d\n", count_of_AtoZ);
    printf("a-z:   %d\n", count_of_atoz);
    printf("0-9:   %d\n", count_of_0to9);
    printf("space: %d\n", count_of_spac);
    printf("other: %d\n", count_of_othr);
}

void main()
{
    char s[100];
    gets(s);
    printf("Input: %s\n", s);

    Statistics(s);
}

8.10)写一个函数,输入一行字符,将该行字符中最长的单词输出

#include<stdio.h>

char* MaxLengthWord(char s[])
{
    int left = 0, right = 0;
    int max_length = 0; //最长单词的长度
    int max_left = 0;    //最长单词左边界
    int max_right = 0;    //最长单词右边界

    int temp = 0;
    while(s[temp] != '\0')
    {
        if(s[temp] == ' ')
        {
            left = temp + 1;
            right = temp + 1;
        }
        else
        {
            right++;
            if(right - left > max_length)
            {
                max_length = right - left;
                max_left = left;
                max_right = right;
            }
        }

        temp++;
    }

    char max_word[100];
    int i;
    for(i = max_left; i <= max_right; i++)
    {
        max_word[i - max_left] = s[i];
    }
    max_word[i - max_left] = '\0';

    return max_word;
}

void main()
{
    char s[100];
    gets(s);
    printf("Input : %s\n", s);
    
    char* w;
    w = MaxLengthWord(s);
    printf("Output: %s\n", w);
}

8.11)写一个函数,用冒泡法对10个字符进行排序

#include<stdio.h>

//冒泡排序
void Sort(char s[], int length)
{
    int i, j;
    char ctemp;
    for(i = 0; i < length; i++)
    {
        for(j = i + 1; j < length; j++)
        {
            if(s[i] > s[j])
            {
                ctemp = s[i];
                s[i] = s[j];
                s[j] = ctemp;
            }
        }
    }
}

void main()
{
    char s[11];
    int counter = 10;
    while(counter--)
    {
        scanf("%c", &s[9 - counter]);
    }
    s[10] = '\0';
    
    printf("排序前:%s\n", s);
    Sort(s, 10);
    printf("排序后:%s\n", s);
}

8.12)用牛顿迭代法求根,方程为ax^3+bx^2+cx+d,输入系数a、b、c、d为1、2、3、4,求x在1附近的实根

#include<stdio.h>

#define    times    10

//牛顿法求方程 ax^3+bx^2+cx+d=0在x=1附近的根
double RootNear1(double a, double b, double c, double d)
{
    double x = 1;
 
    //牛顿迭代法:x[n+1]=x[n]-f(x[n])/f'(x[n])
    int counter;
    for(counter = 0; counter < times; counter++)
    {
        x = x - (a * x * x * x + b * x * x + c * x + d) / 
            (3 * a * x * x + 2 * b * x + c);
    }

    return x;
}

void main()
{
    double a, b, c, d, result;
    scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
    result = RootNear1(a, b, c, d);
    printf("%lf\n", result);
}

8.13)用递归法求n阶勒让德多项式的值,递归公式为

p(n,x)=1 (n=0)

p(n,x)=x (n=1)

p(n,x)=((2n-1)x-p(n-1,x)-(n-1)*p(n-2,x))/n (x>1)

#include<stdio.h>

double func(int n, double x)
{
    if(n == 0)
    {
        return 1;
    }
    else if(n == 1)
    {
        return x;
    }
    else if(n > 1)
    {
        return ((2 * n) * x - func(n - 1, x) - (n - 1) * func(n - 2, x)) / n;
    }
}

void main()
{
    int n;
    double x;
    scanf("%d%lf", &n, &x);
    printf("func(%d, %lf) = %lf\n", n, x, func(n, x));
}

8.14)输入10个学生5门课程成绩,分别用函数实现下列功能

1.计算每个学生的平均分

2.计算每门课的平均分

3.找出所有50个分数中最高的分数所对应的学生和课程

4.计算平均分方差 σ=(Σx[i]^2)/n-((Σx[i])/n)^2

#include<stdio.h>

#define StudentCount    10
#define CourseCount        5

//输出每个学生的平均分
void PrintAverage1(int score[StudentCount][CourseCount])
{
    int i, j;
    int average1;
    for(i = 0; i < StudentCount; i++)
    {
        average1 = 0;
        for(j = 0; j < CourseCount; j++)
        {
            average1 += score[i][j];
        }
        average1 /= CourseCount;
        printf("Student %d's average is %d\n", i, average1);
    }
}

//输出每个科目的平均分
void PrintAverage2(int score[StudentCount][CourseCount])
{
    int i, j;
    int average2;
    for(j = 0; j < CourseCount; j++)
    {
        average2 = 0;
        for(i = 0; i < StudentCount; i++)
        {
            average2 += score[i][j];
        }
        average2 /= StudentCount;
        printf("Student %d's average is %d\n", j, average2);
    }
}

//输出最大分数,并输出这个分数是由哪名学生在哪个科目上获得的
void PrintMaxScore(int score[StudentCount][CourseCount])
{
    int i, j;
    int max_score = 0, max_i = 0, max_j = 0;
    for(i = 0; i < StudentCount; i++)
    {
        for(j = 0; j < CourseCount; j++)
        {
            if(score[i][j] > max_score)
            {
                max_score = score[i][j];
                max_i = i;
                max_j = j;
            }
        }
    }
    printf("Student: %d; Course: %d; Max Score: %d\n", max_i, max_j, max_score);
}

//输出平均分方差 σ=(Σx[i]^2)/n-((Σx[i])/n)^2
void PrintAverageVariance(int score[StudentCount][CourseCount])
{
    int i, j;
    int average[StudentCount];
    for(i = 0; i < StudentCount; i++)
    {
        average[i] = 0;
        for(j = 0; j < CourseCount; j++)
        {
            average[i] += score[i][j];
        }
        average[i] /= CourseCount;
    }

    double part1 = 0.0;
    for(i = 0; i < StudentCount; i++)
    {
        part1 += average[i] * average[i];
    }
    part1 /= StudentCount;

    double part2 = 0.0;
    for(i = 0; i < StudentCount; i++)
    {
        part2 += average[i];
    }
    part2 /= StudentCount;
    part2 *= part2;

    printf("Result: %lf\n", part1 - part2);
}

void main()
{
    int score[StudentCount][CourseCount];
    int i, j;
    for(i = 0; i < StudentCount; i++)
    {
        for(j = 0; j < CourseCount; j++)
        {
            scanf("%d", &score[i][j]);
        }
    }

    PrintAverage1(score);
    PrintAverage2(score);
    PrintMaxScore(score);
    PrintAverageVariance(score);
}

8.15)写几个函数

1.输入10个职工的姓名和职工号

2.按职工号由小到大顺序排序,姓名顺序也随之调整

3.要求输入一个职工号,用折半查找找出该职工的姓名

#include<stdio.h>
#include<string.h>

#define StaffCount    10

void InputInfo(int id[StaffCount], char name[StaffCount][100])
{
    int i;
    for(i = 0; i < StaffCount; i++)
    {
        scanf("%d%s", &id[i], name[i]);
    }
}

void PrintInfo(int id[StaffCount], char name[StaffCount][100])
{
    int i;
    for(i = 0; i < StaffCount; i++)
    {
        printf("Id: %d; Name: %s\n", id[i], name[i]);
    }
}

void SortId(int id[StaffCount], char name[StaffCount][100])
{
    int i, j, temp1;
    char temp2[100];

    for(i = 0; i < StaffCount; i++)
    {
        for(j = i + 1; j < StaffCount; j++)
        {
            if(id[i] > id[j])
            {
                //交换ID
                temp1 = id[i];
                id[i] = id[j];
                id[j] = temp1;

                //交换姓名
                strcpy(temp2, name[i]);
                strcpy(name[i], name[j]);
                strcpy(name[j], temp2);
            }
        }
    }
}

void SearchId(int id[StaffCount], char name[StaffCount][100], int testid)
{
    int left = 0, right = StaffCount - 1, mid = (left + right) / 2;
    while(true)
    {
        if(id[left] == testid)
        {
            printf("Id: %d; Name: %s\n", id[left], name[left]);
            break;
        }
        else if(id[right] == testid)
        {
            printf("Id: %d; Name: %s\n", id[right], name[right]);
            break;
        }
        else if(id[mid] == testid)
        {
            printf("Id: %d; Name: %s\n", id[mid], name[mid]);
            break;
        }
        else if(left >= right - 1)
        {
            break;
        }

        if(id[mid] > testid)
        {
            right = mid - 1;
            //printf("left: %d; right:%d\n", left, right);
        }
        else
        {
            left = mid + 1;
            //printf("left: %d; right:%d\n", left, right);
        }
        mid = (left + right) / 2;
    }
}

void main()
{
    int id[StaffCount];
    char name[StaffCount][100];

    InputInfo(id, name);    //输入ID和姓名
    SortId(id, name);        //根据ID排序
    PrintInfo(id, name);    //输出ID和姓名

    int test;
    printf("Choose an Id: ");
    scanf("%d", &test);
    SearchId(id, name, test);
}

8.16)写一个函数,输入一个十六进制数,输出相应的十进制数

#include<stdio.h>

int HexToDec(char number[])
{
    int result = 0, counter = 0, currnum;
    while(number[counter] != '\0')
    {
        if(number[counter] >= '0' && number[counter] <= '9')
        {
            currnum = number[counter] - '0';
        }
        if(number[counter] >= 'A' && number[counter] <= 'F')
        {
            currnum = number[counter] - 'A' + 10;
        }
        result *= 16;
        result += currnum;
        counter++;
    }
    return result;
}

void main()
{
    char number[10];
    scanf("%s", number);
    printf("%d\n", HexToDec(number));
}

8.17)写一个函数,将一个整数转换成字符串

(书中说的“递归法”我没有理解,所以只是写了一个实现题目功能的代码)

#include<stdio.h>

void IntToString(char result[], int num)
{
    int i = 0;
    while(num != 0)
    {
        result[i] = num % 10 + '0';
        num /= 10;
        i++;
    }
    result[i] = '\0';
    //printf("%s length:%d\n", result, i);

    char temp;
    int j;
    for(j = 0; j < i / 2; j++)
    {
        temp = result[i - j - 1];
        result[i - j - 1] = result[j];
        result[j] = temp;
    }
    result[i] = '\0';
    //printf("%s length:%d\n", result, i);
}

void main()
{
    int num;
    scanf("%d", &num);
    char result[10];
    IntToString(result, num);
    printf("%s\n", result);
}

8.18)给出年、月、日,计算该日是该年的第几天

#include<stdio.h>

//判断某年是否为闰年
int IsLeapYear(int year)
{
    if(year % 4 != 0) //不能被4整除,不是闰年
    {
        return 0;
    }
    else if(year % 400 == 0) //四百年一闰
    {
        return 1;
    }
    else if(year % 100 == 0) //一百年不闰
    {
        return 0;
    }
    else //其他能被4整除的年都是闰年
    {
        return 1;
    }
}

int DayOfTheYear(int year, int month, int day)
{
    int isLeapYear = IsLeapYear(year);
    int temp_mon = 0, temp_day = 0;
    while(temp_mon != month - 1)
    {
        switch(temp_mon)
        {
            case 0: { temp_day += 31; } break; //一月
            case 1: 
                { 
                    if(isLeapYear)
                    {
                        temp_day += 29;
                    }
                    else
                    {
                        temp_day += 28;
                    }
                } break; //二月
            case 2: { temp_day += 31; } break; //三月
            case 3: { temp_day += 31; } break; //四月
            case 4: { temp_day += 31; } break; //五月
            case 5: { temp_day += 31; } break; //六月
            case 6: { temp_day += 31; } break; //七月
            case 7: { temp_day += 31; } break; //八月
            case 8: { temp_day += 31; } break; //九月
            case 9: { temp_day += 31; } break; //十月
            case 10: { temp_day += 31; } break; //十一月
            default: { return -1; } break;
        }
        temp_mon++;
    }
    return temp_day + day;
}

void main()
{
    int year, month, day;
    scanf("%d%d%d", &year, &month, &day);
    printf("DayOfYear:%d\n", DayOfTheYear(year, month, day));
}

END


转载于:https://my.oschina.net/Tsybius2014/blog/307780

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值