三日一练-C语言百题(007)
Posted 嵌入式AIoT君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三日一练-C语言百题(007)相关的知识,希望对你有一定的参考价值。
进制转换:16进制转10进制代码
svx_str.h
#ifndef __SVX_STR_H #define __SVX_STR_H 1 #include <stdint.h> #include <sys/types.h> #ifdef __cplusplus extern "C" #endif uint32_t svx_str_tirm(char *str); uint32_t svx_str_split(char *str, char c, char *str1, size_t len1, char *str2, size_t len2); uint32_t svx_str_suffix_dateandtime(const char *src_str, char *des_str, unsigned int des_size); uint32_t svx_str_to_uint8(char *str, uint8_t *i); uint32_t svx_str_to_int8(char *str, int8_t *i); uint32_t svx_str_to_uint16(char *str, uint16_t *i); uint32_t svx_str_to_int16(char *str, int16_t *i); uint32_t svx_str_to_uint32(char *str, uint32_t *i); uint32_t svx_str_to_int32(char *str, int32_t *i); uint32_t svx_str_to_uint64(char *str, uint64_t *i); uint32_t svx_str_to_int64(char *str, int64_t *i); #ifdef __cplusplus #endif #endif
svx_str.c
#include <ctype.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <stdint.h> #include <time.h> #include <errno.h> #include "svx_str.h" uint32_t svx_str_tirm(char *str) size_t len = 0; char *head = NULL; char *tail = NULL; if(NULL == str) return 1; if(\'\\0\' == (*str)) return 0; len = strlen(str); head = str; tail = str + len - 1; /* find head */ while(*head && isspace(*head)) head++; if(!(*head)) *str = \'\\0\'; return 0; /* find tail */ while(head != tail && isspace(*tail)) tail--; /* get length */ len = tail - head + 1; /* cut string */ if(head == str) *(str + len) = \'\\0\'; else memmove(str, head, len); *(str + len) = \'\\0\'; return 0; uint32_t svx_str_suffix_dateandtime(const char *src_str, char *des_str, unsigned int des_size) time_t t = time(0); struct tm *tt; char *fmt =(char *)malloc(strlen(src_str)+25); if(fmt == NULL) return 1; if( des_size < (strlen(src_str) + 25) ) return 1; memset(fmt,0,strlen(src_str)+25); strcat(fmt, src_str); strcat(fmt,"_%Y-%m-%d_%H-%M-%S"); time(&t); tt = localtime(&t); strftime(des_str, strlen(src_str)+25, fmt,tt); free(fmt); return 0; uint32_t svx_str_split(char *str, char c, char *str1, size_t len1, char *str2, size_t len2) char *p; if(NULL == str || NULL == str1 || 0 == len1 || NULL == str2 || 0 == len2) return 1; /* find char c */ p = str; while(*p && *p != c) p++; if(!(*p)) return 1; *p = \'\\0\'; strncpy(str1, str, len1); p++; strncpy(str2, p, len2); return 0; uint32_t svx_str_to_uint8(char *str, uint8_t *i) unsigned long tmp; if(NULL == str) return 1; tmp = strtoul(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && ULONG_MAX == tmp) || (tmp > UINT8_MAX)) return 1; *i = (uint8_t)tmp; return 0; uint32_t svx_str_to_int8(char *str, int8_t *i) long tmp; if(NULL == str) return 1; tmp = strtol(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && (LONG_MIN == tmp || LONG_MAX == tmp)) || (tmp > INT8_MAX || tmp < INT8_MIN)) return 1; *i = (int8_t)tmp; return 0; uint32_t svx_str_to_uint16(char *str, uint16_t *i) unsigned long tmp; if(NULL == str) return 1; tmp = strtoul(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && ULONG_MAX == tmp) || (tmp > UINT16_MAX)) return 1; *i = (uint16_t)tmp; return 0; uint32_t svx_str_to_int16(char *str, int16_t *i) long tmp; if(NULL == str) return 1; tmp = strtol(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && (LONG_MIN == tmp || LONG_MAX == tmp)) || (tmp > INT16_MAX || tmp < INT16_MIN)) return 1; *i = (int16_t)tmp; return 0; uint32_t svx_str_to_uint32(char *str, uint32_t *i) unsigned long tmp; if(NULL == str) return 1; tmp = strtoul(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && ULONG_MAX == tmp) || (tmp > UINT32_MAX)) return 1; *i = (uint32_t)tmp; return 0; uint32_t svx_str_to_int32(char *str, int32_t *i) long tmp; if(NULL == str) return 1; tmp = strtol(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && (LONG_MIN == tmp || LONG_MAX == tmp)) || (tmp > INT32_MAX || tmp < INT32_MIN)) return 1; *i = (int32_t)tmp; return 0; uint32_t svx_str_to_uint64(char *str, uint64_t *i) unsigned long long tmp; if(NULL == str) return 1; tmp = strtoull(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && UINT64_MAX == tmp) || (tmp > UINT64_MAX)) return 1; *i = (uint64_t)tmp; return 0; uint32_t svx_str_to_int64(char *str, int64_t *i) long long tmp; if(NULL == str) return 1; tmp = strtoll(str, (char **)NULL, 10); if((EINVAL == errno && 0 == tmp) || (ERANGE == errno && (INT64_MIN == tmp || INT64_MAX == tmp)) || (tmp > INT64_MAX || tmp < INT64_MIN)) return 1; *i = (int64_t)tmp; return 0;
C语言每日一练——第61天:掷骰子游戏
C语言每日一练
2021年11月21日
实现掷骰子小游戏
在开始今天的练习前,我先写一个有趣的C语言小游戏——掷骰子(zhì tóu zi)
实现原理
大家对骰子应该不陌生,让我们先看看百度词条的介绍:
掷骰子
拼音:zhì tóu zi
骰子: 既色子,用象牙、骨头或塑料等较坚硬物体做的小四方块;每面刻有点数,一到六,常用一对做各种游戏或赌博。
掷骰子:先摇动骰子,然后抛掷使两个骰子都随意停止在一平面上。
——百度百科
掷骰子时,每次能掷出的点数为1~6
,且是随机的,那么如何用C语言来产生这一随机数呢?
这时就要用到rand()
和srand()
函数了:
srand函数是随机数发生器的初始化函数。原型:
void srand(unsigned int seed)
;
srand
和rand()
配合使用产生伪随机数序列。
- rand():
原型:int rand(void)
,
功能:产生随机值,从srand (seed)
中指定的seed
开始,返回一个[seed, RAND_MAX(0x7fff))
间的随机整数。- srand():
原型:void srand(unsigned seed)
,
参数:seed
是rand()
的种子,用来初始化rand()
的起始值。
功能:可以认为rand()
在每次被调用时,它都会查看srand(seed)
中指定的seed值,如果存在srand(seed)
,那么它会自动调用srand(seed)
一次来初始化它的起始值。如果用户在此之前没有调用过srand(seed)
,它会自动调用srand(1)
一次。——百度百科
上面提到了rand()
函数只能生成伪随机数,意思是如果起始值seed
固定,那么每次程序运行,它产生的随机数序列都是相同的,而不是真正意义上的随机数。形象地说,如果seed
值固定,那每次程序运行,第一次掷到的点数都是固定的,这显然不合理,那怎么生成更加合理的随机数呢?
补充:
种子在每次启动计算机时是随机的,但是一旦计算机启动以后它就不再变化了;也就是说,每次启动计算机以后,种子就是定值了,所以根据公式推算出来的结果(也就是生成的随机数)就是固定的。——http://c.biancheng.net/view/2043.html
我们都知道系统的时间值(总秒数)是时刻都在变化着的,如果把时间秒数当做随机数的种子seed
,那岂不是能实现真正的随机数?答案是方法可行,但并不能产生真正的随机数,因为时间是递增的,是有规律的数字序列,所以产生的随机数也会呈现一定的规律,但是,此时的随机数已经足够我们用来完成掷骰子游戏了,所以我们也没必要去纠结是否是真正的随机数(可能计算机本来就无法产生真正随机数)。
要想获取系统时间秒数,需要用到time()
函数:
time() 是指返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数的函数,主要用来获取当前的系统时间,返回的结果是一个time_t类型。
time_t time(time_t *t);
如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。
——百度百科
time_t
的原型就是long int
,这个函数的实现原理我们也没必要去深究,我们只要清楚它能返回秒数就足够了。
程序中,我们可以通过下面的语句初始化随机数种子和产生随机数:
srand((unsigned)time(NULL)); //用系统秒数初始化随机数种子
ret = rand(); //产生随机数,赋值给ret变量
现在生成了随机数,那如何将随机数转换成骰子的点数呢?
骰子一般都是正方体,有6个面,正面朝上的即为点数,那么它就有6种点数,分别是1~6
,我们将刚才生成的随机数对6取余,即可将随机数限定在0~5
之间,再加上1,就是我们要的随机点数了:
ret = rand() % 6 + 1; //ret即为随机点数
源码介绍
原理介绍完了,接下来直接上代码
代码由两个部分构成:
- 菜单打印:打印功能选择,显示上次投骰子的结果
- 操作选择:选择掷骰子或退出退出程序
#include <stdio.h>
#include <stdlib.h> //srand()/rand()
#include <time.h> //time()
int main()
char choice = '\\0'; //菜单选择
int ret = 0;
//用系统秒数初始化随机数种子
srand((unsigned)time(NULL));
while(1)
/* 1.菜单打印 */
system("cls"); //清屏--Windows系统
printf("======================\\n");
printf("| 掷骰子游戏 |\\n");
printf("| 1:掷骰子 0:退出 |\\n");
if(ret)
printf("| 上轮点数:%d |\\n", ret);
printf("======================\\n");
/* 2.操作选择 */
printf("请选择>>>>>>>\\n");
scanf(" %c", &choice); //输入选择
//" %c" 可以吃前面的空格和回车
while(getchar() != '\\n'); //吃掉除choice外其它字符
ret = 0; //初始化点数
switch(choice)
case '0':
printf("Goodbye!\\n");
return 0; //退出
//掷骰子(产生1 ~ 6 随机数)
case '1':
ret = rand() % 6 + 1;
break;
default: printf("无效选择!\\n");
return 0;
效果展示
今日练习
题目描述
骰子是一个有六个面的正方体,每个面分别印有1〜6之间的小圆点代表点数。假设这个游戏的规则是:两个人轮流掷骰子6次,并将每次投掷的点数累加起来。点数多者获胜;点数相同则为平局。
要求编写程序模拟这个游戏的过程,并求出玩100盘之后谁是最终的获胜者。
问题分析
思路可以参照前面掷骰子小游戏的实现原理。
实现步骤:两层循环,外层循环100次,内层循环6次,每次都将他们掷骰子的点数进行累加,最后总点数大的即为赢家,如果点数相同,则平局。
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
int sum_1 = 0, sum_2 = 0;
int i = 0, j = 0;
//用系统秒数初始化随机数种子
srand((unsigned)time(NULL));
for(i = 0; i < 100; i++)
for(j = 0; j < 6; j++)
//获取骰子点数
sum_1 += rand() % 6 + 1;
sum_2 += rand() % 6 + 1;
printf("甲的总点数:%d\\n", sum_1);
printf("乙的总点数:%d\\n", sum_2);
if(sum_1 > sum_2)
printf("甲获胜!\\n");
else if(sum_1 == sum_2)
printf("平局...\\n");
else
printf("乙获胜!\\n");
return 0;
运行结果
由于掷骰子点数是随机的,所以获胜者也是随机的。
结果1:
结果2:
把他们掷骰子次数调为1
,试了n次之后,终于平局了😂
以上是关于三日一练-C语言百题(007)的主要内容,如果未能解决你的问题,请参考以下文章