2016
1. 函数指针
1.(10分)下面程序的功能是:从键盘读入某门课程的成绩,然后根据输入选项将其排序,输入1则按升序排序,输入2则降序排序;最后输出排序结果。下面程序中存在比较隐蔽的错误,请通过分析和调试程序,发现并改正程序中的错误。
注意:
(1)请将修改正确后的完整源程序拷贝粘贴到答题区内。
(2)对于没有错误的语句,请不要修改。
(3)当且仅当错误全部改正,且程序运行结果调试正确,才给加10分,部分正确不得分。
(4)改错时不能改变程序原有的意图,也不要改变代码的输入输出格式。
运行示例:
Input score:
98 97 88 78 99 57 -1
Total students are 6
Enter 1 to sort in ascending order
Enter 2 to sort in descending order
2
Data items in descending order
99 98 97 88 78 57
#include <stdio.h>
#include <stdlib.h>
#define N 20
int ReadScore(int score[]);
void PrintScore(int score[], int n);
void SelectionSort(int score[], int n, int (*compare)(int a, int b));
void Swap(int *x, int *y);
int Ascending(int a, int b);
int Descending(int a, int b);
int main()
{
int score[N],n;
int order;
n = ReadScore(score);
printf("Total students are %d\n",n);
printf("Enter 1 to sort in ascending order\n");
printf("Enter 2 to sort in descending order\n");
scanf("%d",&order);
if(order == 1)
{
SelectionSort(score, n, Ascending);
printf("Data items in asending order\n");
}
else
{
SelectionSort(score, n, Descending);
printf("Data items in descending order\n");
}
PrintScore(score, n);
return 0;
}
/*读入成绩以负数结束,返回实际输入的成绩个数*/
int ReadScore(int score[])
{
int i=-1;
printf("Input score:\n");
do
{
i++;
scanf("%d",score[i]);
}while (score[i]>=0);
return i;
}
void PrintScore(int score[], int n)
{
int i;
for(i=0; i<n; i++)
printf("%4d",score[i]);
printf("\n");
}
void SelectionSort(int score[], int n, int *compare(int a, int b))
{
int i, j, k;
for(i=0; i<n-1;i++)
{
k = i;
for(j = i+1; j< n; j++)
{
if((*compare)(score[i],score[k]))
{
k = j;
}
}
if(k!= i)
{
Swap(score[i],score[k]);
}
}
}
int Ascending(int a, int b)
{
return a < b;
}
int Descending(int a, int b)
{
return a > b;
}
void Swap(int *x, int *y)
{
int * temp;
*temp = *x;
*x = *y;
*y = *temp;
}
答
#include <stdio.h> #include <stdlib.h> #define N 20 int ReadScore(int score[]); void PrintScore(int score[], int n); void SelectionSort(int score[], int n, int (*compare)(int a, int b)); void Swap(int *x, int *y); int Ascending(int a, int b); int Descending(int a, int b);
int main() { int score[N],n; int order; n = ReadScore(score); printf("Total students are %d\n",n); printf("Enter 1 to sort in ascending order\n"); printf("Enter 2 to sort in descending order\n"); scanf("%d",&order);
if(order == 1) { SelectionSort(score, n, Ascending); printf("Data items in asending order\n"); } else { SelectionSort(score, n, Descending); printf("Data items in descending order\n"); } PrintScore(score, n);
return 0; } /*读入成绩以负数结束,返回实际输入的成绩个数*/ int ReadScore(int score[]) { int i=-1; printf("Input score:\n"); do { i++; scanf("%d",&score[i]); }while (score[i]>=0); return i; }
void PrintScore(int score[], int n) { int i; for(i=0; i<n; i++) printf("%4d",score[i]); printf("\n");
} void SelectionSort(int score[], int n, int (*compare)(int a, int b)) { int i, j, k; for(i=0; i<n-1;i++) { k = i; for(j = i+1; j< n; j++) { if((*compare)(score[j],score[k])) { k = j; }
} if(k!= i) { Swap(&score[i],&score[k]);
} } } int Ascending(int a, int b) { return a < b; } int Descending(int a, int b) { return a > b; } void Swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; } |
2.动态链表
(10分)创建动态链表并打印链表内容。要求通过键盘读入学生的学号和分数,当输入的学号为0时表示链表创建结束,并将读入的学生学号和成绩打印输出。下面程序中存在比较隐蔽的错误,请通过分析和调试程序,发现并改正程序中的错误。
注意:
(1)请将修改正确后的完整源程序拷贝粘贴到答题区内。
(2)对于没有错误的语句,请不要修改。
(3)当且仅当错误全部改正,且程序运行结果调试正确,才给加10分,部分正确不得分。
(4)改错时不能改变程序原有的意图,也不要改变代码的输入输出格式。
运行示例:
150301 65.5
150302 78
150303 87
150304 98.5
0 0
150301 65.50
150302 78.00
150303 87.00
150304 98.50
#include <stdio.h>
struct node
{
long num;
float score;
struct node *next;
}
int main()
{
struct node *head, *p, *q;
head = (struct node*)malloc(sizeof(struct node));
p = (struct node*)malloc(sizeof(struct node));
q = p;
head->next = p;
scanf("%ld%f", p->num, p->score );
while (p->num != 0)
{
q = (struct node*)malloc(sizeof(struct node));
p->next = q;
scanf("%ld%f", p->num, p->score);
}
p = head->next;
do
{
printf("%ld%.2f", p->num, p->score);
p = p->next;
}
while ( p->next == NULL );
free(p);
return 0;
}
答案:
要点:
1.赋值的最后, p.next = NULL 这句赋值语句很重要,否则循环不会结束;
2. 输入的while内部做出指针的连接做出了修改
3. 输出的while条件做出了更改;
#include <stdio.h> #include<stdlib.h> struct node { long num; float score; struct node *next; }; int main() { struct node *head, *p, *q;
head = (struct node*)malloc(sizeof(struct node)); p = (struct node*)malloc(sizeof(struct node)); q = p;
head->next = p; scanf("%ld%f", &(p->num), &(p->score) );
while (p->num != 0) { p = (struct node*)malloc(sizeof(struct node)); q->next = p; scanf("%ld%f", &(p->num), &(p->score) ); q=p; } p->next=NULL;
p = head->next; while(p->next) { printf("%ld %.2f\n", p->num, p->score); p = p->next; } free(p); return 0; } |
2014
1.(10分)编程统计候选人的得票数。 设有3个候选人, Li,Zhang,Fun。
要求输入投票总数n, 然后每次输入一个得票的候选人的名字( 区分大小写) , 若选民输错候选人姓名, 则按废票处理。
选民投票结束后程序自动显示各候选人的得票结果。
请通过分析和调试程序, 发现并改正程序中的错误。
注意: 将修改后的完整的源程序写在答题区内。
对于没有错误的语句, 请不要修改, 修改原本正确的语句也要扣分。
当且仅当错误全部改正, 且程序运行结果调试正确,
才给加10分, 如果只改正了部分错误, 则不加分。
程序运行示例如下:
输入
4
Li
Zhang
zha
Fun
输出
Li:1
Zhang:1
Fun:1
错误代码
#include <string.h>
struct person
{
char name[20];
int count;
} p
erson leader[3] = {"Li", 0, "Zhang", 0, "Fun", 0};
int main()
{
int i, j;
char leader_name[20];
scanf("%d\n", &n);
for (i = 0; i < n; i++)
{
scanf("%s", leader_name);
for (j = 0; j < 3; j++)
if (leader_name == leader[j].name)
leader[j].count++;
} p
rintf("\n");
for (i = 0; i < 3; i++)
printf("%5s:%d\n", leader[i].name, leader[i].count);
return 0;
}
正确代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person
{
char name[20];
int count;
};
// 结构体数组,双大括号
struct person leader[3] = {{"Li", 0},
{"Zhang", 0},
{"Fun", 0}};
int main()
{
int i, j, n;
char leader_name[20];
scanf("%d\n", &n);
for (i = 0; i < n; i++)
{
scanf("%s", leader_name);
for (j = 0; j < 3; j++)
{
// 字符串判断相等不能用==
if(strcmp(leader_name, leader[j].name) == 0)
{
leader[j].count++;
}
}
}
printf("\n");
for (i = 0; i < 3; i++)
printf("%5s:%d\n", leader[i].name, leader[i].count);
return 0;
}
2.(10分)大数的存储问题。
编程计算并输出1~n之间的所有数的阶乘。
其中n<=40, 由主函数从键盘读入。
**输入提示信息: "Input n:\n"
**输入格式要求: "%d"
**输出格式要求: "%d! = "
请通过分析和调试程序, 发现并改正程序中的错误。
注意: 将修改后的完整的源程序写在答题区内。
对于没有错误的语句, 请不要修改, 修改原本正确的语句也要扣分。
当且仅当错误全部改正, 且程序运行结果调试正确,
才给加10分, 如果只改正了部分错误, 则不加分。
程
序运行示例如下:
Input n:
20
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000
16! = 20922789888000
17! = 355687428096000
18! = 6402373705728000
19! = 121645100408832000
20! = 2432902008176640000
答案:
大数乘法,进位相关知识
#include <stdio.h>
#include <stdlib.h>
#define SIZE 51
int BigFact(int m, int data[]);
int main()
{
int data[SIZE]; /* 存储50位数, 为了方便记忆, 不使用data[0] */
int index; /* 表示阶乘值的位数 */
int n;
int i, j;
printf("Input n:\n");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
index = BigFact(i, data);
// 高位到低位依次输出
if (index != 0)
{
printf("%d! = ", i);
for (j = index; j > 0; j--)
{
printf("%d", data[j]);
}
printf("\n");
}
else
{
printf("Over flow!\n");
exit(1);
}
}
return 0;
}
int BigFact(int m, int data[])
{
int i;
int j, k;
int index = 1; // 位数
// data[]清0
for (i = 0; i < SIZE; i++)
{
data[i] = 0;
}
data[1] = 1;
for (i = 1; i <= m; i++)
{
for (j = 1; j <= index; j++)
{
data[j] = data[j] * i;
}
// 检测非最高位
for (k = 1; k < index; k++)
{
if (data[k] >= 10)
{
data[k + 1] = data[k + 1] + data[k] / 10;
data[k] = data[k] % 10; // 除法改成取余
}
}
// 检测最高位, 并增加进位
while (data[index] >= 10 && index <= SIZE - 1)
{
data[index + 1] = data[index] / 10;
data[index] = data[index] % 10;
index++; // 增加index++
}
}
if (index <= SIZE)
{
return index;
}
else
{
return 0;
}
}
2013
1. 闰年计算
1.(10分)输入某年某月某日,计算并输出它是这一年的第几天
(要求考虑闰年的问题)。
下面程序中存在比较隐蔽的错误,
请通过分析和调试程序,发现并改正程序中的错误。
注意:将修改后的完整的源程序写在答题区内。
对于没有错误的语句,请不要修改,修改原本正确的语句也要扣分。
当且仅当错误全部改正,且程序运行结果调试正确,
才给加10分,如果只改正了部分错误,则不加分。
答案:
闰年计算规则: 不能被100整除时能被4整除,或能给400整除
#include <stdio.h>
int DayofYear(int year, int month, int day);
int dayTab[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
int year, month, day, yearDay;
printf("Please enter year, month, day:\n");
scanf("%d,%d,%d", &year, &month, &day);
yearDay = DayofYear(year, month, day);
printf("yearDay = %d\n", yearDay);
return 0;
}
int DayofYear(int year, int month, int day)
{
int i;
for (i = 1; i < month; i++)
{
day += dayTab[i];
}
// 闰年考虑,不能被100整除时能被4整除,或能给400整除
if((year%100!=0 && year%4==0) || (year%400==0)) day++;
return day;
}
2. 贪心算法
.(10分)在一种室内互动游戏中,魔术师要每位观众心里想一个三位数abc
(a、b、c分别是百位、十位和个位数字),
然后魔术师让观众心中记下acb、bac、bca、cab、cba五个数
以及这5个数的和值。
只要观众说出这个和是多少,则魔术师一定能猜出观众心里想的原数abc是多少。
例如,观众甲说他计算的和值是1999,则魔术师立即说出他想的数是443,
而观众乙说他计算的和值是1998,则魔术师说:“你算错了!”。
请编程模拟这个数字魔术游戏。
下面程序中存在比较隐蔽的错误,
请通过分析和调试程序,发现并改正程序中的错误。
注意:将修改后的完整的源程序写在答题区内。
对于没有错误的语句,请不要修改,修改原本正确的语句也要扣分。
当且仅当错误全部改正,且程序运行结果调试正确,
才给加10分,如果只改正了部分错误,则不加分。
答案:
错误地方:
1. 关于sum求和的错误
2. if的等于是“==”而不是“=”
#include <stdio.h>
int Magic(int m);
int main()
{
int m, ret;
printf("Input a sum:\n");
scanf("%d", &m);
ret = Magic(m);
if (ret != 1)
{
printf("The sum you calculated is wrong!\n");
}
return 0;
}
int Magic(int m)
{
int a, b, c, n;
for (a = 0; a <= 9; a++)
{
for (b = 0; b <= 9; b++)
{
for (c = 0; c <= 9; c++)
{
n = 122 * a + 212 * b + 221 * c;
if (m == n)
{
printf("The number is %d\n", 100 * a + 10 * b + c);
return 1;
}
}
}
}
return -1;
}