明解C语言中级篇练习代码------第四章

一放假真的就看不进书了害
而且这章习题真的好难!超级无敌巨难!!!
4-6想了好久还是没想出来 哭哭( •̥́ ˍ •̀ू )

练习4-1

//编写一个限制玩家可以输入次数的“珠玑妙算”程序。

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void make4digit (int x[])
{
    int i, j, val;

    for (i=0; i<4; i++) {
        do {
            val = rand()%10;
            for (j=0; j<i; j++)
                if (val == x[j])
                    break;
        } while (j<i);
        x[i] = val;
    }
}

int check (const char s[])
{
    int i, j;

    if (strlen(s) != 4)
        return 1;

    for (i=0; i<4; i++) {
        if (!isdigit(s[i]))
            return 2;
        for (j=0; j<i; j++)
            if (s[i] == s[j])
            return 3;
    }

    return 0;
}

void judge (const char s[], const int no[], int *hit, int *blow)
{
    int i, j;

    *hit = *blow = 0;
    for (i=0; i<4; i++) {
        for (j=0; j<4; j++) {
            if (s[i] == '0'+no[j])
                if (i == j)
                    (*hit)++;
                else
                    (*blow)++;
        }
    }
}

void printf_result (int snum, int spos)
{
    if (spos == 4)
		printf("回答正确!!");
	else if (snum == 0)
		printf("    这些数字里没有答案数字。\n");
	else {
		printf("    这些数字里包括%d个答案数字。\n", snum);

		if (spos == 0)
			printf("    但是数字的位置都不一致。\n");
		else
			printf("    其中有%d个数字的位置是一致的。\n", spos);
	}
	putchar('\n');
}

int main(void)
{
	int try_no=0;
	int chk;
	int hit,blow;
	int no[4];
	char buff[10];
	clock_t start,end;
	int times = 10;                            //限制次数

	srand( time(NULL) );

	puts("■ 来玩珠玑妙算吧。");
	puts("■ 请猜4个数字。");
	puts("■ 其中不包含相同数字。");
	puts("■ 请像4307这样连续输入数字。");
	puts("■ 不能输入空格字符。\n");

	make4digit(no);

	start = clock();

	do {
        if (times == 0) {
            printf("□GAME OVER!\n");
            break;
        }

        printf("□你只有%d次机会了噢~\n\n",times);

        do {
            printf("请输入:");
			scanf("%s", buff);

			chk = check(buff);

			switch (chk) {
			 case 1: puts("\a请确保输入4个字符。"); break;
			 case 2: puts("\a请不要输入除了数字以外的字符。"); break;
			 case 3: puts("\a请不要输入相同的数字。"); break;
			}
        } while (chk != 0);

        try_no++;
        times--;
        judge(buff, no, &hit, &blow);
        printf_result(hit + blow, hit);

	} while (hit < 4);

	end = clock();

	printf("用了%d次。\n用时%.1f秒。\n",
					try_no, (double)(end - start) / CLOCKS_PER_SEC);

	return 0;
}

练习4-2

//给“珠玑妙算”添加提示功能。

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int no[4];                //把目标数字变为全局变量,因为在不同函数中都有用到
int hint = 4;             //最多提示次数
int hint_bit = 1;         //提示的位数
int hint1 = -1;
int hint2 = -1;

void make4digit (int x[])
{
    int i, j, val;

    for (i=0; i<4; i++) {
        do {
            val = rand()%10;
            for (j=0; j<i; j++)
                if (val == x[j])
                    break;
        } while (j<i);
        x[i] = val;
    }
/*
    for (i=0; i<4; i++)            检查答案
        printf("%d ",x[i]);
    puts("\n");
*/
}

int check (const char s[])
{
    int i, j;

    if (strlen(s) != 4)
        return 1;

    for (i=0; i<4; i++) {
        if (!isdigit(s[i]))
            return 2;
        for (j=0; j<i; j++)
            if (s[i] == s[j])
            return 3;
    }

    return 0;
}

