Error[8]: Undefined offset: 206, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 114
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

上一篇:从0开始学c语言-28-qsort函数、 数组和指针参数、函数指针数组(转移表)、回调函数_阿秋的阿秋不是阿秋的博客-CSDN博客

目录

练习1:整型提升和截断练习

练习2:大小端

练习3:杨辉三角

练习4:打印菱形

练习5:猜凶手

练习6:猜名次

练习7:知识补充

练习8:求最小公倍数

方法1

方法2

练习9:倒置一句话的单词


练习1:整型提升和截断练习
[+++]

先不说结果,一步步分析

[+++]
[+++]
[+++]

所以,

[+++]
练习2:大小端
[+++]

我们先补齐一下a变量。

unsigned int a = 0x1234;
0x1234 ——> 0x00001234
[+++]

因为题目说是大端模式处理器,所以高字节位数字放到内存中的低地址。

那么内存中从低地址到高地址a的储存样子应该是(低地址)00001234(高地址)。

此时 &a 取到的是00 00 12 34当中00字节的地址,能够访问四个字节,又因为对&a进行了强制类型转换,那么便只能取到一个字节的内容,先读取低地址的,也就是00字节的地址。

然后对这个地址进行解引用存储到 char b 变量中。

所以 b=00 。

练习3:杨辉三角

这就是杨辉三角,但是这样看不好转换成代码来写,

我们换成这样。

[+++]

可以看到第一列和每行最后一个数字都是1,然后每行1和1中间的数字[+++],比如:6=3+3

6(1和1之间的数字)

3(6自己列上面一行的数字)

3(6自己列上面一行数字的前一列数字)

然后又观察到第一行一个数字,第二行两个数字,第n行就是n个数字了。

然后我就写出来了

[+++]

如果想打印成三角的样子,就试着学学接下来这道题来借鉴一下

练习4:打印菱形

[+++]
练习5:猜凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

[+++]
练习6:猜名次

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:

A选手说:B第二,我第三;

B选手说:我第二,E第四;

C选手说:我第一,D第二;

D选手说:C最后,我第三;

E选手说:我第四,A第一;

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

        代码中检查不能重复的函数代码是具有普适性的,这道题也可以投机取巧,去掉检查重复的函数,改为if条件语句(五个数相乘=120 也就等价于不重复)进行输出。

[+++]
练习7:知识补充

c语言本身是没有输入输出语句的,它只规定了各种语法规则,它是引用库函数里的输入输出函数,c语言知识规定了函数的参数、返回类型和功能,至于怎么实现的不重要,每个厂商自己实现。

练习8:求最小公倍数

正整数A和正整数B的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求A和B的最小公倍数。

输入:5 7 输出:35

其实在之前这个文章里我们说过最大公约数和最小公倍数的关系从0开始学c语言-过渡-练习之猜随机数字游戏、求最大公约数_阿秋的阿秋不是阿秋的博客-CSDN博客

最小公倍数=输入的两个数相乘 / 最大公倍数

方法1

这里我们先按照题目给的思路写一个:正整数A和正整数B的最小公倍数是指 能被A和B整除的最小的正整数值

int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	int m = a > b ? a : b; //找较大的数
	while (1)
	{
		if (m % a == 0 && m % b == 0)
		{
			printf("%d\n", m);
			break;
		}
		m++;
	}
	return 0;
}
方法2

最小公倍数=输入的两个数相乘 / 最大公倍数

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int max = a > b ? b : a;  //找两个数中较小的那个数
	while (1)
	{
		if (a % max == 0 && b % max == 0)
		{
			printf("最大公约数是:%d \n", max);
			break;
		}
		max--;
	}
    int p=(a*b)/max;
    printf("最小公倍数%d \n",p);
	return 0;
}

练习9:倒置一句话的单词

输入:I like games.

输出:games like I.

可以看到我们输入和输出的结果对比,标点都跟着倒置。

首先写个主函数

[+++]

