题目1,选做:
假设 int n = 0xCAFE;
请用表达式完成下面操作 (拓展题:不要求每个同学都写)
(a) 测试最后 4 位中是不是最少有 3 位为 1.
(b) 逆转字节序(i.e.,使 n = 0xFECA)
(c) 旋转 4 位 (i.e., 使 n = 0xECAF)
答案代码/补:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
bool is_three(int a);
int feca(int a);
int ecaf(int a);
int main(void) {
int n = 0xCAFE;
printf("%.4x\n", n);
if (is_three(n)) {
printf("yes\n");
}
else {
printf("nono\n");
}
printf("%.4x\n", feca(n));
printf("%.4x\n", ecaf(n));
return 0;
}
bool is_three(int a) {
int mask = a & 0xf; //只看后四位
//printf("%.4x\n", mask);
if (mask == 0x7 || mask == 0xb || mask > 0xc) {
return true;
}
else {
return false;
}
}
int feca(int a) {
//0xCAFE
int temp1 = a & 0xff; //temp1=0x00fe
int temp2 = a & 0xff00; //temp2=0xca00
temp1 <<= 8; //temp1=0xfe00
temp2 >>= 8; //temp2=0x00ca
return temp1 | temp2;
}
int ecaf(int a) {
//0xCAFE
int temp1 = a & 0xf; //temp1=0x000e
int temp2 = a & 0xfff0; //temp2=0xcaf0
temp1 <<= 12; //temp1=0xe000
temp2 >>= 4; //temp2=0x0caf
return temp1 | temp2;
}
参考答案:
(a)
&
int x = n & 0xF; x == 0x7 || x == 0xB || x >= 0xD; 1111, 1110, 1101, 1011, 0111 F E D B 7
(b)
(n & 0xFF) << 8; 0xFE00 n >> 8; 0x00CA ((n & 0xFF) << 8) | (n >> 8);
(c)
(n & 0xF) << 12; 0xE000 (n >> 4); 0x0CAF ((n & 0xF) << 12) | (n >> 4);
题目二,必做:
(a) 目前使用的格里高利历闰年的规则如下:
-
公元年分非4的倍数,为平年。
-
公元年分为4的倍数但非100的倍数,为闰年。
-
公元年分为100的倍数但非400的倍数,为平年。
-
公元年分为400的倍数为闰年。
请用一个表达式判断某一年是否为闰年。
(b) 输入某一天的年月日,输出下一天的年月日。
(c) 输入某两天的年月日,输出这两天的相距多少天(不考虑公元前,且第一个日期比第二个日期要早)。
(d) 已知1970年1月1日是星期四,输入之后的某一天的年月日,判断它是星期几?
答案代码:个人
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
/*
(d) 已知1970年1月1日是星期四,输入之后的某一天的年月日,判断它是星期几?*/
bool is_leap(int t_year);
void tomorrow(int t_year, int t_mon, int t_day,bool judge);
int interval1( int t_mon, int t_day, bool judge);
int interval2( int t_mon, int t_day, bool judge);
int interval3(int t_year,int s_year);
int main(void) {
int t_year, t_mon, t_day;
int s_year, s_mon, s_day;
printf("第一个问题:insert date\n");
scanf("%d%d%d", &t_year,&t_mon,&t_day);
bool judge = is_leap(t_year);
if (judge==true) {
printf("%d is leap year.\n", t_year);
}
else {
printf("%d is not leap year.\n", t_year);
}
tomorrow(t_year, t_mon, t_day, judge);
printf("第二个问题:insert first date\n");
scanf("%d%d%d", &t_year, &t_mon, &t_day);
printf("insert second date\n");
scanf("%d%d%d", &s_year, &s_mon, &s_day);
judge = is_leap(t_year);
bool judge1 = is_leap(s_year);
int days01 = interval1( t_mon, t_day, judge);
int days02 = interval2(s_mon, s_day, judge1);
int days03 = interval3(t_year,s_year);
int result_days = days01 + days02 + days03;
printf("%d\n", days01);
printf("%d\n", days02);
printf("%d\n", days03);
printf("%d-%d-%d between %d-%d-%d has %d\n", t_year, t_mon, t_day, s_year, s_mon, s_day, result_days);
printf("第三个问题:insert one date affter 1970,01,01\n");
scanf("%d%d%d", &t_year, &t_mon, &t_day);
judge = is_leap(1970);
judge1 = is_leap(t_year);
days01 = interval1(1, 1, judge);
days02 = interval2(t_mon, t_day, judge1);
days03 = interval3(1970, t_year);
result_days = days01 + days02 + days03;
printf("%d\n", days01);
printf("%d\n", days02);
printf("%d\n", days03);
printf("1970-1-1 between %d-%d-%d has %d\n", t_year, t_mon, t_day, result_days);
result_days %= 7;
switch (result_days) {
case 0:printf("周4\n"); break;
case 1:printf("周5\n"); break;
case 2:printf("周6\n"); break;
case 3:printf("周7\n"); break;
case 4:printf("周1\n"); break;
case 5:printf("周2\n"); break;
case 6:printf("周3\n"); break;
}
return 0;
}
//是否是闰年
bool is_leap(int t_year) {
bool judge = false;
if ((t_year % 4 == 0 && t_year % 100 != 0) || (t_year % 400 == 0)) {
//printf("%d is leap year.\n", t_year);
judge = true;
}
//else {
// printf("%d is not leap year.\n", t_year);
//}
return judge;
}
//明天
void tomorrow(int t_year, int t_mon, int t_day, bool judge) {
int aff_year=t_year, aff_mon=t_mon, aff_day=t_day;
int month[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (judge == true) {
month[1] = 29;
}
if (month[t_mon-1] == t_day) {
aff_day = 1;
if (t_mon == 12) {
aff_year =t_year+ 1;
aff_mon = 1;
}
else {
aff_mon +=1;
}
}
else {
aff_year = t_year;
aff_mon = t_mon;
aff_day += 1;
}
printf("tomorrow is %d %d %d\n\n", aff_year, aff_mon, aff_day);
}
//第一年剩余时间
int interval1( int t_mon, int t_day, bool judge) {
int days = 0;
int month[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (judge == true) {
month[1] = 29;
}
int i = 0;
for (i = 0; i < t_mon-1; i++) {
days += month[i];
}
if (judge==true) {
days = 366 - (days + t_day);
}
else {
days = 365 - (days + t_day);
}
return days;
}
//最后一年度过时间
int interval2(int t_mon, int t_day, bool judge) {
int days = 0;
int month[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (judge == true) {
month[1] = 29;
}
int i = 0;
for (i = 0; i < t_mon - 1; i++) {
days += month[i];
}
days += t_day;
return days;
}
//中间年份时间
int interval3(int t_year, int s_year) {
int days03=0;
int i = t_year + 1;
for (i = t_year + 1; i <= s_year-1; i++) {
bool judge = is_leap(i);
if (judge == true) {
days03 += 366;
}
else {
days03 += 365;
}
}
return days03;
}
参考答案:
(a)
bool isLeapYear(int year) { return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0); }
(b)
int daysOfMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; void setDaysOfFeb(int year) { if (isLeapYear(year)) { daysOfMonth[2] = 29; } else { daysOfMonth[2] = 28; } } int main(void) { int year, month, day; scanf("%d%d%d", &year, &month, &day); day++; setDaysOfFeb(year); if (day > daysOfMonth[month]) { day = 1; month++; } if (month > 12) { month = 1; year++; } printf("%4d/%.2d/%2d\n", year, month, day); return 0; }
(c)
int daysOfMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int distance(int year1, int month1, int day1, int year2, int month2, int day2) { int days = 0; // 计算year1还剩多少天 setDaysOfFeb(year1); days += daysOfMonth[month1] - day1; for (int i = month1 + 1; i <= 12; i++) { days += daysOfMonth[i]; } // 计算中间年份的天数 for (int i = year1 + 1; i < year2; i++) { days += 365; if (isLeapYear(i)) { days++; } } // 计算year2过了多少天 setDaysOfFeb(year2); for (int i = 1; i < month2; i++) { days += daysOfMonth[i]; } days += day2; // 如果 year1 == year2, 那么多算了一整年 if (year1 == year2) { days -= 365; if (isLeapYear(year1)) { days--; } } return days; }
(d)
int weekday(int year, int month, int day) { int days = distance(1970, 1, 1, year, month, day); return (4 + days) % 7; }