void judge (const char s[], const int no[], int *hit, int *blow)
{
    int i, j;

    *hit = *blow = 0;
    for (i=0; i<4; i++) {
        for (j=0; j<4; j++) {
            if (s[i] == '0'+no[j])
                if (i == j) {
                    (*hit)++;
                    if (hint1 == -1)               //因为要把第一个放入hint1中,后面可能给出提示,所以一开始hint的标识应该是不可能随机给出的数字
                        hint1 = no[j];
                }
                else {
                    (*blow)++;
                    hint2 = s[i]-'0';              //注意s[i]-'0'变为int型数字
                }
        }
    }
}

void hint_show (void)
{
    int i;
    int tishi;

    if (hint > 0) {
        printf("\n你还有%d次提示机会。\n",hint);
        puts("\n提示内容有:");
        printf("□提示第%d个字符。---1\n",hint_bit);
        puts("□提示\"hit\"的数字中最前面一个字符。---2");
        puts("□提示\"blow\"的数字中最末尾一个字符。---3");
        puts("不需要提示,直接返回。---0");
    hint_choose:
        printf("请选择:");
        scanf("%d",&tishi);
        printf("\n");

        if (tishi == 1) {
            printf("第%d个字符为 %d。\n",hint_bit,no[hint_bit-1]);
            hint_bit++;                                                 //提示完要把提示的位数增加,即下一次提示第二位,再第三位...
            hint--;
        }
        else if (tishi == 2) {
        	if (hint1 == -1)
        		printf("无正确位置的数字!");
        	else
           		printf("%d 正确且位置正确!",hint1);
            hint--;
        }
        else if (tishi == 3) {
        	if (hint2 == -1)
        		printf("无正确数字!");
            else
				printf("%d 正确但位置错误!",hint2);
            hint--;
        }
        else if (tishi == 0)
            return;
        else {
            printf("ERROR!\n");
            goto hint_choose;
        }
        putchar('\n');
    }
}

void printf_result (int snum, int spos)
{
	int opt;

    if (spos == 4) {
		printf("回答正确!!");
		return;
	}
	else if (snum == 0)
		printf("    这些数字里没有答案数字。\n");
	else {
		printf("    这些数字里包括%d个答案数字。\n", snum);

		if (spos == 0)
			printf("    但是数字的位置都不一致。\n");
		else
			printf("    其中有%d个数字的位置是一致的。\n", spos);
	}
	putchar('\n');

	if (hint > 0) {
	choose:
	    printf("需要提示吗?1---需要 0---不需要:");
	    scanf("%d",&opt);

	    if (opt == 1)
	        hint_show();
	    else
	        if (opt != 0 ) {
	            printf("ERROR!\n");
	            goto choose;
	        }
	}
	else
		puts("你已经没有提示机会了!");

	putchar('\n');
}

int main(void)
{
	int try_no=0;
	int chk;
	int hit,blow;
	char buff[10];
	clock_t start, end;

	srand( time(NULL) );

	puts("■ 来玩珠玑妙算吧。");
	puts("■ 请猜4个数字。");
	puts("■ 其中不包含相同数字。");
	puts("■ 请像4307这样连续输入数字。");
	puts("■ 不能输入空格字符。");
	printf("■ 你有%d次提示机会。\n\n",hint);

	make4digit(no);

	start = clock();

	do {
        do {
            printf("请输入:");
			scanf("%s", buff);

			chk = check(buff);

			switch (chk) {
			 case 1: puts("\a请确保输入4个字符。"); break;
			 case 2: puts("\a请不要输入除了数字以外的字符。"); break;
			 case 3: puts("\a请不要输入相同的数字。"); break;
			}
        } while (chk != 0);

        try_no++;
        judge(buff, no, &hit, &blow);
        printf_result(hit + blow, hit);

	} while (hit < 4);

	end = clock();

	printf("用了%d次。\n用时%.1f秒。\n",
					try_no, (double)(end - start) / CLOCKS_PER_SEC);

	return 0;
}

练习4-3

//编写一个数字位数非4位且位数可变的“珠玑妙算”程序。游戏开始时询问“设成几位数:”,让玩家输入数字位数。

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int bits;

void makesomedigit (int x[])
{
    int i, j, val;

    for (i=0; i<bits; i++) {
        do {
            val = rand()%10;
            for (j=0; j<i; j++)
                if (val == x[j])
                    break;
        } while (j<i);
        x[i] = val;
    }
}