然后写怎么翻转整个字符串的reverse函数

因为逆序字符串,那就需要传递字符串的地址和长度,分别用来改变字符串内容和确认字符串下标。

[+++]

然后考虑怎么逆序每个单词,要知道的是我们是用空格来划分单词的,那就很重要了。

利用好空格,来使用reverse函数就可以实现了。

在写逆序每个单词函数的时候,我发现上面的reverse函数不太好用了,得每次确定长度,确定长度还得自己想想该怎么设才正好,不如弄两个指针来作为reverse函数的参数方便。

reverse函数就改写成这样了。

[+++]

 这是我的思考过程,之后就很快写好了~

注意:我的表达式是以每次arr+i指向空格和\0位置为基础进行的运算,为的是确定这次的终点以及下次的起点。

#include 
#include 
#include 
void reverse(char* left, char*right)
{
	assert(left&&right);
	while (left'))
		{
			end = arr + i-1;
			reverse(ret, end);
			ret = end +2; //为了让下一个ret指向下次reverse的起点
		}
	}
}
int main()
{
	char arr[100] = { 0 };
	gets(arr); //scanf不读取空格
	int len = strlen(arr);
	//两步翻转法(左旋会用到三步翻转法
	//1·字符串整体逆序
	reverse(arr, arr+len-1);
	//2·每个单词逆序。
	reverse_word(arr, len);
	printf("%s\n", arr);
	return 0;
}

<===>)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
从0开始学c语言-29-数据储存练习、筑基期练习、两步翻转_C_内存溢出

从0开始学c语言-29-数据储存练习、筑基期练习、两步翻转

从0开始学c语言-29-数据储存练习、筑基期练习、两步翻转,第1张

上一篇:从0开始学c语言-28-qsort函数、 数组和指针参数、函数指针数组(转移表)、回调函数_阿秋的阿秋不是阿秋的博客-CSDN博客

目录

练习1:整型提升和截断练习

练习2:大小端

练习3:杨辉三角

练习4:打印菱形

练习5:猜凶手

练习6:猜名次

练习7:知识补充

练习8:求最小公倍数

方法1

方法2

练习9:倒置一句话的单词


练习1:整型提升和截断练习
int main()
{
  unsigned char a = 200;
  unsigned char b = 100;
  unsigned char c = 0;
  c = a + b;
  printf(“%d %d”, a+b,c);
  return 0;
}

先不说结果,一步步分析

unsigned char a = 200;
00000000 00000000 00000000 11001000 - 200的补码
11001000 - a
unsigned char b = 100;
00000000 00000000 00000000 01100100 - 100的补码
01100100 - b
11001000 - a
01100100 - b
c = a + b
//因为a和b不够int大小,所以在相加的时候需要进行整型提升
//而a和b都是无符号整型,所以高位补0
00000000 00000000 00000000 11001000 - a
00000000 00000000 00000000 01100100 - b
00000000 00000000 00000001 00101100 - a+b
//又因为c是无符号整型的char整型
//需要进行截断保存
00101100 - c

所以,

printf(“%d %d”, a+b,c);
a+b=300
c=44
练习2:大小端
unsigned int a = 0x1234;
unsigned char b = *(unsigned char *)&a;
在32位大端模式处理器上变量b等于?

我们先补齐一下a变量。

unsigned int a = 0x1234;
0x1234 ——> 0x00001234
unsigned char b = *(unsigned char *)&a;
0x00001234 - a

因为题目说是大端模式处理器,所以高字节位数字放到内存中的低地址。

那么内存中从低地址到高地址a的储存样子应该是(低地址)00001234(高地址)。

此时 &a 取到的是00 00 12 34当中00字节的地址,能够访问四个字节,又因为对&a进行了强制类型转换,那么便只能取到一个字节的内容,先读取低地址的,也就是00字节的地址。

然后对这个地址进行解引用存储到 char b 变量中。

所以 b=00 。

练习3:杨辉三角

