C和指针 第七章 习题

时间:2024-12-19 00:07:14

  7.1 hermite递归函数

int hermite(int n, int x)
{
if (n <= 0) {
return 1;
} if (n == 1) {
return 2 * x;
} return 2 * x * hermite(n - 1, x) - 2 * (n - 1) * hermite(n - 2, x);
}

7.2两个整型值M和N(m、n均大于0)的最大公约数计算公式:

gcd(M,N)

当M % N = 0;  N

当M % N =R, R > 0; gcd(N,R)

unsigned int gcd(unsigned int M, unsigned int N)
{
if (M % N == 0) {
return N;
} unsigned int R;
R = M % N;
return gcd(N, R);
}

7.3 为原型编写函数定义,

int ascii_to_interger(char *string)

每遇到一位数,把当前总值乘以10,加上遇到的数。

int ascii_to_interger(char *string)
{
static total = 0;
int num = *string - '0'; //到达字符串末尾或遇到非法字符直接返回总计值
if (*string == '\0' || (*string - '0' > 9)) {
return total;
} //每遇到一个数,把当前值乘以10,加上遇到的数
total = 10 * total + num; //string右进一位
return ascii_to_interger(string + 1);
}

7.4  可变参数函数需要第一个参数必须为命名的确定参数。编写可变函数max_list求最大值。

#include <stdarg.h>

int max_list(int first_arg, ...)
{
//指向参数栈的指针
va_list va_arg;
//初始化指针
va_start (va_arg, first_arg); int value = va_arg(va_arg, int);
int max = first_arg; while (value > 0) {
if (max < value) {
max = value;
}
//循环取出值
value = va_arg(va_arg, int);
}
//将指针指向为NULL
va_end(va_arg); return max;
}

7.5实现简化版本的printf函数,能够处理%d %f %s %c格式码,假设以及存在print_interger和print_float,其他的两个用putchar打印。

#include <stdio.h>
#include <stdarg.h>
void print_integer(int integer)
{
printf("%d", integer);
} void print_float(float floatNum)
{
printf("%f", floatNum);
} //mini版printf只支持 %d %f %c %s
void mini_prinf(char *format, ...)
{
va_list arg; va_start(arg, format);
char *sPtr = format;
char *str;
float flt; while (*sPtr != '\0') {
//普通字符直接输出
if (*sPtr != '%') {
putchar(*sPtr++);
continue;
} // %%输出一个%
if ((*sPtr == *(sPtr + 1) == '%')) {
putchar(*sPtr++);
sPtr++;
continue;
} //遇到%后面有格式符,进行判断类型,然后读取打印参数,每次跳2位包括% 和后面的格式码
switch (*(sPtr + 1)){
case 'd':
print_integer(va_arg(arg, int));
sPtr += 2;
break;
case 'f':
/*C语言中,调用一个不带原型声明的函数时:
调用者会对每个参数执行“默认实际参数提升(default argument promotions)”。
同时,对可变长参数列表超出最后一个有类型声明的形式参数之后的每一个实际参数,也将执行上述提升工作。*/
//所以这里写double
print_float(va_arg(arg, double));
sPtr += 2;
break;
case 'c':
//字符也是小整型,直接当int取,char读出来
putchar(va_arg(arg, int));
sPtr += 2;
break;
case 's':
str = va_arg(arg, char *);
while (*str != '\0') {
putchar(*str++);
}
sPtr += 2;
break;
default:
sPtr += 2;
break;
}
}
}

整型提升:

——float类型的实际参数将提升到double
——char、short和相应的signed、
——unsigned类型的实际参数提升到int
——如果int不能存储原值,则提升到unsigned int

参考:http://blog.****.net/astrotycoon/article/details/8284501

7.6 编写函数:

void written_amount(unsigned int amount, char * buffer);

实现amount为16312,buffer中储存SIXTEEN THOUSAND THREE HUNDRED TEWLVE

#include <stdio.h>
#include <string.h>
//一千THOUSAND,一千的一千倍一百万MILLION,一百万的一千倍十亿BILLION,下面的数只是对一千以下的数进行num转字符串,更高位的只需三位分隔开,加上千,百万,十亿,单位即可。
int num_to_alp(unsigned int num, char * buffer)
{
if (num == 0) {
//返回0,标示num为0,便于后面不加thousand,billion单位
return 0;
}
static char *digits[] = {"", "ONE ", "TWO ", "THREE ", "FOUR ", "FIVE ", "SIX ", "SEVEN ", "EIGHT ", "NINE ", "TEN ", "ELEVEN ", "TWELVE ", "THIRTEEN ",
"FOURTEEN ", "FIFTEEN ", "SIXTEEN ", "SEVENTEEN ", "EIGHTEEN ", "NINETEEN " }; static char *tens[] = {"", "", "TWENTY ", "THIRTY ", "FORTY ", "FIFTY ", "SIXTY ", "SEVENTY ", "EIGHTY ", "NINETY "}; //如果百位有数,先添加百位
if (num / 100) {
int hud = num / 100;
strcat(buffer, digits[hud]);
strcat(buffer, "HUNDRED ");
} num = num % 100;
//对十位上的数判断处理,大于20用ty后缀,小于20用digits中字符串
int ten = num / 10; if (ten >= 2) {
//十位
strcat(buffer, tens[ten]);
//个位
num = num % 10;
strcat(buffer, digits[num]);
}else{
//小于20直接用digits中个位
strcat(buffer, digits[num]);
}
return 1;
} //将amount按三位分一组,进行分组。数组第一位指定组长eg 123456789 =>数组[3, 789, 456, 123]
unsigned int * div_amount(unsigned int amount)
{
unsigned int arr_amount[100]; unsigned int amount_dived;
int loc = 1;
do {
arr_amount[loc] = amount % 1000;
amount /= 1000;
loc++;
} while (amount); arr_amount[0] = loc - 1; return arr_amount;
} void written_amount(unsigned int amount, char *buffer)
{
if (amount == 0) {
strcat(buffer, "zero ");
}
//上千,百万,十亿,单位
static char *magnitudes[] = { "", "THOUSAND ", "MILLION ", "BILLION " };
//分割后的数组指针
unsigned int *dived_arr;
//分割的段数,数组长度
int len;
//分隔数字
dived_arr = div_amount(amount);
len = dived_arr[0]; //当分成三组时只需要magnitudes前三个
while (len > 0) {
          
//对每三个数字进行num转字符串
if (num_to_alp(dived_arr[len], buffer)) {
//如果三位数不是零,加上这三位数的单位
strcat(buffer, magnitudes[len - 1]);
}
len--;
}
}

  

 测试:

int main()
{
char buffer[1] = { '\0' };
unsigned int amount = 12345678910;
written_amount(amount, buffer);
printf("%s\n", buffer); buffer[0] = '\0';
amount = 1000001;
written_amount(amount, buffer);
printf("%s\n", buffer); buffer[0] = '\0';
amount = 1;
written_amount(amount, buffer);
printf("%s\n", buffer); buffer[0] = '\0';
amount = 0;
written_amount(amount, buffer);
printf("%s\n", buffer); while (1)
;
return 0;
}

  

 执行结果:

C和指针 第七章 习题