int check (const char s[])
{
    int i, j;

    if (strlen(s) != bits)
        return 1;

    for (i=0; i<bits; i++) {
        if (!isdigit(s[i]))
            return 2;
        for (j=0; j<i; j++)
            if (s[i] == s[j])
            return 3;
    }

    return 0;
}

void judge (const char s[], const int no[], int *hit, int *blow)
{
    int i, j;

    *hit = *blow = 0;
    for (i=0; i<bits; i++) {
        for (j=0; j<bits; j++) {
            if (s[i] == '0'+no[j])
                if (i == j)
                    (*hit)++;
                else
                    (*blow)++;
        }
    }
}

void printf_result (int snum, int spos)
{
    if (spos == bits)
		printf("回答正确!!");
	else if (snum == 0)
		printf("    这些数字里没有答案数字。\n");
	else {
		printf("    这些数字里包括%d个答案数字。\n", snum);

		if (spos == 0)
			printf("    但是数字的位置都不一致。\n");
		else
			printf("    其中有%d个数字的位置是一致的。\n", spos);
	}
	putchar('\n');
}

int main(void)
{
	int try_no=0;
	int chk;
	int hit,blow;
	int no[10];
	char buff[10];
	clock_t start, end;

	srand( time(NULL) );

	puts("■ 来玩珠玑妙算吧。");

    printf("□ 设成几位数的呢?");
	scanf("%d",&bits);

	printf("■ 请猜%d个数字。\n",bits);
	puts("■ 其中不包含相同数字。");
	puts("■ 请像4307这样连续输入数字。");
	puts("■ 不能输入空格字符。\n");



	makesomedigit(no);

	start = clock();

	do {
        do {
            printf("请输入:");
			scanf("%s", buff);

			chk = check(buff);

			switch (chk) {
			 case 1: printf("\a请确保输入%d个字符。\n",bits); break;
			 case 2: puts("\a请不要输入除了数字以外的字符。"); break;
			 case 3: puts("\a请不要输入相同的数字。"); break;
			}
        } while (chk != 0);

        try_no++;
        judge(buff, no, &hit, &blow);
        printf_result(hit + blow, hit);

	} while (hit < bits);

	end = clock();

	printf("用了%d次。\n用时%.1f秒。\n",
					try_no, (double)(end - start) / CLOCKS_PER_SEC);

	return 0;
}

练习4-4

//编写一个允许出现重复次数的“珠玑妙算”程序。

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void make4digit (int x[])
{
    int i;

    for (i=0; i<4; i++) {
         x[i] = rand()%10;
    }
}

int check (const char s[])
{
    int i, j;

    if (strlen(s) != 4)
        return 1;

    for (i=0; i<4; i++) {
        if (!isdigit(s[i]))
            return 2;
    }

    return 0;
}

void judge (const char s[], const int no[], int *hit, int *blow)
{
    int i, j;

    *hit = *blow = 0;
    for (i=0; i<4; i++) {
        for (j=0; j<4; j++) {
            if (s[i] == '0'+no[j])
                if (i == j)
                    (*hit)++;
                else
                    (*blow)++;
        }
    }
}

void printf_result (int snum, int spos)
{
    if (spos == 4)
		printf("回答正确!!");
	else if (snum == 0)
		printf("    这些数字里没有答案数字。\n");
	else {
		printf("    这些数字里包括%d个答案数字。\n", snum);

		if (spos == 0)
			printf("    但是数字的位置都不一致。\n");
		else
			printf("    其中有%d个数字的位置是一致的。\n", spos);
	}
	putchar('\n');
}

int main(void)
{
	int try_no=0;
	int chk;
	int hit,blow;
	int no[4];
	char buff[10];
	clock_t start, end;

	srand( time(NULL) );

	puts("■ 来玩珠玑妙算吧。");
	puts("■ 请猜4个数字。");
	puts("■ 其中可以包含相同数字。");
	puts("■ 请像4307这样连续输入数字。");
	puts("■ 不能输入空格字符。\n");

	make4digit(no);

	start = clock();

	do {
        do {
            printf("请输入:");
			scanf("%s", buff);

			chk = check(buff);

			switch (chk) {
			 case 1: puts("\a请确保输入4个字符。"); break;
			 case 2: puts("\a请不要输入除了数字以外的字符。"); break;
			}
        } while (chk != 0);

        try_no++;
        judge(buff, no, &hit, &blow);
        printf_result(hit + blow, hit);

	} while (hit < 4);

	end = clock();

	printf("用了%d次。\n用时%.1f秒。\n",
					try_no, (double)(end - start) / CLOCKS_PER_SEC);

	return 0;
}