这就是杨辉三角,但是这样看不好转换成代码来写,

我们换成这样。

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

可以看到第一列和每行最后一个数字都是1,然后每行1和1中间的数字(共三种情况),比如:6=3+3

6(1和1之间的数字)

3(6自己列上面一行的数字)

3(6自己列上面一行数字的前一列数字)

然后又观察到第一行一个数字,第二行两个数字,第n行就是n个数字了。

然后我就写出来了

#define ROW 10
#define RAN 10
int main()
{
	//int ROW, RAN;
	//scanf("%d %d", &ROW, &RAN);
	//int arr[ROW][RAN]; //这样输入值的数组不行,因为创建数组的数值必须是常量

	int arr[ROW][RAN]; //这样定义的就行
	int i = 0;
	int j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j <= i; j++)
		{
			if ((0 == j) || (i == j))
			{
				arr[i][j] = 1;
			}
			else
			{
				arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
			}
		}
	}
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j <= i; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

如果想打印成三角的样子,就试着学学接下来这道题来借鉴一下

练习4:打印菱形

int main()
{
	int line = 0;
	int i = 0;
	scanf("%d", &line);//7

	//打印上半部分
	for (i = 0; i < line; i++)
	{
		//打印一行
		//打印空格
		int j = 0;
		for (j = 0; j < line - 1 - i; j++)
		{
			printf(" ");
		}
		//打印*
		for (j = 0; j < 2 * i + 1; j++)//奇数
		{
			printf("*");
		}
		printf("\n");
	}

	//打印下半部分
	for (i = 0; i < line - 1; i++)
	{
		//打印一行
		int j = 0;
		for (j = 0; j <= i; j++)
		{
			printf(" ");
		}
		for (j = 0; j < 2 * (line - 1 - i) - 1; j++)
		{
			printf("*");
		}
		printf("\n");
	}
	return 0;
}
练习5:猜凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

int main()
{
	int killer = 0;
	for (killer = 'A'; killer <= 'D'; killer++)
	{
		if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3)
		{
			printf("%c\n", killer);
		}
	}
	return 0;
}
练习6:猜名次

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:

A选手说:B第二,我第三;

B选手说:我第二,E第四;

C选手说:我第一,D第二;

D选手说:C最后,我第三;

E选手说:我第四,A第一;

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

        代码中检查不能重复的函数代码是具有普适性的,这道题也可以投机取巧,去掉检查重复的函数,改为if条件语句(五个数相乘=120 也就等价于不重复)进行输出。

int checkData(int *p)
{
	int tmp[7] = { 0 }; //标记表,实际是哈希表的思路。一开始每个元素都是0。
	int i;
	for (i = 0; i < 5; i++)
	{
		if (tmp[p[i]]) //如果这个位置的标记已经是1,则代表重复,直接返回0。
		{
			return 0;
		}
		tmp[p[i]] = 1; //如果不是,则给这个位置标记为1。
	}
	return 1; //全部标记完毕也没有出现重复的情况,代表OK。
}

int main()
{
	int p[5]; //0 1 2 3 4分别代表a b c d e

	for (p[0] = 1; p[0] <= 5; p[0]++)
	{
		for (p[1] = 1; p[1] <= 5; p[1]++)
		{
			for (p[2] = 1; p[2] <= 5; p[2]++)
			{
				for (p[3] = 1; p[3] <= 5; p[3]++)
				{
					for (p[4] = 1; p[4] <= 5; p[4]++) //五层循环遍历
					{
                    //这里是五个人的描述,由于比较表达式只有0和1两个结果,如果要两个条件
//有且只有一个为真,则可以用比较表达式的值总和为1的方式直接判定。别忘了还要判定不能并列。
						if ((p[1] == 2) + (p[0] == 3) == 1 && //B第二,我第三
							(p[1] == 2) + (p[4] == 4) == 1 && //我第二,E第四
							(p[2] == 1) + (p[3] == 2) == 1 && //我第一,D第二
							(p[2] == 5) + (p[3] == 3) == 1 && //C最后,我第三
							(p[4] == 4) + (p[0] == 1) == 1 && //我第四,A第一
							checkData(p) //不能并列
							)
						{
							for (int i = 0; i < 5; i++)
							{
								printf("%d ", p[i]);
							}
							putchar('\n');
						}
					}
				}
			}
		}
	}

	return 0;
}
练习7:知识补充

