20251期《C语言程序设计B》程序改错题讲解-20251208-知识点整理

525 阅读29分钟

答题要求

  • 要特别注意,最少最小改动原则,C语法灵活,有很多种改法
  • 每一行都要认真推敲一下,按不能改动的行,来反推该如何来改动,更符合语法语义要求
  • 改完之后,在本地一定要编译运行一下,可以自行给入一些测试数据
  • 学习阶段,一定要读懂题,猜测对该题考核的知识点,举一反三
  • 个别一些题,在运用上其实不多,但确实容易考到人
给出的程序可能存在语法或算法上的问题或需要补充完整,但需要修改的地方肯定在/*******Found*******/下的第一行上,不能修改其它地方,不能修改或删除/*******Found*******/本身,遵循**最少修改****符合编程规范****较通用(非别出心裁)** 、保持一行一条语句及{与}单独一行的原则。由于是计算机自动阅卷,修改时不能增加行或删除行,哪怕是一个空行都不行,否则可能得0分。  
  注意:(1)若/*******Found*******/下有___________,则应当将___________去掉并填上相应的程序代码。  
      (2)程序应当在Turbo C V2/V3、MS VC V6或GCC V3中完成编译链接并能正常运行。

具体解答

一些题给出了题面,原码,修改后的代码,对应的知识点整理 可以一直讨论下去 很多题,有很多种正确的改法,但提供的改法,仅仅只是一个参考

D1讲解

题面 功能是从键盘读入一个数并在屏幕上显示。

原码

#include<stdio.h>

int main(void)
{
        int xy2;

        /*********Found************/
        scanf("%s", &xy2);
        /*********Found************/
        printf("xy2=%5d\n", &xy2);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        int xy2;

        /*********Found************/
        scanf("%d", &xy2);
        /*********Found************/
        printf("xy2=%5d\n", xy2);

	return 0;
}

知识点

  • 数据类型匹配相应的输入输出格式
  • scanf 和 printf 的格式化输入输出
  • 输入时,取内存地址
  • 输出时,直接使用变量

D2讲解

题面 功能是调用函数,显示两个实数间最大的一个。

原码

#include<stdio.h>

float fmax(float x, float y);

int main(void)
{
        /*********Found************/
        float l, 1;

        l = 3.0;
        i = 5.6f;
        /*********Found************/
        printf("fmax(%5.2f, %5.2f)=%5.2f\n", i, l, fMax(i, l));

	return 0;
}

/*********Found************/
int fmax(float x, float y)
{
        if (x < y) return y;
        else return x;
}

改后

#include<stdio.h>

float fmax(float x, float y);

int main(void)
{
        /*********Found************/
        float l, i;

        l = 3.0;
        i = 5.6f;
        /*********Found************/
        printf("fmax(%5.2f, %5.2f)=%5.2f\n", i, l, fmax(i, l));

	return 0;
}

/*********Found************/
float fmax(float x, float y)
{
        if (x < y) return y;
        else return x;
}

知识点

  • 变量先定义,后使用
  • 对字母的显示要敏感一些,有一些字体上很相似,要特别注意:i,l,1,o,0,O,I,L
  • 函数相关概念:声明,定义,调用。
  • 函数头要一致,注意输入参数和返回值的使用

D3讲解

题面 功能是将字符串yy在屏幕上输出。

原码

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char yy[200] = "ok??\n";

        /*********Found************/
        fol (; *yy; yy++)
        {
                putchar(*yy);
        }

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char *yy = "ok??\n";

        /*********Found************/
        for (; *yy; yy++)
        {
                putchar(*yy);
        }

	return 0;
}

知识点

  • 指针
  • 字符指针
    • 让指针指向一个串
    • 这是一个指针变量,可以滑动
    • 用*yy 方式,取对应的内存的值,即取出字符来显示
  • 字符串和字符数组,内存的操作
  • 指针滑动实现对字符串里的每个字符的访问
  • C 常用关键字不能写错

D5讲解

题面 功能是将字符串yy显示在屏幕上。

原码

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char yy[100] = "ok??\n",

        /*********Found************/
        prntf("%s", yy);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char yy[100] = "ok??\n";

        /*********Found************/
        printf("%s", yy);

	return 0;
}

知识点

  • 最小改动原则
  • printf 函数名不能写错了
  • 字符数组的整体初始化,应该使用{}和单个字符元素来进行
  • 最简单的改法就是让一个字符指针来指向该字符串即可

D6讲解

题面 功能是从键盘读入一行字符(包括空格、TAB等字符)并在屏幕上显示。

原码

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char yy<128>;

        /*********Found************/
        getchar(yy);

        /*********Found************/
        printf("%y", yy);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char yy[128];

        /*********Found************/
        gets(yy);

        /*********Found************/
        printf("%s", yy);

	return 0;
}

知识点

  • 数组的语法,是使用 []
  • 读入一行字符,定义数组来装一行字符
  • gets 可以读入一行,虽然不提倡再用它,但仍然可以使用
  • 要注意,使用时不可以越界
  • 输出时,使用%s 格式输出一个字符串

D7讲解

题面 功能是判断x和y是否相等,相等则显示x=y,不等则显示x<>y。

原码

#include<stdio.h>

int main(void)
{
        /*********Found************/
        char x, y;

        x = 39270;
        y = 41001;
        /*********Found************/
        if (x != y)
        {
                printf("x=y");
        }
        /*********Found************/
        else;;
        {
                printf("x<>y\n");
        }

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        /*********Found************/
        int x, y;

        x = 39270;
        y = 41001;
        /*********Found************/
        if (x == y)
        {
                printf("x=y");
        }
        /*********Found************/
        else
        {
                printf("x<>y\n");
        }

	return 0;
}

知识点

  • 编码风格,大括号使用
  • if...else...基本结构,程序块要分清楚
  • 使用什么数据类型,需要合理
  • 逻辑判断,要和实际需求吻合

D8讲解

题面 功能是打开文件d:\te.c用于读并判断打开是否成功。

原码

#include<stdio.h>