练习4-5

//编写一个不猜数字而猜颜色的“珠玑妙算”程序。颜色共8种(白色、黑色、红色、蓝色、黄色、绿色、橙色、褐色),从中选出不重复的4种颜色让玩家来猜。

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char color[9][10]={"无", "白色", "黑色", "红色", "蓝色", "黄色", "绿色", "橙色", "褐色"};

void make4digit (int x[])
{
    int i, j, val;

    for (i=0; i<4; i++) {
        do {
            val = 1+rand()% 8;
            for (j=0; j<i; j++)
                if (val == x[j])
                    break;
        } while (j<i);
        x[i] = val;
    }
    for (i=0; i<4; i++)
        printf("%d ",x[i]);
    puts("\n");
}

int check (const char s[][10])
{
    int i, j;

    for (i=0; i<4; i++) {

        for(j=1; j<=8; j++) {
            if( !(strcmp(s[i],color[j])) )        //比较字符串要用strcmp函数,不能直接用==判断。
                break;
        }
        if (j == 9)                               //这个判断不能放在for语句里,因为一旦j=9后会跳出for循环而不执行这个语句!
            return 2;

        for (j=0; j<i; j++)
            if( !(strcmp(s[i],s[j])) )
                return 3;
    }

    return 0;
}

void judge (const char s[][10], const int no[], int *hit, int *blow)
{
    int i, j;

    *hit = *blow = 0;
    for (i=0; i<4; i++) {
        for (j=0; j<4; j++) {
            if ( !(strcmp(s[i],color[no[j]])) )          //注意是对应数字的颜色,所以是color[no[j]]。
                if (i == j)
                    (*hit)++;
                else
                    (*blow)++;
        }
    }
}

void printf_result (int snum, int spos)
{
    if (spos == 4)
		printf("回答正确!!");
	else if (snum == 0)
		printf("    这些数字里没有对应答案数字的颜色。\n");
	else {
		printf("    这些数字里包括%d个对应答案数字的颜色。\n", snum);

		if (spos == 0)
			printf("    但是对应数字的颜色的位置都不一致。\n");
		else
			printf("    其中有%d个对应数字的颜色的位置是一致的。\n", spos);
	}
	putchar('\n');
}

int main(void)
{
	int try_no=0;
	int chk;
	int hit,blow;
	int no[4];
	char buff[4][10];
	clock_t start, end;
	int i;

	srand( time(NULL) );

	puts("■ 来玩猜颜色版的珠玑妙算吧。");
	puts("■ 白-1 黑-2 红-3 蓝-4 黄-5 绿-6 橙-7 褐-8 ");
	puts("■ 请猜4个颜色。");
	puts("■ 其中不包含相同颜色。");
	puts("■ 请像 白色 黑色 这样输入颜色。");
	puts("■ 不能输入空格字符,回车代表输入完毕。\n");

	make4digit(no);

	start = clock();

	do {
        do {
            printf("\n");
            for(i=0; i<4; i++) {
                printf("请输入第%d个颜色:",i+1);
                scanf("%s", buff[i]);
            }

			chk = check(buff);

			switch (chk) {
			 case 2: puts("\a请不要输入除了颜色以外的字符。"); break;
			 case 3: puts("\a请不要输入相同的颜色。"); break;
			}
        } while (chk != 0);

        try_no++;
        judge(buff, no, &hit, &blow);
        printf_result(hit + blow, hit);

	} while (hit < 4);

	end = clock();


    printf("\n正确答案是:\n");
    for (i=0; i<4; i++) {
        printf("%s ",color[no[i]]);
    }
    printf("\n");

	printf("用了%d次。\n用时%.1f秒。\n",
					try_no, (double)(end - start) / CLOCKS_PER_SEC);

	return 0;
}

