C程序设计(谭浩强第五版)第六章习题精解。C语言课后习题解析。C语言考研,C语言专升本,C语言期末考试,初学C语言,程序设计基础,编程题必备。C语言第四章:选择结构程序设计编程题解析。

C程序设计(谭浩强第五版)第章习题精解

第六章:利用数组处理批量数据目录:

用筛选法求100之内的素数

2.用选择法对10个整数排序

3.求一个3 X 3的整形矩阵对角线元素之和

4.有一个已经排好序的数组,要求输入一个数后,按原来顺序的规律 将它插入数组中

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

6.输出一下的杨慧三角(要求输出10行)

7.输出"魔方阵"。所谓魔方阵是指这样的方阵,它的每一行、每一列 和对角线之和均相等。例如:

8.找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。

9. 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求 用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组 中,则输出"无此数"。

10.有一篇文章,共有3行文字,每行有80个字符。要求分别统计出 其中英文大写字母、小写字母、数字、空格以及其他字符的个数。

10.输出以下图案:

11.有一行电文,以按下面规律译成密码:

12.编一程序,将两个字符串连接起来,不要用strcat函数

13.编写一个程序,将两个字符串s1和s2比较,如果s1 > s2,输出一 个整数;若s1 = s2,输出0;若s1 < s2,输出一个负数。不要用 strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相对应字符的ASCII码的差值。例 如,"A"和“C”相比,由于"A" < "C",应输出负数,同时由 于‘A’与‘C’的ASCII码差值为2,因此应输出"-2"。同理:“And” 和"Aid"相比较,根据第2个字符比较结果,"n"比"i"大5,因此应输 出"5"。

14.编写一个程序,将字符数组s2中的全部字符复制到字符数组s1 中,不用strcpy函数。复制时,‘\0’也要赋值过去。'\0'之后的字符不 复制。


第六章:利用数组处理批量数据

  1. 用筛选法求100之内的素数

A解题思路

筛选法:

  1. 首先定义一个整形数组,存放1-100的数字

  2. 当发现其中一个数不是素数时,将其标记为0

  3. 循环结束后将未被标记为0的数输出即可。

B代码部分

#include<Stdio.h>

void main()

{

int a[100];

int i,j;

for (i = 0; i < 100; i++)

{

a[i] = i + 1;//赋初值

for (j = 2; j < a[i]; j++)

if (a[i] % j == 0)

a[i] = 0;

if (a[i] != 0)

printf("%d是素数\n", a[i]);

}

}

C执行结果

2.用选择法对10个整数排序

A解题思路

只需记住选择排序核心代码即可:

for(i=0;i<10;i++)

for(j=i+1;j<10;j++)

if (a[i] > a[j])

{

int tmp = a[i];

a[i] = a[j];

a[j] = tmp;

}

B代码部分

#include<Stdio.h>

int i, j;

void sort(int a[])

{

for(i=0;i<10;i++)

for(j=i+1;j<10;j++)

if (a[i] > a[j])

{

int tmp = a[i];

a[i] = a[j];

a[j] = tmp;

}

}

void main()

{

int a[10];

printf("请输入10个需要排序的整数:\n");

for (i = 0; i < 10; i++)

scanf("%d", &a[i]);

sort(a);

printf("使用选择法拍完序后为:\n");

for (i = 0; i < 10; i++)

printf("%d ", a[i]);

}

C执行结果

3.求一个3 X 3的整形矩阵对角线元素之和

A解题思路

  1. 先输入一个3*3的矩阵

  2. 第一个对角线是行和列都相同

  3. 第二个对角线是行从0-2,列为2-行。

  4. 算出后相加即可。

B代码部分

#include<stdio.h>

void main()

{

int i, j;

int a[3][3];

printf("请输入一个3行3列的整形矩阵:\n");

for (i = 0; i < 3; i++)

for (j = 0; j < 3; j++)

scanf("%d", &a[i][j]);

int sum1 = 0, sum2 = 0;

for (i = 0; i < 3; i++)

{

sum1 += a[i][i];

sum2 += a[i][2 - i];

}

printf("两个对角线的和为:%d", sum1 + sum2);

}

C执行结果

4.有一个已经排好序的数组,要求输入一个数后,按原来顺序的规律 将它插入数组中

A解题思路

  1. 先输入1个数给x

  2. End变量是指数组的最后一个元素的下标-1,

  3. 当end>0且当前数>x时,就将该数移动到其后面一个元素

  4. 循环结束后,将该位置补上输入的数即可

B代码部分

#include<stdio.h>

void main()