int main(void)
{
        FILE *fp;
        /*********Found************/
        char fileName[] = "d:\te.c";

        /*********Found************/
        fp = fopen(fileName, "w");

        /*********Found************/
        if (fp is NULL)
        {
                puts("File Open Error!");
                return 1;
        }
        putchar(fgetc(fp));
        fclose(fp);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        FILE *fp;
        /*********Found************/
        char fileName[] = "d:\\te.c";

        /*********Found************/
        fp = fopen(fileName, "r");

        /*********Found************/
        if (fp == NULL)
        {
                puts("File Open Error!");
                return 1;
        }
        putchar(fgetc(fp));
        fclose(fp);

	return 0;
}

知识点

  • 在 win 下,路很使用反斜杠时,要注意它在双引号中,是转义的标志,需要两个反斜杠
  • 表示文件的路径,需要用反斜杠,注意转义表示法
  • 只读的方式打开文件,传入的模式参数应该是 "r"
  • 判断文件指针是否打开了文件,使用 相等 的逻辑

D10讲解

题面 功能是将字符串str2显示在屏幕上。

原码

#include<stdio.h>

/*********Found************/
#define START
/*********Found************/
#define NEXT

int main(void)
{
        char *str2 = "13125176247";
        const int i = 0;

        for (printf("\n"); str2[i]; )
        START
                putchar(str2[i]);
                /*********Found************/
                i++;
        NEXT

	return 0;
}

改后

#include<stdio.h>

/*********Found************/
#define START {
/*********Found************/
#define NEXT }

int main(void)
{
        char *str2 = "13125176247";
        const int i = 0;

        for (printf("\n"); str2[i]; )
        START
                putchar(str2[i]);
                /*********Found************/
                str2++;
        NEXT

	return 0;
}

知识点

  • 宏定义要正确使用它的替换功能
  • 程序块的 {} 是一个整体,有开始,有结束,这里用宏替换了
  • 这里的 i 变量,是一具常量,终始为 0 ,那么要遍历整个串里的每一个字符,指针本身就得移动了
  • 相当于是,下标固定,只取 0,即当前指向的位置
  • 但每次用完指针后,指针会滑动

D11讲解

题面 功能是计算1/1 + 1/2 + … + 1/N之和并显示。

原码

#include<stdio.h>

#define N 10

int main(void)
{
        /*********Found************/
        long jieguo = 0;
        int fm;

        for (fm = 1; fm <= N; fm++)
        {
                /*********Found************/
                jieguo += 1 / fm;
        }
        printf("%8.6f\n", jieguo);

	return 0;
}

改后

#include<stdio.h>

#define N 10

int main(void)
{
        /*********Found************/
        float jieguo = 0;
        int fm;

        for (fm = 1; fm <= N; fm++)
        {
                /*********Found************/
                jieguo += (float)1 / fm;
        }
        printf("%8.6f\n", jieguo);

	return 0;
}

知识点

  • 小数除法和整数除法,在 C 语言里,都用的是/符号
  • 为了得到小数,需要进行强制数据转换,否则,没有小数部分,精度丢失
  • 也可以写成 1.0 / fm 这样也很简便

D12讲解

题面 功能是从键盘读入a和b的值(输入格式限定为仅a,b),在屏幕上显示b行a。

原码

#include<stdio.h>

int main(void)
{
        int a, b;

        /*********Found************/
        scanf("%d%d", &a, &b);
        while (b > 0)
        /*********Found************/
        ___________

                printf("%d\n", a);
                b--;
        /*********Found************/
        ___________

        printf("bye bye!\n");

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        int a, b;

        /*********Found************/
        scanf("%d,%d", &a, &b);
        while (b > 0)
        /*********Found************/
        {

                printf("%d\n", a);
                b--;
        /*********Found************/
        }

        printf("bye bye!\n");

	return 0;
}

知识点

  • 要求输入时,有逗号间隔,格式化输入,格式要一致
  • 输出的是 b 行 a
  • 循环体这个域要定义正确,正好符合 while 语法要求

D13讲解

题面 功能是从键盘输入最多10个字符(遇换行则停止输入)到数组Buf中,然后在屏幕上显示。

原码

#include<stdio.h>