练习4-6
真的不会 太难了 仙女落泪 (´°̥̥̥̥̥̥̥̥ω°̥̥̥̥̥̥̥̥`)

练习4-7

//在第1章中,我们编写了一个猜0~999的数字的“猜数游戏”。编写一个程序,让所出的题目中不同数字位上不能出现相同的数字(例如55和919等)

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_STAGE 10

double digit_no=0;              //目标数字
double digit_ans=0;             //输入数字
//这里的两个全局变量是将int/char型数组数字转化为int型纯数字用,必须用doubl型,再强制转化为int型输出,我一开始定义的int型,发现一直有误差。

void makedigits (int x[], int y)
{
    int i, j;

    for(i=0; i<y; i++) {
        if (i==0)                      //第一位不能为0
            x[i] = 1 + rand()%9;
        else {
fuzhi:      x[i] = rand()%10;
            for (j=0; j<i; j++) {
                if (x[j] == x[i])      //确保数字不一样
                    goto fuzhi;        //有时候goto真的很好用!
            }
        }
    }
/*
    for (i=0; i<y; i++) {                  可以检查每位产生的数字
        printf("%d ",x[i]);
    }
*/
    j = y - 1;
    digit_no = 0;
    for (i=0; i<y; i++) {                 //将int型数组转化为数字,pow(10,j)代表10的j次方,是在<math.h>中定义
        digit_no += (x[i])*pow(10,j);
        j--;
    }
/*
    printf("答案为%d\n",(int)digit_no);   检查用
*/
}

int check (const char ans[], int y)
{
    int i, j;

    if (strlen(ans) != y)
        return 1;

    for (i=0; i<y; i++) {
        if ( isdigit(ans[i]) == 0)
            return 2;
        for (j=0; j<i; j++) {
            if (ans[i] == ans[j])
                return 3;
        }
    }

    return 0;
}

int main(void)
{
	int i,j;
	int stage=0;             //输入次数
	int num[MAX_STAGE];      //显示记录
	int weishu;              //要猜的数字位数
	int no[4];               //目标数字
	char ans[10];            //玩家输入数字
	int chk;                 //检查输入数字

	srand(time(NULL));
	weishu = 1 + rand()%3;                           //先用随机值决定要猜的位数

    puts("■ 来玩猜改进版的猜数游戏吧。");
	puts("■ 其中不包含相同数字。");
	puts("■ 不能输入空格字符,回车代表输入完毕。");
	printf("■ 你要猜的数字为 %d 位数。\n",weishu);

	makedigits(no,weishu);

	do {
		printf("\n还剩%d次机会。是多少呢:", MAX_STAGE - stage);

        do {
            printf("请输入:");
            scanf("%s",ans);

            chk = check(ans,weishu);

            printf("\n");
            switch (chk) {
                 case 1: printf("\a请确保输入%d个字符。\n",weishu); break;
                 case 2: puts("\a请不要输入除了数字以外的字符。"); break;
                 case 3: puts("\a请不要输入相同的数字。"); break;
                }
        } while (chk != 0);

        j = weishu - 1;
        digit_ans = 0;                              //每一次都要重新归零!!!
        for (i=0; i<weishu; i++) {
            digit_ans += (ans[i]-'0')*pow(10,j);    //与上面同理转化为int型数字,char型字符要减去'0'转化为每一位的数字
            j--;
        }
        printf("你输入的答案为:%d\n",(int)digit_ans); //强制转换
        num[stage++] = digit_ans;

        if (digit_ans > digit_no)
			printf("\a再小一点。\n");
		else if (digit_ans < digit_no)
            printf("\a再大一点。\n");
        else
            break;

	} while ( stage < MAX_STAGE);

	if (digit_ans != digit_no)
		printf("\n\a很遗憾,正确答案是%d。\n", (int)digit_no);
	else {
		printf("\n回答正确。\n");
		printf("您用了%d次猜中了。\n", stage);
	}

	puts("\n--- 输入记录 ---");
	for (i = 0; i < stage; i++)
		printf(" %2d : %4d %+4d\n", i + 1, num[i], num[i] - (int)digit_no);

	return 0;
}


版权声明:本文为Isabel_Bei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。