{

int x;

int a[10] = { 1,2,3,4,5,6,7,9,10 };

printf("请输入一个数:");

scanf("%d", &x);

int end = 8;

while (end >= 0 && a[end] > x)

{

a[end + 1] = a[end];

end--;

}

a[end+1] = x;

for (x = 0; x < 10; x++)

printf("%d ", a[x]);

}

C执行结果

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

A解题思路

本题采用第一个和最后一个数进行交换,然后再逐次往里遍历,直到最左边的数大于等于最右边的数时,不再发生数据交换。

B代码部分

#include<stdio.h>

void main()

{

int s[5];

int x = sizeof(s)/4;

int i;

printf("请输入%d个值:", x);

for (i = 0; i < x; i++)

scanf("%d", &s[i]);

int left = 0, right = x-1;

while (left < right)//用于进行数据交换

{

int tmp = s[left];

s[left] = s[right];

s[right] = tmp;

left++;

right--;

}

printf("倒着拍完序的数组为:");

for (i = 0; i < x; i++)

printf("%d ", s[i]);

}

C执行结果

6.输出一下的杨慧三角(要求输出10行)

A解题思路

仔细观察杨慧三角可以看到: 第0列和对角线上的数据全部为1,其余位置上的数据为上一行正对数据与上一行正对前一个数据之和。

比如: a[4][2] = a[3][2] + a[3][1]

得出公式:a[i][j] = a[i - 1][j] + a[i - 1][j - 1];

B代码部分

#include<stdio.h>

void main()

{

int i, j,a[10][10];

for(i=0;i<10;i++)

for (j = 0; j <= i; j++)

{

if(i==j||j==0)

a[i][j] = 1;//第0列和对角线上的数据全部为1

}

for (i = 0; i < 10; i++)

for (j = 0; j <= i; j++)

{

if(a[i][j]!=1)

a[i][j] = a[i - 1][j] + a[i - 1][j - 1];//其余位置上的数据为上一行正对数据与上一行正对前一个数据之和。

}

for (i = 0; i < 10; i++)//输出

{

for (j = 0; j <= i; j++)

printf("%-5d", a[i][j]);

printf("\n");

}

}

C执行结果

7.输出"魔方阵"。所谓魔方阵是指这样的方阵,它的每一行、每一列 和对角线之和均相等。例如:

8   1   6

3   5   7

4   9   2

A解题思路

首先我们来了解一下魔方阵的生成方法:

1.先把第0行中间置为1.

2.下一个元素放在当前元素的上一行,下一列。

x = a[i - 1][j + 1]

3.如果上一行,下一列已有元素,则下一个元素存放在当前列的下一行。

x = a[i + 1][j]

4.把矩阵看成是回绕的(像个球卷起来那样)

if i<0 i = 最后一行

if j>size j = 0

最后大家可以直接去看代码部分,基本上每一步我都标注了相关注释,程序易读性很高。

B代码部分

#include<stdio.h>

void main()

{

int n;//用于表示魔方阵的阶数

printf("请输入一个3-100之间的奇数,用于做魔方阵的阶数:");

scanf("%d", &n);

int a[100][100] = { 0 };//先定义一个阶数最大为100的未赋值的魔方阵。

int row, col;//定义两个变量用于存放魔方阵的行和列

int prerow, precol ;//定义两个变量用来存放当前行和列的值

row = 0;

col = n / 2;

a[row][col] = 1;//1.先把第0行中间的元素置为1.

int i, j;

for (i = 2; i <= n * n; i++)//因为已经赋值了一个1,所以i从2开始,需要赋值n*n-1次

{

row--;

col++;//2.下一个元素放在当前元素的上一行,下一列。

if (row < 0)

row = n - 1;//如果行是第-1行,就把他换成最后一行

if (col >= n)

col = 0;//如果列到达了-1列(也就是超过了最后一列),就将其置为第1列

//4.这两句的功能是把矩阵看成是回绕的(像个球卷起来那样)

if (a[row][col] != 0)//3.如果上一行,下一列已有元素,则下一个元素存放在当前列的下一行。

{

row = prerow + 1;//prerow是当前行+1就是下一行。

col = precol;//precol是当前列,不用变化。

}

a[row][col] = i;//这句代码是给魔方阵赋值的唯一语句,经过上面的3个if条件后,到这里进行相应的赋值。

prerow = row;

precol = col;//记录下来当前行和列的值

}

for (i = 0; i < n; i++)//用于输出已赋值后的n阶魔方阵

{

for (j = 0; j < n; j++)

printf("%-4d", a[i][j]);

printf("\n");

}

}

C执行结果

8.找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。

A解题思路

例子:

9 6 8 70

10 23 55 66

15 67 4 69

其中66为鞍点并且唯一。

