1. 计算机人群中颇为流行的一个笑话是“我29岁,但我不告诉你这个数字的基数!”如果基数是16,这个人实际上是41岁。编写一个程序,接受一个年龄作为命令行参数,并在2~36的范围中计算那个字面值小于等于29的最小基数。例如,如果用户输入41,程序应该计算出这个最小基数为16。因为在十六进制中,十进制41的值是29。
解析:
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char **argv ){
int result_value;
int initial_value;
int result_base;
result_value = atoi( *++argv );
printf( "result_value = %d\n", result_value );
initial_value = 29;
while( initial_value >= 10 ){
int dec = initial_value / 10;
int unit = initial_value % 10;
int flag = 0;
int base = 2;
while( base <= 36 ){
int compute_value = dec * base + unit;
if( compute_value > result_value ){
break;
} else if( compute_value == result_value ){
result_base = base;
flag = 1;
break;
}
++base;
}
if( flag == 1 ){
break;
}
--initial_value;
}
printf( "result_base = %d, initial_value = %d\n", result_base, initial_value );
return EXIT_SUCCESS;
}
输出:
2.编写一个函数,通过返回一个范围为1~6的随机整数来模拟掷骰子。注意,这6个值出现的概率应该相同。当这个函数第一次调用时,它应该用当天的当前时间作为种子来产生随机数。
解析:
除了“概率相等”这个要求,这个问题的其他部分非常简单。这里有个例子。普通情况下你将把一个随机数对6取模,产生一个0~5的值,将这个值加上1并返回。但是,如果随机数生成函数所返回的最大值是32767,那么这些值就不是“概率相等”。从0~32765返回的值所产生的0~5之间各个值的概率是相等。但是,最后两个值(32766和32767)的返回值将分别是0和1,这使它们的出现概率有所增加(是5462/32768而不是5461/32768)。由于我们需要的答案的范围很窄,因此这个差别是非常小的。如果这个函数试图产生一个范围在1和30000之间的随机数,那么前2768个值的出现概率将是后面那些值的两倍。程序中的循环用于消除这种错误,方法是一旦出现最后两个值,就产生另一个随机值。
解析:
/*
** 通过返回一个范围为1~6的值,模拟掷一个六边的骰子。
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
** 计算将产生6作为骰子值的随机数生成函数所返回的最大数。
*/
#define MAX_OK_RAND (int)((((long)RAND_MAX + 1) / 6 ) * 6 - 1)
int throw_die( void );
int main( void ){
printf( "RAND_MAX = %d, MAX_OK_RAND = %d\n", RAND_MAX, MAX_OK_RAND );
printf( "%d %d %d", throw_die(), throw_die(), throw_die() );
return EXIT_SUCCESS;
}
int throw_die( void ){
static int is_seeded = 0;
int value;
if( !is_seeded ){
is_seeded = 1;
srand( (unsigned int)time( NULL ) );
}
do{
value = rand();
} while( value > MAX_OK_RAND );
return value % 6 + 1;
}
输出:
3. 编写一个程序,以一种3岁小孩的方式来说明当前的时间(例如,时针在5上面,分钟在12上面)。
解析:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void ){
time_t t;
struct tm *ptm;
t = time( NULL );
ptm = localtime( &t );
printf( "at present, hour hand locates on the %d digit, minute hand locates on the %d digit.\n",
ptm->tm_hour, ptm->tm_min );
return EXIT_SUCCESS;
}
输出:
4. 编写一个程序,接受3个整数为命令行参数,把它们分别解释为月(1~12),日(1~31)和年(0~?)。然后,它应该打印这个日子是星期几(或将是星期几)。对于那个范围的年份,这个程序的结果才是正确的?
解析:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( int argc, char **argv ){
const char *weekday[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int year;
int month;
int day;
int week;
month = atoi( *++argv );
day = atoi( *++argv );
year = atoi( *++argv );
week = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
printf( "week = %s\n", weekday[week + 1] );
return EXIT_SUCCESS;
}
输出:
5. 冬天的天气预报常常会给出“风寒”(wind chill)这个词,它的意思是一个特定的温度或风速所感觉到的寒冷度。例如,如果气温为摄氏-5度(华氏23度),并且风速美妙10米(22.37mph,即每小时22.37英里),那么风寒度便是摄氏-22.3度(华氏-8.2度)。编写一个函数,使其使用下面的原型计算风寒度。
double wind_chill( double temp, double velocity );
temp是摄氏气温的度数,velocity是风速(米/秒)。函数返回摄氏形式的风寒度。
风寒度使用下面的公式计算的:
对于一个给定的气温和风速,这个公式给出在风速为4mph(风寒度标准)的情况下产生相同寒冷度的温度。V是以米/秒计的风速,t是33-temp,也就是中性皮肤温度(摄氏33度)和气温之间的温度差。常量A=10.45,B=10,C=-1。X=1.78816,它是4mph转换为米/秒的值。常量A=10.45,B=10,C=-1。X=1.78816,它是4mph转换为米/秒的值。
解析:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
double wind_chill( double temp, double velocity );
int main( void ){
double temp;
double velocity;
double result;
temp = -5.0;
velocity = 10.0;
result = wind_chill( temp, velocity );
printf( "temp = %.1f, velocity = %.1f, result = %.1f\n", temp, velocity, result );
return EXIT_SUCCESS;
}
double wind_chill( double temp, double velocity ){
const double var_a = 10.45;
const double var_b = 10.0;