C语言程序与设计第四版课后习题 - 第六章(二)

6.6 逆序存放数组

题目概述:

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

题目思路:
  • 本题只需要知道数组的最后一个元素即可
    • 用最后的元素和最初的元素交换,如何访问到数组最后一个元素?就要使用到sizeof了
      • sizeof关键字:是C语言的关键字,是可以计算类型或者变量大小的,同时也可以计算数组的大小
        • 我们只需要知道,sizeof(数组名):计算的是整个数组的大小,单位是字节,比如说本题,sizeof(arr),
          • int arr[5]:有5个元素,每个元素类型都是int类型,所以得出数组总大小为:5*4=20
        • 然后我们在计算sizeof(arr[0]):计算的是数组中元素个数的类型,单位是字节,比如说arr[0]是int类型,也就是4个字节
        • 最后我们sizeof(arr) / sizeof(arr[0])得出数组元素个数,也就是5,放入sz变量中
  • 然后就好做了,但是arr[sz]就是数组的最后一个元素吗?数组下标是从0开始的,所以arr[sz-1]才是真正的数组最后一个元素
  • 由于循环完了一次i++,那么arr[1]就要跟arr[sz-1]的前一个元素交换顺序,但是我们应该如何交换呢?我们可以直接arr[sz-1-i],那么当i=0的时候,arr[0]就跟arr[5-1-0]交换,也就是arr[0] 和 arr[4],当i=1的时候,arr[1]和arr[5-1-1]交换,也就是arr[1]和arr[3]...以此类推
  • 最后,由于是两两交换,所以我们不需要遍历整个数组,只要遍历半个就能完成交换,否则遍历完整个数组会把逆序的又逆回来,得到的还是86541
代码实现:
c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
/*将一个数组中的值按逆序重新存放。例如,原来顺序为 8,6,5,4,1。要求改为 1,4,5,6,8*/
int main()
{
	int arr[] = { 8,6,5,4,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int temp = 0;

	for (i = 0; i < sz / 2; i++)
	{
		temp = arr[i];
		arr[i] = arr[sz - 1 - i];
		arr[sz - 1 - i] = temp;
	}

	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

运行结果如下:

6.7 输出图案

题目概述:

输出如下图案:

题目思路:
  • 由图得,我们发现后面星号空格组合是不变的,变的是前面的空格,所以我们只需要处理前面的空格即可
  • 我们可以划一条线计算一下每一行空格的数量

由图可得,推出公式:空格数量是2i

代码实现:
c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	int i = 0;
	int j = 0;

	for (i = 0; i < 5; i++)
	{
		for (j = 0; j < 2 * i; j++)
		{
			printf(" ");
		}
		printf("* * * * *\n");
	}



	return 0;
}

运行结果如下:

6.8 短文统计字符

题目概述:

有一篇短文,共有 3 行文字,每行有 80 个字符。想统计出其中英文大写字母,小写字母,数字、空格以及其他字符各有多少个。

题目思路:
  • 本题难点在输入数据
  • 因为我们输入的是字符串,定义了一个char类型的数字,但是我们是不能用scanf输入的,原因是:
    • scanf在输入字符\字符串时当遇到空格的时候就认为结束输入,导致后面的数字无法读入。
    • 就算那是scanf可以输入整个字符串,我们也不可能一个一个遍历(j = 0;j<80;j++)输入吧,这个时候就需要用到gets函数
  • gets函数:
    • C 库函数 char *gets(char *str) 从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。当读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
    • 只要知道gets函数是输入字符串的,遇到'\0'就结束
代码实现:
c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
/*有一篇短文,共有 3 行文字,每行有 80 个字符。
想统计出其中英文大写字母,小写字母,数字、空格以及其他字符各有多少个。*/
#include <stdio.h>
int main()
{
	char ch[3][80] = { '0' };
	int i = 0;
	int j = 0;
	int upper = 0;
	int lower = 0;
	int number = 0;
	int other = 0;
	int space = 0;

	for (i = 0; i < 3; i++)
	{
		gets(ch[i]);
	}

	for (i = 0; i < 3; i++)
	{
		for (j = 0; ch[i][j] != '\0'; j++)
		{
			if (ch[i][j] >= 'A' && ch[i][j] <= 'Z')
			{
				upper++;
			}
			else if (ch[i][j] >= 'a' && ch[i][j] <= 'z')
			{
				lower++;
			}
			else if (ch[i][j] >= '0' && ch[i][j] <= '9')
			{
				number++;
			}
			else if (ch[i][j] == ' ')
			{
				space++;
			}
			else
			{
				other++;
			}
		}
	}

	printf("upper:%d\n", upper);
	printf("lower:%d\n", lower);
	printf("num:%d\n", number);
	printf("space:%d\n", space);
	printf("other:%d\n", other);

	return 0;
}

6.9 翻译密码

题目概述:

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

A->Z a->z

B->Y b->y

C->X c->x

即第 1个字母变成第 26 个字母,第 2个字母变成第 25 个字母,第i个字母变成第(26-i+1)个字母。非字母字符不变。假如已知道密码是 Umtorhs,要求编程序将密码译回原文,并输出密码和原文。

题目思路:
  • 本题感觉也是找规律,我们看ASCII码表

看大写字母部分,65-90就是大写字母的部分,加起来再减去密文,就能得到大写字母解码的部分,本题其实可以将65+90加起来到代码上,但是为了更清晰,采用了'A'+'Z'

对于小写字母,97-122就是小写字母部分,加起来再减去密文,就能得到小写字母解码部分

代码实现:
c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	char ch[100] = { '0' };

	gets(ch);

	int i = 0;
	for (i = 0; ch[i] != '\0'; i++)
	{
		if (ch[i] >= 'A' && ch[i] <= 'Z')
		{
			ch[i] = 'A' + 'Z' - ch[i];
		}
		else if (ch[i] >= 'a' && ch[i] <= 'z')
		{
			ch[i] = 'a' + 'z' - ch[i];
		}
		else {
			ch[i] = ch[i];
		}
	}

	printf("%s", ch);


	return 0;
}