鞍点:即该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。

B代码部分

#include<stdio.h>

void main()

{

int a[3][4] = { {9,6,8,70},{10,23,55,66},{15,67,4,69} };

int i, j,k;

int max;

int j2;

int flat = 0;//标志变量,0代表没有找到,1代表找到了

for (i = 0; i < 3; i++)

{

max = a[i][0];

for (j = 0; j < 4; j++)//先找出该行上最大的值

{

if (max < a[i][j])

{

max = a[i][j];

j2 = j;//找到该行上最大元素后记录下当前所在列的下标

}

}

for (k = 0; k < 3; k++)//判断max是不是该列最小值,不是就退出这个循环

{

if (a[k][j2] < max)

{

break;

}

}

if (k == 3)//如果上面的循环正常结束,说明k=3,就是找到鞍点了,输出即可

{

printf("找到鞍点了,是:%d", max);

flat = 1;

}

}

if (flat == 0)

{

printf("没有找到鞍点!");

}

}

C执行结果

9. 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求 用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组 中,则输出"无此数"。

A解题思路

  1. 首先定义一个有序数组

  2. 输入要查找的数

  3. 定义函数使用二分查找方式找出该数的位置

二分查找核心代码:

while (left <= right)

{

int mid = (left + right) / 2;

if (a[mid] == x)

{

printf("找到了,该数为数组中第%d个元素。", mid + 1);

break;

}

else if (a[mid] > x)

right = mid - 1;

else if (a[mid] < x)

left = mid + 1;

}

4.如果循环正常结束,也就是left>right输出无此数。

B代码部分

#include<stdio.h>

void find(int a[], int x,int r)

{

int left = 0;

int right =r;

while (left <= right)

{

int mid = (left + right) / 2;

if (a[mid] == x)

{

printf("找到了,该数为数组中第%d个元素。", mid + 1);

break;

}

else if (a[mid] > x)

right = mid - 1;

else if (a[mid] < x)

left = mid + 1;

}

if (left > right)

printf("无此数!");

}

void main()

{

int a[15] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};

int r = sizeof(a) / 4 - 1;//用于计算整型数组下标最大值,此步骤无法在函数里计算。

printf("请输入要查找的数》:");

int x;

scanf("%d", &x);

find(a, x,r);

}

C执行结果

10.有一篇文章,共有3行文字,每行有80个字符。要求分别统计出 其中英文大写字母、小写字母、数字、空格以及其他字符的个数。

A解题思路

  1. 定义一个3行80列的字符型数组用于存放3行文字,每行有80个字符。

  2. 使用gets函数输入这3行文字

  3. 使用双重for循环进行遍历,外层用于遍历行数,内层用于遍历每行有多少字符。

  4. 根据所求值定义相应的变量和条件,计算完后进行输出即可。

B代码部分

#include<stdio.h>

void main()

{

char str[3][80] = { 0 };//共有3行文字,每行有80个字符。

int i;

for (i = 0; i < 3; i++)//输入这3行文字

{

printf("请输入第%d行文字:", i + 1);

gets(str[i]);

}

//英文大写字母、小写字母、数字、空格以及其他字符的个数

int big, small, num, speace, other;

big = small = num = speace = other = 0;

int j=0;

for(i=0;i<3;i++)

for (j = 0; str[i][j]; j++)//双重循环进行遍历

{

if (str[i][j] >= 'A' && str[i][j] <= 'Z')

big++;

else if (str[i][j] >= 'a' && str[i][j] <= 'z')

small++;

else if (str[i][j] >= '0' && str[i][j] <= '9')

num++;

else if (str[i][j] == ' ')

speace++;

else

other++;

}

printf("英文大写字母:%d、小写字母:%d、数字:%d、空格:%d,其他字符:%d", big, small, num, speace, other);

}

C执行结果

10.输出以下图案:

* * * *
  * * * *
    * * * *
      * * * *
        * * * *

A解题思路

  1. 观察发现,此图案有5行,每行都有* * * *

  2. 找出规律,第二行比第一行多2个空格在前面,第3行比第二行多2个空格在前面...

  3. 使用双重循环进行输出

  4. 外层循环用于控制输出的行数

  5. 内层循环用于控制输出的空格数

B代码部分

#include<stdio.h>

void main()

{

int i, j;

for (i = 0; i < 5; i++)//外层循环用于控制输出的行数

{

for (j = 0; j < i; j++)//内层循环用于控制输出的空格数

{

printf(" ");

}

printf("* * * *\n");

}

}

C执行结果

11.有一行电文,以按下面规律译成密码:

  1. >Z a->z

  2. B->Y b->y

  3. C->X c->x

  4. …。