int main(void)
{
        char c, Buf[11];
        int pos;

        /*********Found************/
        for (pos = 1; pos <= 10; pos++)
        {
                /*********Found************/
                if ((c = getchar() == '\n')
                {
                        break;
                }
                Buf[pos] = c;
        }
        /*********Found************/
        ___________
        printf("%s\n", Buf);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        char c, Buf[11];
        int pos;

        /*********Found************/
        for (pos = 0; pos <= 10; pos++)
        {
                /*********Found************/
                if ((c = getchar()) == '\n')
                {
                        break;
                }
                Buf[pos] = c;
        }
        /*********Found************/
        Buf[pos] = '\0';
        printf("%s\n", Buf);

	return 0;
}

知识点

  • 数组的下标,是从 0 开始记数的
  • 数组操作,不要越界
  • getchar 是要先完成输入,再做判断输入的字符是不是回车换行符
  • 字符串存入数组中,需要人工给出串的结尾符,然后才能把字符数组当成串来操作

D14讲解

题面 功能是调用函数swap,将a和b的值交换,最后在屏幕上显示交换后的a,b之值。

原码

#include<stdio.h>

/*********Found************/
void swap(int x, int y);

int main(void)
{
        int a = 3, b = 4;

        /*********Found************/
        swap(a, b);
        printf("a=%d b=%d\n", a, b);

	return 0;
}

/*********Found************/
void swap(int x, int y)
{
        int tmpX;

        /*********Found************/
        ___________
        *x = *y;
        /*********Found************/
        *y = x;
}

改后

#include<stdio.h>

/*********Found************/
void swap(int *x, int *y);

int main(void)
{
        int a = 3, b = 4;

        /*********Found************/
        swap(&a, &b);
        printf("a=%d b=%d\n", a, b);

	return 0;
}

/*********Found************/
void swap(int *x, int *y)
{
        int tmpX;

        /*********Found************/
        tmpX = *x;
        *x = *y;
        /*********Found************/
        *y = tmpX;
}

知识点

  • 子函数要想完成主调函数的变量值交换,一定要用传址的方式
  • 子函数的形参变量,是地址,也就是可以用指针来表示
  • 调用函数时,传入变量的地地,以完成地址内的数据值交换操作
  • 交换算法的朴素实现:使用第三个量,仅仅用于存值和取值操作

D16讲解

题面 功能是worker2的信息使用结构体存储,从键盘读入其各项信息并显示。

原码

#include<stdio.h>

int main(void)
{
        struct WKER
        {
                long ID;
                long int num;
                char name[20];
                char sex;
        /*********Found************/
        } ;

        worker2.ID = 1L;
        /*********Found************/
        scanf("%s %s %s", &worker2.num, worker2.name, &worker2.sex);
        /*********Found************/
        printf("worker's info: num=%s name=%s sex=%s\n",
                        worker2.num, worker2.name, worker2.sex);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
        struct WKER
        {
                long ID;
                long int num;
                char name[20];
                char sex;
        /*********Found************/
        } worker2;

        worker2.ID = 1L;
        /*********Found************/
        scanf("%ld %s %c", &worker2.num, worker2.name, &worker2.sex);
        /*********Found************/
        printf("worker's info: num=%ld name=%s sex=%c\n",
                        worker2.num, worker2.name, worker2.sex);

	return 0;
}

知识点

  • 结构体类型定义和同时定义结构体变量
  • 使用结构体变量
  • 结构体变量里的分量,在格式化输入时,要注意取地址,是数组的,数组名本身就是地址
  • 格式化输入时,类型要匹配 %ld 匹配的就是 long 型, %s 匹配串, %c 匹配的就是字符

D1000讲解

题面 功能是从键盘输入3个浮点数a,b,c(输入时abc之间以空格相隔),首先按照输入顺序显示在屏幕上,然后按从小到大顺序把它们输出到屏幕上。

原码

#include<stdio.h>

int main(void)
{
	float a, b, c, t;

	printf("please input three numbers:\n");
	/*********Found************/
	scanf("%f%f", &a, &b, &c);
	printf("before sort:a=%g,b=%g,c=%g\n", a, b, c);
	if (a > b)
	{
		t = a;
		a = b;
		/*********Found************/
		b = a;
	}
	if (a > c)
	{
		t = a;
		a = c;
		c = t;
	}
	if (b > c)
	{
		t = b;
		b = c;
		c = t;
	}
	printf("after  sort:a=%g,b=%g,c=%g\n", a, b, c);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	float a, b, c, t;

	printf("please input three numbers:\n");
	/*********Found************/
	scanf("%f%f%f", &a, &b, &c);
	printf("before sort:a=%g,b=%g,c=%g\n", a, b, c);
	if (a > b)
	{
		t = a;
		a = b;
		/*********Found************/
		b = t;
	}
	if (a > c)
	{
		t = a;
		a = c;
		c = t;
	}
	if (b > c)
	{
		t = b;
		b = c;
		c = t;
	}
	printf("after  sort:a=%g,b=%g,c=%g\n", a, b, c);

	return 0;
}

知识点

  • 格式化输入,占位符要和输入参数的个数匹配一致
  • 交换算法要写正确,t 里的临时存放要取出来使用

D1001讲解

题面 功能是求分数序列:2/1,3/2,5/3,8/5,13/8,21/13,....前20项之和,要求显示的结果中小数部分有4位。

原码

#include<stdio.h>

#define T 20

int main(void)
{
	int n;
	/*********Found************/
	long i, j, temp, sum;

	i = 2;
	j = 1;
	sum = 0;
	for (n=1; n<=T; n++)
	{
		sum = sum + i / j;
		temp = i;
		i = i + j;
		j = temp;
	}

	/*********Found************/
	printf("2/1+3/2+5/3+8/5+13/8+...=%5.2f\n", sum);

	return 0;
}

改后

#include<stdio.h>

#define T 20

int main(void)
{
	int n;
	/*********Found************/
	float i, j, temp, sum;

	i = 2;
	j = 1;
	sum = 0;
	for (n=1; n<=T; n++)
	{
		sum = sum + i / j;
		temp = i;
		i = i + j;
		j = temp;
	}

	/*********Found************/
	printf("2/1+3/2+5/3+8/5+13/8+...=%5.4f\n", sum);

	return 0;
}

知识点

  • 涉及到除法的精度,需要用浮点数类型
  • 输出 4 位小数,要注意格式设置正确

D1002讲解

题面 功能是实现两数交换。

原码

#include<stdio.h>

int main(void)
{
	int x = 5, y = 9;

	x = x + y;
	y = x - y;
	/*****Found*****/
	x = y - x;
	printf("x=%d, y=%d\n", x, y);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int x = 5, y = 9;

	x = x + y;
	y = x - y;
	/*****Found*****/
	x = x - y;
	printf("x=%d, y=%d\n", x, y);

	return 0;
}

知识点

  • 不使用第三个“空杯子”完成数据交换,要注意算法的巧用
  • 建议自己列两个具体的数尝试一下,就明白算法了

D1003讲解

题面 功能是将16进制数100转换为10进制数输出。

原码

#include<stdio.h>

int main(void)
{
	/*****Found*****/
	int i = 100;

	/*****Found*****/
	printf("%d\n", &i);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	/*****Found*****/
	int i = 0x100;

	/*****Found*****/
	printf("%d\n", i);

	return 0;
}

知识点

  • 在 C 语言下,十六进制数据的表示方法
    • 0x12 十六进制
    • 012 八进制
    • 12 十进制
  • 格式化输出为十进制数时,用%d,直接使用变量名即可

D1004讲解

题面 功能是输入姓名,屏幕输出问候。

原码

#include<stdio.h>

int main(void)
{
	char s[10];

	printf("please input your name:");
	/*********Found************/
	scanf("%c", s);

	printf("hello ");
	/*********Found************/
	puts(s[10]);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	char s[10];

	printf("please input your name:");
	/*********Found************/
	scanf("%s", s);

	printf("hello ");
	/*********Found************/
	puts(s);

	return 0;
}

知识点

  • 主要是字符数组和字符串的关系
  • 用数组来盛装字符串
  • %s 的输入方式,会自动加上串尾符,但要注意数组长度,不可越界
  • %s 的输出方式,会将数组名当成指向了串的指针,直接以串格式输了,直到遇到串结束符为止

D1005讲解

题面 功能是从键盘读入两个整数并在屏幕上显示。要求:输入时限定两数之间仅以逗号隔开。

原码

#include<stdio.h>

int main(void)
{
	int a, b;

	/*********Found*********/
	scanf("%d%d", &a, &b);
	/*********Found*********/
	printf("a=%d,b=%d\n", &a, &b);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int a, b;

	/*********Found*********/
	scanf("%d,%d", &a, &b);
	/*********Found*********/
	printf("a=%d,b=%d\n", a, b);

	return 0;
}

知识点

  • 主要是格式化输入输出数据
  • 输入时,要注意原样输入的,有别于占位格式输入的部分

D1006讲解

题面 功能是判断输入的数据是否与已经给出的数据j相等。

原码

#include<stdio.h>

int main(void)
{
	long int i = 79870, j = 23;

	/*****Found*****/
	scanf("%f", &i);

	/*****Found*****/
	if (j == i);
	{
		printf("Equal!");
	}
	else
	{
		printf("Not equal!");
	}

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	long int i = 79870, j = 23;

	/*****Found*****/
	scanf("%ld", &i);

	/*****Found*****/
	if (j == i)
	{
		printf("Equal!");
	}
	else
	{
		printf("Not equal!");
	}

	return 0;
}

知识点

  • 格式化输入长整型,要使用%ld
  • if 判断后,一般使用{}做语句处理部分,直接给;,则做成了空语句,后面还有 else 时,就会有语法上的逻辑错误

D1007讲解

题面 功能是使用getchar方式从键盘读入一个字符,判断该字符是否大写字符。

原码

#include<stdio.h>

int main(void)
{
	char ch;

	/****Found****/
	getchar(ch);
	/*****Found*****/
	if ('A' <= ch, ch <= 'Z')
	{
		printf("yes");
	}
	else
	{
		printf("no");
	}

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	char ch;

	/****Found****/
	ch = getchar();
	/*****Found*****/
	if ('A' <= ch && ch <= 'Z')
	{
		printf("yes");
	}
	else
	{
		printf("no");
	}

	return 0;
}

知识点

  • getchar 函数的正确使用,是用它的返回值
  • 判断是不是大写字母的判断逻辑要写正确,要使用逻辑与符号 &&

D1008讲解

题面 功能是判断用户是不是输入的整数0。

原码

#include<stdio.h>

int main(void)
{
	int n;

	scanf("%d", &n);
	/****Found****/
	switch (n);
	{
		/****Found****/
		case0:
			printf("Zero\n");
			break;
		default:
			printf("Non-Zero");
			break;
	}

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int n;

	scanf("%d", &n);
	/****Found****/
	switch (n)
	{
		/****Found****/
		case 0:
			printf("Zero\n");
			break;
		default:
			printf("Non-Zero");
			break;
	}

	return 0;
}

知识点

  • switch 结构,需要基本的主语熟悉
  • 对于 n,可以是整数
  • 在 case 匹配时,必须是常量
  • 注意 break 的使用

D1009讲解

题面 功能是输入一个整数,如果为1时输出100,为2时输出200,其它输出0。

原码

#include<stdio.h>

int main(void)
{
	int x, y;

	scanf("%d", &x);

	switch (x)
	{
		/*********Found************/
		case x == 1:
			y = 100;
			break;
		/*********Found************/
		case x == 2:
			y = 200;
			break;
		default:
		/*********Found************/
			y = 500;
			break;
	}
	printf("%d\n", y);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int x, y;

	scanf("%d", &x);

	switch (x)
	{
		/*********Found************/
		case 1:
			y = 100;
			break;
		/*********Found************/
		case 2:
			y = 200;
			break;
		default:
		/*********Found************/
			y = 0;
			break;
	}
	printf("%d\n", y);

	return 0;
}

知识点

  • 考查 switch 结构的基础语法
  • 在对 x 进行匹配时,不需要用关系运算,直接匹配相应的常量即可
  • 按功能要求,最后应赋值为 0,以符合逻辑输出需要

D1010讲解

题面 功能是输入若干字符数据(回车表示输入结束),分别统计其中‘A’、‘B’、‘C’的个数。

原码

#include<stdio.h>

int main(void)
{
	char c;
	int k1 = 0, k2 = 0, k3 = 0;

	/*********Found************/
	while (c = getchar() != '\n')
	{
		switch (c)
		{
			/*********Found************/
			case A:
				k1++;
				break;
			case 'B':
				k2++;
				break;
			case 'C':
				k3++;
				break;
			default :
				;
		}
	}
	printf("A=%d,B=%d,C=%d\n", k1, k2, k3);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	char c;
	int k1 = 0, k2 = 0, k3 = 0;

	/*********Found************/
	while ((c = getchar()) != '\n')
	{
		switch (c)
		{
			/*********Found************/
			case 'A':
				k1++;
				break;
			case 'B':
				k2++;
				break;
			case 'C':
				k3++;
				break;
			default :
				;
		}
	}
	printf("A=%d,B=%d,C=%d\n", k1, k2, k3);

	return 0;
}

知识点

  • 先完成输入,再完成判断是不是回车换行字符
  • switch 里的 case 匹配的是常量,这里就是字符常量,字符用单引号

D1011讲解

题面 功能是从输入数据中统计正整数和负整数的个数。用输入0来结束输入,变量i存放正整数个数,变量j存放负整数的个数。

原码

#include<stdio.h>

int main(void)
{
	int i = 0, j = 0, n;

	printf("\ninput numbers:");
	scanf("%d", &n);
	/*********Found*********/
	while (______________)
	{
		if (n > 0)
		{
			i++;
		}
		if (n < 0)
		{
			j++;
		}
		/*********Found*********/
		_________________________
	}
	printf("i=%d,j=%d", i, j);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int i = 0, j = 0, n;

	printf("\ninput numbers:");
	scanf("%d", &n);
	/*********Found*********/
	while (0 != n)
	{
		if (n > 0)
		{
			i++;
		}
		if (n < 0)
		{
			j++;
		}
		/*********Found*********/
		scanf("%d", &n);
	}
	printf("i=%d,j=%d", i, j);

	return 0;
}

知识点

  • 一直要输入数据,循环体中,就是输入语句
  • 何时跳出循环,当 n 为 0 时,跳出,判断不为 0 时,就直接可以输入

D1012讲解

题面 功能是显示用1、2、3、4个数字组成的互不相同且无重复数字的三位数。

原码

#include<stdio.h>

int main(void)
{
	int i, j, k;

	/*********Found************/
	for (i=1;      ; i++)
	{
		for (j=1; j<5; j++)
		{
			for (k=1; k<5; k++)
			{
				/*********Found************/
				if (i!=k && i!=j && ______)
				{
					printf("%d%d%d ", i, j, k);
				}
			}
		}
	}

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int i, j, k;

	/*********Found************/
	for (i=1; i<5; i++)
	{
		for (j=1; j<5; j++)
		{
			for (k=1; k<5; k++)
			{
				/*********Found************/
				if (i!=k && i!=j && j!=k)
				{
					printf("%d%d%d ", i, j, k);
				}
			}
		}
	}

	return 0;
}

知识点

  • 这是一个典型的暴力求解方法
  • 穷尽所有的组合形式,并判断题目要求的“互不相同且无重复数字”

D1013讲解

题面 功能是将一个数组中的值按逆序重新存放。例如,原来顺序为8,6,5,4,1,要求改为1,4,5,6,8。

原码

#include<stdio.h>

#define N 10

int main(void)
{
	int a[N], i, temp;

	printf("please input %d integer numbers:\n", N);
	for (i=0; i<N; i++)
	{
		scanf("%d", &a[i]);
	}

	printf("the array before reverse:\n");
	for (i=0; i<N; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	/*********Found************/
	for (i=0; i<N; i++)
	{
		temp = a[i];
		/*********Found************/
		a[i] = a[N-i];
		/*********Found************/
		a[N-i] = temp;
	}

	printf("the array after reverse:\n");
	for (i=0; i<N; i++)
	{
		printf("%d  ", a[i]);
	}
	printf("\n");

	return 0;
}

改后

#include<stdio.h>

#define N 10

int main(void)
{
	int a[N], i, temp;

	printf("please input %d integer numbers:\n", N);
	for (i=0; i<N; i++)
	{
		scanf("%d", &a[i]);
	}

	printf("the array before reverse:\n");
	for (i=0; i<N; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	/*********Found************/
	for (i=0; i<N/2; i++)
	{
		temp = a[i];
		/*********Found************/
		a[i] = a[N-i-1];
		/*********Found************/
		a[N-i-1] = temp;
	}

	printf("the array after reverse:\n");
	for (i=0; i<N; i++)
	{
		printf("%d  ", a[i]);
	}
	printf("\n");

	return 0;
}

知识点

  • 折半做镜像数据交换,达到逆序的目的
  • 数组操作时,不可越界,下标最多到 N-1

D1014讲解

题面 功能是将字符数组a中元素从大到小排列(值相同的元素不交换位置)。

原码

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

int main(void)
{
	int i, j, k;
	char a[] = "language", t;

	k = strlen(a);
	for (i=0; i<k; i++)
	{
		for (j=i+1; j<k; j++)
		{
			/*****Found*****/
			if (a[i] > a[j])
			{
				t = a[j];
				/*****Found*****/
				a[i] = a[j];
				a[i] = t;
			}
		}
	}
	printf("%s\n", a);

	return 0;
}

改后

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

int main(void)
{
	int i, j, k;
	char a[] = "language", t;

	k = strlen(a);
	for (i=0; i<k; i++)
	{
		for (j=i+1; j<k; j++)
		{
			/*****Found*****/
			if (a[i] < a[j])
			{
				t = a[j];
				/*****Found*****/
				a[j] = a[i];
				a[i] = t;
			}
		}
	}
	printf("%s\n", a);

	return 0;
}

知识点

  • 相当于是选择排序,从大到小,判断时,前面小于才交换
  • 交换数据时,交换算法的编写是固定写法

D1015讲解

题面 功能是定义一个整型数组,采用子函数实现数据输入。

原码

#include<stdio.h>

void input(int a[], int n);

int main(void)
{
	int a[10], i;

	/*********Found************/
	input(a[10], 10);
	for (i=0; i<10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}


void input(int a[], int n)
{
	int i;

	for (i=0; i<n; )
	{
		scanf("%d", &a[i]);
		/*********Found************/
		i--;
	}
}

改后

#include<stdio.h>

void input(int a[], int n);

int main(void)
{
	int a[10], i;

	/*********Found************/
	input(a, 10);
	for (i=0; i<10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}


void input(int a[], int n)
{
	int i;

	for (i=0; i<n; )
	{
		scanf("%d", &a[i]);
		/*********Found************/
		i++;
	}
}

知识点

  • 函数的基础知识:声明,定义,调用
  • 函数的参数表,类型,个数要匹配
  • 数组名作为函数的参数传入即可

D1016讲解

题面 功能是从键盘输入5个整数,保存到一整型数组变量中(此数组只能保存5个数),并在屏幕上按逆序输出。

原码

#include<stdio.h>

int main(void)
{
	/*********Found*********/
	int n=5, i, a[n];

	printf("\ninput 5 numbers:");
	/*********Found*********/
	for (i=1; i<n; i++)
	{
		scanf("%d", &a[i]);
	}
	for (i=n-1; i>=0; i--)
	{
		printf("%d\t", a[i]);
	}

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	/*********Found*********/
	int n=5, i, a[5];

	printf("\ninput 5 numbers:");
	/*********Found*********/
	for (i=0; i<n; i++)
	{
		scanf("%d", &a[i]);
	}
	for (i=n-1; i>=0; i--)
	{
		printf("%d\t", a[i]);
	}

	return 0;
}

知识点

  • 这个题本身,在 C99 标准下,第一个行没有问题,但在 C89 标准下,需要在 [] 中使用常量
  • 数组的下标,从 0 开始

D1017讲解

题面 功能是输入10个浮点数,并输出这组数中的最大值和最小值。

原码

#include<stdio.h>

int main(void)
{
	float a[10], max, min;
	int i;

	printf("Please input 10 floats");
	for (i=0; i<10; i++)
	{
		/*********Found************/
		scanf("%f", _____);
	}
	max = min = a[0];
	for (i=1; i<10; i++)
	{
		/*********Found************/
		if (_____)
		{
			max = a[i];
		}
		if (min > a[i])
		{
			min = a[i];
		}
	}

	printf("Max number is:%.2f\nMin number is:%.2f\n", max, min);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	float a[10], max, min;
	int i;

	printf("Please input 10 floats");
	for (i=0; i<10; i++)
	{
		/*********Found************/
		scanf("%f", &a[i]);
	}
	max = min = a[0];
	for (i=1; i<10; i++)
	{
		/*********Found************/
		if (max < a[i])
		{
			max = a[i];
		}
		if (min > a[i])
		{
			min = a[i];
		}
	}

	printf("Max number is:%.2f\nMin number is:%.2f\n", max, min);

	return 0;
}

知识点

  • 输入数据时,要取内存地址
  • 打擂算法,直接求最大或是最小值,要注意判断方式

D1018讲解

题面 功能是通过函数,将一个字符串中的元音字母复制到另一字符串,然后输出。

原码

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

void vowel(char str1[], char str2[]);

int main(void)
{
	char str1[81], str2[81];

	printf("please input the string:\n");
	gets(str1);

	/*********Found************/
	vowel(________________);
	printf("the vowel string is:\n");
	puts(str2);
	if (strlen(str2) == 0)
	{
		printf("NONE!\n");
	}

	return 0;
}

void vowel(char str1[], char str2[])
{
	int i, j = 0;
	/*********Found************/
	for (i=0; ________________; i++)
	{
		if (str1[i]=='A' || str1[i]=='E' || str1[i]=='I'
			|| str1[i]=='O'	|| str1[i]=='U' || str1[i]=='a'
			|| str1[i]=='e'	|| str1[i]=='i' || str1[i]=='o'
			|| str1[i]=='u')
		{
			str2[j] = str1[i];
			j++;
		}
	}

	str2[j] = '\0';
}

改后

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

void vowel(char str1[], char str2[]);

int main(void)
{
	char str1[81], str2[81];

	printf("please input the string:\n");
	gets(str1);

	/*********Found************/
	vowel(str1,str2);
	printf("the vowel string is:\n");
	puts(str2);
	if (strlen(str2) == 0)
	{
		printf("NONE!\n");
	}

	return 0;
}

void vowel(char str1[], char str2[])
{
	int i, j = 0;
	/*********Found************/
	for (i=0; str1[i]!='\0'; i++)
	{
		if (str1[i]=='A' || str1[i]=='E' || str1[i]=='I'
			|| str1[i]=='O'	|| str1[i]=='U' || str1[i]=='a'
			|| str1[i]=='e'	|| str1[i]=='i' || str1[i]=='o'
			|| str1[i]=='u')
		{
			str2[j] = str1[i];
			j++;
		}
	}

	str2[j] = '\0';
}

知识点

  • 函数的声时,定义,调用,前后头部要一致
  • 调用函数时,传入的参数要符合要求,要匹配定义时的需要
  • 逐个字符判断是不是元音字母,从串头,到串尾标志符即可

D1019讲解

题面 功能是计算输出10个学生的平均成绩。

原码

#include<stdio.h>

/*****Found*****/
average(double x, y);

int main(void)
{
	int i;
	double score, total;
	double aver;

	printf("Please enter the 1's grade\n");
	scanf("%lf", &total);

	for (i=2; i<=10; i++)
	{
		printf("Please enter the %d's grade\n", i);
		scanf("%lf", &score);
		/*****Found*****/
		total = score;
	}
	aver = average(total, 10);
	printf("The average: %f\n", aver);

	return 0;
}

/*****Found*****/
average(double x, y)
{
	return x / y;
}

改后

#include<stdio.h>

/*****Found*****/
double average(double x, y);

int main(void)
{
	int i;
	double score, total;
	double aver;

	printf("Please enter the 1's grade\n");
	scanf("%lf", &total);

	for (i=2; i<=10; i++)
	{
		printf("Please enter the %d's grade\n", i);
		scanf("%lf", &score);
		/*****Found*****/
		total = score;
	}
	aver = average(total, 10);
	printf("The average: %f\n", aver);

	return 0;
}

/*****Found*****/
double average(double x, y)
{
	return x / y;
}

知识点

  • 函数的声明和定义,头部分要一致

D1020讲解

题面 功能是使用递归实现Fibonacci数的计算,Fn=Fn-1+Fn-2(1、1、2...,第7项为13)。

原码

#include<stdio.h>

int f(int n);

/*****Found*****/
int main(void);
{
	printf("F(7)=%d\n", f(7));

	return 0;
}

int f(int n)
{
	if (n <= 2)
	{
		/*****Found*****/
		return 2;
	}
	return f(n - 1) + f(n - 2);
}

改后

#include<stdio.h>

int f(int n);

/*****Found*****/
int main(void)
{
	printf("F(7)=%d\n", f(7));

	return 0;
}

int f(int n)
{
	if (n <= 2)
	{
		/*****Found*****/
		return 1;
	}
	return f(n - 1) + f(n - 2);
}

知识点

  • main 函数最常见的写法,之后不可能为;
  • fibo 数列,前两项为递归出口,值为 1,不是 2

D1021讲解

题面 功能是依次输出3^1到3^5。

原码

#include<stdio.h>

/*****Found*****/
int f(n);

int main(void)
{
	int i;

	for (i=1; i<=5; i++)
	{
		printf("%d\n", f(3));
	}

	return 0;
}

int f(int n)
{
	/*****Found*****/
	int p = 1;

	p = p * n;
	return p;
}

改后

#include<stdio.h>

/*****Found*****/
int f(int n);

int main(void)
{
	int i;

	for (i=1; i<=5; i++)
	{
		printf("%d\n", f(3));
	}

	return 0;
}

int f(int n)
{
	/*****Found*****/
	static int p = 1;

	p = p * n;
	return p;
}

知识点

  • 这里的 3^5 即累乘,需要函数本身记住之前上一次计算的结果,再参与下一次的计算
  • 使用静态变量,可以有记忆性,不会释放内存,就能在前一次计算结果的基础上再做相乘运算
  • 考查的知识点就是:静态变量

D1022讲解

题面 功能是通过一个加法子函数,输入两个浮点数,求和。

原码

#include<stdio.h>

/*********Found************/
int add(float x, float y);

int main(void)
{
	float a, b;

	scanf("%f%f", &a, &b);
	/*********Found************/
	printf("sum=%f\n", add(x, y));

	return 0;
}

/*********Found************/
float add(float x, float y);
{
	return x + y;
}

改后

#include<stdio.h>

/*********Found************/
float add(float x, float y);

int main(void)
{
	float a, b;

	scanf("%f%f", &a, &b);
	/*********Found************/
	printf("sum=%f\n", add(a, b));

	return 0;
}

/*********Found************/
float add(float x, float y)
{
	return x + y;
}

知识点

  • 函数的定义,要符合算法逻辑需求
  • 函数的实现,头之后不可能是; 而是体
  • 函数的调用,要传入实际,而不是给形参名

D1023讲解

题面 功能是函数outnum输出自己是第几次被调用。

原码

#include<stdio.h>

void outnum(void);

int main(void)
{
	int i;

	for (i=0; i<5; i++)
	{
		/*********Found************/
		outnum(i);
	}

	return 0;
}

void outnum(void)
{
	/*********Found************/
	int i = 0;

	i++;
	printf("%d\n", i);
}

改后

#include<stdio.h>

void outnum(void);

int main(void)
{
	int i;

	for (i=0; i<5; i++)
	{
		/*********Found************/
		outnum();
	}

	return 0;
}

void outnum(void)
{
	/*********Found************/
	static int i = 0;

	i++;
	printf("%d\n", i);
}

知识点

  • 静态变量的记忆性
  • 只初始化一次之后,以后的累加即++运算,均在前一次计算的结果上进行
  • 累加即可达到题目的目标:它调了多少次

D1024讲解

题面 功能是调用子函数Average()求两数的平均值,并输出到屏幕上。

原码

#include<stdio.h>

/*********Found*********/
int Average(x, y);

int main(void)
{
	int a = 12;
	int b = 24;
	int ave;

	/*********Found*********/
	ave = Average(int a, int b);
	printf("Average of %d and %d is %d.\n", a, b, ave);

	return 0;
}

/*********Found*********/
int Average(x, y)
{
	int result;

	result = (x + y) / 2;

	return result;
}

改后

#include<stdio.h>

/*********Found*********/
int Average(int x, int y);

int main(void)
{
	int a = 12;
	int b = 24;
	int ave;

	/*********Found*********/
	ave = Average(a, b);
	printf("Average of %d and %d is %d.\n", a, b, ave);

	return 0;
}

/*********Found*********/
int Average(int x, int y)
{
	int result;

	result = (x + y) / 2;

	return result;
}

知识点

  • 声明和定义时,要给出形参变量的类型
  • 调用时,直接传入参数变量本身即可

D1025讲解

题面 功能是输入一整数n(n>0),main()函数中调用子函数Func()n次,并在屏幕上打印出每次调用该子函数的次数。

原码

#include<stdio.h>

void Func(void);

int main(void)
{
	int i, n;

	printf("\ninput a data:");
	scanf("%d", &n);
	for (i=0; i<n; i++)
	{
		/*********Found*********/
		________________________
	}

	return 0;
}

void Func(void)
{
	/*********Found*********/
	________________________

	times++;
	printf("Func() was called %d time(s).\n", times);
}

改后


#include<stdio.h>

void Func(void);

int main(void)
{
	int i, n;

	printf("\ninput a data:");
	scanf("%d", &n);
	for (i=0; i<n; i++)
	{
		/*********Found*********/
		Func();
	}

	return 0;
}

void Func(void)
{
	/*********Found*********/
	static int times=0;

	times++;
	printf("Func() was called %d time(s).\n", times);
}

知识点

  • 静态变量的记忆性
  • 初始化一次,每次调用时,上一次的结果会记忆,因为内存不会释放
  • 可用于记录函数调用了多少次

D1030讲解

题面 功能是利用交换指针法将两个数按从大到小的顺序输出来。

原码

#include<stdio.h>

int main(void)
{
	int a, b, *p1, *p2, *p;

	printf("input a, b:");
	scanf("%d,%d", &a, &b);

	p1 = &a;
	p2 = &b;
	/*********Found************/
	if (p1 < p2)
	{
		p = p1; 
		p1 = p2; 
		p2 = p;
	}

	printf("a=%d b=%d\n", a, b);
	/*********Found************/
	printf("max=%d min=%d\n", p1, p2);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int a, b, *p1, *p2, *p;

	printf("input a, b:");
	scanf("%d,%d", &a, &b);

	p1 = &a;
	p2 = &b;
	/*********Found************/
	if (*p1 < *p2)
	{
		p = p1; 
		p1 = p2; 
		p2 = p;
	}

	printf("a=%d b=%d\n", a, b);
	/*********Found************/
	printf("max=%d min=%d\n", p1, p2);

	return 0;
}

知识点

  • 判断的是值,不是地址
  • *用于解引用指针,也就是获取指针指向的地址里的值,再用值进行比较
  • 保证 p1 指针指向大的值

D1034讲解

题面 功能是将指针变量p指向变量a,并通过指针变量p从键盘输入a的值,再输出到屏幕上。

原码

#include<stdio.h>

int main(void)
{
	int a;
	/*********Found************/
	float *p;

	p = &a;
	/*********Found************/
	scanf("%d", &p);
	printf("a=%d\n", *p);

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	int a;
	/*********Found************/
	int *p;

	p = &a;
	/*********Found************/
	scanf("%d", p);
	printf("a=%d\n", *p);

	return 0;
}

知识点

  • 指针本身就是地址
  • p 指向 a 的地址后,用 p 就是用&a

D1035讲解

题面 功能是输出数组中下标为偶数的字符。

原码

#include<stdio.h>

int main(void)
{
	/*********Found************/
	char yy[200] = "abcdefghijk";

	while (*yy != '\0')
	{
		putchar(*yy);
		/*********Found************/
		yy++;
		if ('\0' == *(yy-1))
		{
			break;
		}
	}

	return 0;
}

改后

#include<stdio.h>

int main(void)
{
	/*********Found************/
	char *yy = "abcdefghijk";

	while (*yy != '\0')
	{
		putchar(*yy);
		/*********Found************/
		yy=yy+2;
		if ('\0' == *(yy-1))
		{
			break;
		}
	}

	return 0;
}

知识点

  • 使用可以移动的指针变量,指向字符串,才可以用滑动指针的方式遍历检查相应的字符
  • 下标为偶数,则每次指针滑动 2 个单位
  • 注意,滑动 2 个单位,可能会越界,错过串尾,因此有一个回退的判断

D1047讲解

题面 功能是:从一个子函数中输入结构体信息并在主函数中输出。

原码

#include <stdio.h>
#include <stdlib.h>

struct aa
{
	int a;
	double b;
};

/*********Found************/
void Input(struct aa x);

int main(void)
{
	struct aa y;

	/*********Found************/
	Input(y);
	printf("%d %f\n", y.a, y.b);
	return 0;
}

/*********Found************/
void Input(struct aa x)
{
	char tmp[10];

	printf("请输入整型数a:");
	gets(tmp);
	x->a = atoi(tmp);
	printf("请输入单精度数b:");
	gets(tmp);
	x->b = atof(tmp);
}

改后

#include <stdio.h>
#include <stdlib.h>

struct aa
{
	int a;
	double b;
};

/*********Found************/
void Input(struct aa *x);

int main(void)
{
	struct aa y;

	/*********Found************/
	Input(&y);
	printf("%d %f\n", y.a, y.b);
	return 0;
}

/*********Found************/
void Input(struct aa *x)
{
	char tmp[10];

	printf("请输入整型数a:");
	gets(tmp);
	x->a = atoi(tmp);
	printf("请输入单精度数b:");
	gets(tmp);
	x->b = atof(tmp);
}

知识点

  • 需要修改传入的结构体变量,一定要传地址,不可以用传值的方式
  • 改函数声明和函数实现
  • 调用时,传入结构的地址

D1057讲解

题面 功能是:分别用变量名numA、指向变量numB的指针ptr输出变量numA和numB的值。

原码

#include <stdio.h>

int main(void)
{
	float numA, numB, *ptr;

	numA = 4.5;
	numB = 6.8f;
	/*********Found************/
	ptr = numB;
	/*********Found************/
	printf("numA=%f, numB=%f\n", numA, ptr);

	return 0;
}	

改后

#include <stdio.h>

int main(void)
{
	float numA, numB, *ptr;

	numA = 4.5;
	numB = 6.8f;
	/*********Found************/
	ptr = &numB;
	/*********Found************/
	printf("numA=%f, numB=%f\n", numA, *ptr);

	return 0;
}	

知识点

  • 指针的基本应用
  • 同型指针指向对应的变量的地址
  • 输出时,需要对指针进行解引用操作,即*

D1058讲解

题面 功能是:使用指针输出结构体变量stu1的成员name之值。

原码

#include <stdio.h>

int main(void)
{ 
	struct student
	{
		int num;
		char name[10];
		float score[3];
	} stu1 = {2012,  "WuHua",  {75.4f, 80, 92}}; 
	struct student *ptr;
	
	/*********Found************/
	ptr = stu1;
	/*********Found************/
	printf("%s\n", ptr.name);
	
	return 0;
}

改后

#include <stdio.h>

int main(void)
{ 
	struct student
	{
		int num;
		char name[10];
		float score[3];
	} stu1 = {2012,  "WuHua",  {75.4f, 80, 92}}; 
	struct student *ptr;
	
	/*********Found************/
	ptr = &stu1;
	/*********Found************/
	printf("%s\n", ptr->name);
	
	return 0;
}

知识点

  • 结构体指针变量,指向结构体变量的地址,要取地址
  • 在指向完成以后,用指针操作结构体时,就用指向运算符号 ->

D1067讲解

题面 功能是从键盘读入一个数到变量num中,再输出num的值到屏幕上。

原码

#include <stdio.h>

int main(void)
{
	/*********Found************/
	char ptr;
	int num;
	
	/*********Found************/
	ptr = num;

	printf("请输入一个数:");
	scanf("%d", ptr);
	printf("用户输入的数为:%d\n", num);
	
	return 0;
}

改后

#include <stdio.h>

int main(void)
{
	/*********Found************/
	int* ptr;
	int num;
	
	/*********Found************/
	ptr = &num;

	printf("请输入一个数:");
	scanf("%d", ptr);
	printf("用户输入的数为:%d\n", num);
	
	return 0;
}

知识点

  • 13 行没有错,则上面的变量 ptr 肯定是指针变量

  • 变量为 int,指针肯定为 int*

  • 完成指向时,就是取变量的地址,赋值给指针变量,指针就是存变量的地址的