运行结果如下:

6.10 拼接字符串

题目概述:

编写一程序,将两个字符串连接起来,

  • 用 strcat 函数
  • 不用 strcat 函数
题目思路:
Part 1 用strcat函数

首先知道这个函数的用法

  • 声明

    • 下面是 strcat() 函数的声明。

      char *strcat(char *dest, const char *src)

  • 参数

    • dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。

    • src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。

  • 本题的目标数组就是s1,追加的字符串就是s2

代码实现:

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
	char s1[100] = { '0' };
	char s2[50] = { '0' };

	gets(s1);
	gets(s2);
	strcat(s1, s2);
	printf("%s", s1);


	return 0;
}

运行结果如下:

Part2 不用strcat函数
  • 如果不用函数的话,我们就要先找到s1字符串的末尾,我们只需要用一个循环查找就行,当i不满足条件时,那么s1[i]就指向了s1'\0'处
  • 然后就可以把s2的字符串拷贝到s1处了,也就是一个一个字符的拷贝过去,知道遇到'\0';
  • 但是需要注意,s1拷贝完了之后后面是缺了一个'\0'的,所以我们要认为的加上去

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	char s1[100] = { '0' };
	char s2[50] = { '0' };
	int i = 0;
	int j = 0;

	gets(s1);
	gets(s2);
	
	while (s1[i] != '\0')
	{
		i++;
	}

	while (s2[j] != '\0')
	{
		s1[i] = s2[j];
		i++;
		j++;
	}

	s1[i] = '\0';

	printf("%s", s1);

	return 0;
}
相关推荐
pigzhouyb几秒前
指针学习-
java·学习·算法
励志成为大佬的小杨16 分钟前
初始c语言第一个c语言项目
c语言·c++·算法
叫我阿呆就好了34 分钟前
C 实现植物大战僵尸(二)
c语言·开发语言
雾月551 小时前
LeetCode 1768 交替合并字符串
算法·leetcode·职场和发展
Milk夜雨1 小时前
C语言中的贪心算法
c语言·开发语言·数据结构·算法·ios
哥谭居民00011 小时前
普通的树形数据primevue的treetable组件的treetable[ ]
前端·javascript·算法
SunkingYang1 小时前
C/C++应该如何使用NI-488.2库?
c语言·c++·协议·ni·使用方法·设备·gpib
序属秋秋秋2 小时前
《数据结构》期末考试测试题【上】
数据结构·算法·链表·单元测试
ALISHENGYA2 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(for循环语句)(三)
数据结构·c++·算法
初阳7852 小时前
11. 日常算法
算法