c语言本身是没有输入输出语句的,它只规定了各种语法规则,它是引用库函数里的输入输出函数,c语言知识规定了函数的参数、返回类型和功能,至于怎么实现的不重要,每个厂商自己实现。

练习8:求最小公倍数

正整数A和正整数B的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求A和B的最小公倍数。

输入:5 7 输出:35

其实在之前这个文章里我们说过最大公约数和最小公倍数的关系从0开始学c语言-过渡-练习之猜随机数字游戏、求最大公约数_阿秋的阿秋不是阿秋的博客-CSDN博客

最小公倍数=输入的两个数相乘 / 最大公倍数

方法1

这里我们先按照题目给的思路写一个:正整数A和正整数B的最小公倍数是指 能被A和B整除的最小的正整数值

int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	int m = a > b ? a : b; //找较大的数
	while (1)
	{
		if (m % a == 0 && m % b == 0)
		{
			printf("%d\n", m);
			break;
		}
		m++;
	}
	return 0;
}
方法2

最小公倍数=输入的两个数相乘 / 最大公倍数

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int max = a > b ? b : a;  //找两个数中较小的那个数
	while (1)
	{
		if (a % max == 0 && b % max == 0)
		{
			printf("最大公约数是:%d \n", max);
			break;
		}
		max--;
	}
    int p=(a*b)/max;
    printf("最小公倍数%d \n",p);
	return 0;
}

练习9:倒置一句话的单词

输入:I like games.

输出:games like I.

可以看到我们输入和输出的结果对比,标点都跟着倒置。

首先写个主函数

int main()
{
	char arr[100] = { 0 };
	gets(arr); //scanf不读取空格
	int len = strlen(arr);
	//两步翻转法(左旋会用到三步翻转法
	//1·字符串整体逆序
	//2·每个单词逆序。
    return 0;
}

然后写怎么翻转整个字符串的reverse函数

因为逆序字符串,那就需要传递字符串的地址和长度,分别用来改变字符串内容和确认字符串下标。

void reverse(char* arr, int len)
{
	assert(arr);
	int left = 0;
	int right = len - 1;
	while (left

然后考虑怎么逆序每个单词,要知道的是我们是用空格来划分单词的,那就很重要了。

利用好空格,来使用reverse函数就可以实现了。

在写逆序每个单词函数的时候,我发现上面的reverse函数不太好用了,得每次确定长度,确定长度还得自己想想该怎么设才正好,不如弄两个指针来作为reverse函数的参数方便。

reverse函数就改写成这样了。

void reverse(char* left, char*right)
{
	assert(left&&right);
	while (left

 这是我的思考过程,之后就很快写好了~

注意:我的表达式是以每次arr+i指向空格和\0位置为基础进行的运算,为的是确定这次的终点以及下次的起点。

#include 
#include 
#include 
void reverse(char* left, char*right)
{
	assert(left&&right);
	while (left'))
		{
			end = arr + i-1;
			reverse(ret, end);
			ret = end +2; //为了让下一个ret指向下次reverse的起点
		}
	}
}
int main()
{
	char arr[100] = { 0 };
	gets(arr); //scanf不读取空格
	int len = strlen(arr);
	//两步翻转法(左旋会用到三步翻转法
	//1·字符串整体逆序
	reverse(arr, arr+len-1);
	//2·每个单词逆序。
	reverse_word(arr, len);
	printf("%s\n", arr);
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/3002266.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-27
下一篇 2022-09-27

发表评论

登录后才能评论

评论列表(0条)