即第1个字母编程第26个字母,第i个字母编程第(26-i+1)个字母,非字母字符不变,要求编程序将密码 译回原文,并输出密码和原文。

A解题思路

  1. 首先我们根据题目给出的规律得出以下编码公式:

  2. 26-(ch-’A/a’)-1

  3. 26是一共26个字母,(ch-’A/a’)是指从A/a开始数是正数第几个数,这样26-(ch-’A/a’)就等于与之相对应的倒数第几个数,为什么要-1?因为数组下标是从0开始,为了防止转变后下标越界,我们需要-1保持平衡。

  4. 编码和解码规则相同,将所给密码的每个字符区分大小写然后代入公式,注意,因为这个公式算出的是由正数第几个转变为倒数第几个,所以我们如果想正常输出的话还需要在其前面加上起始数A/a

  5. 得出最终公式为:

  6. 大写str='A'+(26 - (str- 'A') - 1);小写str='a'+ (26 - (str[i] - 'a') - 1);

B代码部分

#include<stdio.h>

void main()

{

char str[128] = { 0 };

printf("请输入一串密码:");

gets(str);

printf("你输入的密码为:%s\n", str);

int i=0;

while (str[i])

{

if (str[i] >= 'A' && str[i] <= 'Z')

str[i] = 'A'+(26 - (str[i] - 'A') - 1);

else if (str[i] >= 'a' && str[i] <= 'z')

str[i] ='a'+ (26 - (str[i] - 'a') - 1);

i++;

}

printf("破译后的原文为:%s", str);

}

C执行结果

12.编一程序,将两个字符串连接起来,不要用strcat函数

A解题思路

  1. 首先遍历到第一个字符串的末尾

  2. 将第二个字符串的第一个值开始赋值到第一个字符串的最后一个值+1处,如此往后

  3. 赋值完成后给第一个字符串加上’\0’结束符

  4. 将第一个字符串输出即可。

B代码部分

#include<stdio.h>

void mystrcat(char str1[], char str2[])

{

int i, j;

for (i = 0; str1[i]; i++)

;

for (j = 0; str2[j]; j++)

str1[i++] = str2[j];

str1[i] = '\0';

puts(str1);

}

void main()

{

char str1[123] ="abcd";

char str2[123] = "efg";

printf("请输入两个字符串:\n");

gets(str1);

gets(str2);

mystrcat(str1, str2);

}

或者下面这个是不赋值结束符的表示,代码更少一些,不过没有上面那个易懂。

void mystrcat(char str1[], char str2[])

{

int i, j;

for (i = 0; str1[i]; i++)

;

for (j = 0; str1[i++] = str2[j]; j++)

;

puts(str1);

}

void main()

{

char str1[123] ="abcd";

char str2[123] = "efg";

mystrcat(str1, str2);

}

C执行结果

13.编写一个程序,将两个字符串s1和s2比较,如果s1 > s2,输出一 个整数;若s1 = s2,输出0;若s1 < s2,输出一个负数。不要用 strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相对应字符的ASCII码的差值。例 如,"A"和“C”相比,由于"A" < "C",应输出负数,同时由 于‘A’与‘C’的ASCII码差值为2,因此应输出"-2"。同理:“And” 和"Aid"相比较,根据第2个字符比较结果,"n"比"i"大5,因此应输 出"5"。

A解题思路

1,输入2个字符串

2.逐个遍历这两个字符串相对应的每个元素,如果相等继续判断下一个

3.遇到不相等的元素直接返回差值即可。

B代码部分

#include<stdio.h>

void mystrcmp(char s1[], char s2[])

{

int i=0;

while (s1[i]||s2[i])

{

if (s1[i] - s2[i] == 0)

i++;

else

{

printf("%d", s1[i] - s2[i]);

break;

}

}

}

void main()

{

char s1[10], s2[10];

gets(s1);

gets(s2);

mystrcmp(s1, s2);

}

C执行结果

14.编写一个程序,将字符数组s2中的全部字符复制到字符数组s1 中,不用strcpy函数。复制时,‘\0’也要赋值过去。'\0'之后的字符不 复制。

A解题思路

1,输入2个字符串

2,使用循环逐个遍历并复制,

3,当遇到第二个字符串的结束符时停止复制,且此时结束符也复制到第一个字符串中了。

B代码部分

#include<stdio.h>

void mystrcpy(char s1[], char s2[])

{

int i=0,j=0;

while (s1[i++] = s2[j++]);

}

void main()

{

char s1[12], s2[12];

gets(s1);

gets(s2);

mystrcpy(s1, s2);

puts(s1);

}

C执行结果

  • 3
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

立志冲海大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值