C和指针 第7章 函数 7.11 编程练习

1.Hermite Polynomials(厄密多项式)是这样定义的:
                       n <= 0: 1 
        Hn(x) =   n = 1: 2x
                       n >= 2: 2xH(n-1)(x) - 2(n-1)H(n - 2)(x) 
例如,H3(2)的值是40。编写一个递归函数,计算Hn(x)的值。该函数应该与下面的原型匹配:
int hermite( int n, int x) 
解析:
Hermite polynomials用于物理学和统计学。它们也可以作为递归联系在程序中使用。

#include <stdio.h>
#include <stdlib.h>

/*
**计算Hermite polynomial的值
**
**输入:
**    n, x: 用于标识值
**
**输出:
**    polynomial的值(返回值)
*/
int hermite( int n, int x );
int main( void ){
    int n;
    int x;
    int result;
    
    n = 3;
    x = 2;
    result = hermite( n, x );
    printf( "the result of hermite( %d, %d ) is %d.\n", n, x, result );
    
    return EXIT_SUCCESS;
}

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 ); 
}
输出:

2.两个整型值M和N(M、N均大于0)的最大公约数可以按照下面的方法计算:
                        M % N = 0: N
gcd( M, N ) =  
                        M % N = R, R > 0: gcd( N, R )
请编写一个名叫gcd的函数,它接受两个整型参数,并返回两个数的最大公约数。
如果这两个参数中的任何一个不大于0,函数就该返回零。
解析:
#include <stdio.h>
#include <stdlib.h>

int gcd( int m, int n );
 
int main( void ){
    int m;
    int n;
    int result;
    
    m = 5;
    n = 3;
    result = gcd( m, n );
    printf( "the result of gcd( %d, %d ) is %d\n", m, n, result );

    return EXIT_SUCCESS;
}

int gcd( int m, int n ){
    if( m <= 0 || n <= 0 ){
        return 0;
    }
    if( m % n == 0 ){
        return n;
    }
    return gcd( n, m % n );
}
输出:

3.为下面这个函数原型编写函数定义:
    int ascii_to_integer( char *string );
这个字符串参数必须包含一个或多个数字,函数应该把这些数字字符转换为整数并返回这个整数。如果字符串参数包含了任何非数字字符,函数就返回零。不必担心算术溢出。
提示:这个技巧很简单---每发现一个数字,就把当前值乘以10,并把这个值和新数字所代表的值相加。
解析:
#include <stdio.h>
#include <stdlib.h>

/*这个问题应该用迭代方案解决,而不应该采用递归方式。*/ 
int ascii_to_integer( char *string );
 
int main( void ){
    char string[] = "254";
    int result;
    
    printf( "string = %s\n", string );
    result = ascii_to_integer( string );
    printf( "the result of ascii_to_integer( \"%s\" ) is %d\n", string, result );

    return EXIT_SUCCESS;
}

/*
**逐个把字符串的字符转换为数字。
*/ 
int ascii_to_integer( char *string ){
    int value = 0;
    /*
    **逐个把字符串的字符转换为数字。
    */
    while( *string >= '0' && *string <= '9' ){
        value *= 10;
        value += *string - '0';
        string++;
    }
    /*
    **错误检查:如果由于遇到一个非数字字符而终止,把结果设置为0。
    */
    if( *string != '\0' ){
        value = 0;
    } 
    
    return value;    
}
输出:

 4.编写一个名叫max_list的函数,用于检查任意数目的整型参数并返回它们中的最大值。参数列表必须以一个负值结尾,用于提示列表的结束。
/*
** method_01
** this method needs you provide the number of variable parameter, 
** but we may not use all the variable parameter, it will stop until it encounters a '\0'.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

int max_list( int n_values, ... );
 
int main( void ){
    int max_value, max_value2;
    int value;
    int value2;
    int value3;
    int value4;
    int n_values;
    
    n_values = 5;
    value = 6;
    value2 = 12;
    value3 = 8;
    value4 = -1;
    max_value = max_list( n_values, value, value2, value3, value4 );
    printf( "n_values = %d, value = %d, value2 = %d, value3 = %d, value4 = %d\nmax_value = %d\n", 
    n_values, value, value2, value3, value4, max_value );
    
    n_values = 7;
    value = 25;
    value2 = 88;
    value3 = 98;
    value4 = -1;
    max_value2 = max_list( n_values, value, value2, value3, value4 );
    printf( "n_values = %d, value = %d, value2 = %d, value3 = %d, value4 = %d\nmax_value2 = %d\n", 
    n_values, value, value2, value3, value4, max_value2 );

    return EXIT_SUCCESS;
}

int max_list( int n_values, ... ){
    va_list var_arg;
    int count;
    int max;
    int temp;
    
    count = 0;
    va_start( var_arg, n_values );
    max = va_arg( var_arg, int );
    if( max < 0 ){
        printf( "the first value of variable parameter is %d, %d is smaller than zero.\n", max, max );
        printf( "return the negative value.\n" );
        return max;
    } 
    
    for( count = 1; count < n_values; count += 1 ){
        temp = va_arg( var_arg, int );
        if( temp < 0 ){
            break;
        }
        if( max < temp ){
            max = temp;
        }
    }

    va_end( var_arg );
    
    return max;
}
输出:

/* 
** method_02
** this method don't need you to provoid  neither number of value nor the type of value, 
** because the program tells me it will stop until it encounters a negative number.
*/ 
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

int max_list(int first_arg, ...);

int main( void ){
    int max_value, max_value2;
    int value;
    int value2;
    int value3;
    int value4;
    
    value = 6;
    value2 = 12;
    value3 = 8;
    value4 = -1;
    max_value = max_list( value, value2, value3, value4 );
    printf( "value = %d, value2 = %d, value3 = %d, value4 = %d\nmax_value = %d\n", 
    value, value2, value3, value4, max_value );
}
/* 
** we can use the first_arg neither number of value nor the type of value, 
** because the program tells me it will stop until it encounters a negative number.
*/ 
int max_list(int first_arg, ...)
{
    va_list var_arg;
    int  max = 0;
    
    if (first_arg >= 0) {
        int  this_arg;
        max = first_arg;
    
        va_start(var_arg, first_arg);
        while ((this_arg = va_arg(var_arg, int)) >=0)
            if (this_arg > max)
                max = this_arg;
        va_end(var_arg);
    } else{
        printf( "first_arg is %d, %d is smaller than zero.\n", max, max );
        printf( "return the negative value.\n" );
        return first_arg;
    }
    return max;
}
输出:

参考链接:https://blog.csdn.net/weixin_42385823/article/details/114890781 

5.实现一个简化的printf函数,它能够处理%d、%f、%s和%c格式码。根据ANSI标准的原则,其他格式码的行为是未定义的。可以假定已经存在函数print_integer和print_float,用于打印这些类型的值。对于另外两种类型的值,使用putchar来打印。
解析:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

int printf_simple_version( const char *format, ... );
int print_integer( int n );
int print_float( double f );

int main( void ){
    char ch = 'a';
    int i = 42;
    float f = 2.0f;
    char pc[] = "hello!";
    int count = 0;
    int count2 = 0;
    
    count = printf( "pc=%s ch=%c i=%d f=%f", pc, ch, i, f );
    printf( "\n" ); 
    count2 = printf_simple_version( "pc=%s ch=%c i=%d f=%f", pc, ch, i, f );
    printf( "\n" );
    printf( "count = %d, count2 = %d\n", count, count2 );
    int usual_ch_len = strlen( "pc= ch= i= f=" );
    /* 
    ** the first 1 represents a character
    ** the second 1 represents an integer number
    ** the third 1 represents a float number
    */
    int total_len = usual_ch_len + strlen(pc) + 1 + 1 + 1;
    printf( "usual_ch_len = %d, total_len = %d\n", usual_ch_len, total_len );
    
    printf( "print the result of %%s %%c %%d format code:\n" );
    count = printf( "%s %c %d ", pc, ch, i );
    printf( "\n" );
    count2 = printf_simple_version( "%s %c %d ", pc, ch, i );
    printf( "\n" );
    printf( "count = %d, count2 = %d\n", count, count2 );

    printf( "print the result of %%f format code:\n" );
    count =  printf( "%f", 1.0f); 
    printf( "\n" );
    count2 = printf_simple_version( "%f", f );
    printf( "\n" );
    printf( "count = %d, count2 = %d", count, count2 );
    
    return EXIT_SUCCESS;
}

int printf_simple_version( const char *format, ... ){
    va_list var_arg;
    
    va_start( var_arg, format );
    
    char *str[10] = { NULL }; /* record the character pointers point to dynamic memroy */
    int number_character = 0; /* record the total of character */
    int inner_counter = 0;       /* record the length of every format character */ 
    int outer_counter = 0;       /* record the number of character pointer */ 
    const char *message_begin;/* record the beginning of format string */
    while( *format != '\0' ){
        message_begin = format;   
        if( *message_begin == '%' ){ /* record beginning of format character */ 
            inner_counter++;
            format += 1;
            if( *format == 's' || *format == 'c' || *format == 'd' || *format == 'f' ){
                inner_counter++;
                format += 1;
                str[outer_counter] = (char *)malloc( (inner_counter + 1) * sizeof(char) );
                if( str[outer_counter] != NULL ){
                    strncpy( str[outer_counter], message_begin, inner_counter );
                    str[outer_counter][inner_counter] = '\0';
                    if( strcmp( str[outer_counter], "%c" ) == 0 ){
                        putchar( va_arg( var_arg, int ) );
                        number_character++;
                    } else if( strcmp( str[outer_counter], "%s" ) == 0 ){
                        char *temp = va_arg( var_arg, char * );
                        int str_len = 0;
                        while( *temp ){
                            putchar( *temp++ );
                            str_len++;
                        }
                        number_character += str_len; 
                    } else if( strcmp( str[outer_counter], "%d" ) == 0 ){
                        int value = va_arg( var_arg, int ); 
                        print_integer( value );
                        int counter = 1;
                        while( value / 10 ){
                            counter++;
                            value /= 10;
                        }
                        number_character += counter;
                    
                    } else if( strcmp( str[outer_counter], "%f" ) == 0 ){
                        double value = va_arg( var_arg, double ); 
                        print_float( value );
                        /*
                        ** number_character++;
                        */
                        int int_value = value; //the integral part of float number 
                        int counter = 1;
                        while( int_value / 10 ){
                            counter++;
                            int_value /= 10;
                        }
                        number_character += counter;
                        number_character += 7; //decimal point add default six precision  
                    }
                    outer_counter += 1;
                    inner_counter = 0;
                } else{
                    printf( "memory allocation failed.\n" );
                    break;
                }
            } else{
                printf( "illegal formal code!\n" );
                break;
            }
        } else{  /* usual character */ 
            putchar( *format );
            format += 1;
            number_character++;
        } 
    }
    int i;
    /* 释放动态分配的内存 */ 
    for( i = 0; i < outer_counter; ++i ){
        free( str[i] );
    } 
    
    return number_character;    
}

int print_integer( int n ){
    printf( "%d", n );
}
int print_float( double f ){
    printf( "%f", f );
}
输出:

6.编写如下函数:
    void written_amount( unsigned int amount, char *buffer );
它把amount表示的值转换为单词形式,并存储于buffer中。这个函数可以在一个打印支票的程序中使用。例如,如果amount的值是16312,那么buffer中存储的字符串应该是
    SIXTEEN THOUSAND THREE HUNDRED TWELVE
调用程序应该保证buffer缓冲区的空间足够大。
有些只可以用两种不同的方法进行打印。例如,1200可以是ONE THOUSAND TWO HUNDRED或TWELVE HUNDRED。可以选择一种自己喜欢的形式。
/*
** a very good method.
** the thought of recursion.
** divide these number into different group, headmost group is computed firstly.
*/ 
#include <stdio.h>
#include <stdlib.h>
#include<string.h>

static const char  *digits[] = {"", "ONE ", "TWO ", "THREE ", "FOUR ", "FIVE ", "SIX ", "SEVEN ",
"EIGHT ", "NINE ", "TEN ", "ELEVEN ", "TWELVE ", "THIRTEEN ",
"FOURTEEN ", "FIFTEEN ", "SIXTEEN ", "SEVENTEEN ", "EIGHTEEN ",
"NINETEEN "
};
static const  char  *tens[] = {
"", "", "TWENTY ", "THIRTY ", "FORTY ", "FIFTY ", "SIXTY ", "SEVENTY ",
"EIGHTY ", "NINETY "
};
static const char  *magnitudes[] = {
"", "THOUSAND ", "MILLION ", "BILLION "
};

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

int main( void ){
    char buffer[100] = {'\0'};
    
    printf( "UINT_MAX = %u\n", UINT_MAX );
    written_amount( UINT_MAX, buffer );
    printf( "%s\n", buffer );

    return EXIT_SUCCESS;
}

/*
**  Convert the last 3–digit group of amount to words.  Amount is the value
**  to be converted, buffer is where to put the words, and magnitude is the
**  name of the 3–digit group we’re working on.
*/
static void do_one_group(unsigned int amount, char *buffer, char **magnitude)
{
    int  value;
    /*
    ** Get all the digits beyond the last three.  If we have any value
    ** there, process those digits first.  Note that they are in the next
    ** magnitude.
    */
    value = amount / 1000;
    if (value > 0)
        do_one_group(value, buffer, magnitude + 1);
    /*
    ** Now process this group of digits.  Any hundreds?
    */
    amount %= 1000;
    value = amount / 100;
    if (value > 0) {
        strcat(buffer, digits[value]);
        strcat(buffer, "HUNDRED ");
    }
    /*
    ** Now do the rest of the value.  If less than 20, treat it as a single
    ** digit to get the teens names.
    */
    value = amount % 100;
    if (value >= 20) {
        /*
        ** Greater than 20.  Do a tens name and leave the units to be
        ** printed next.
        */
        strcat(buffer, tens[value / 10]);
        value %= 10;
    }
    if (value > 0)
        strcat(buffer, digits[value]);
    /*
    ** If we had any value in this group at all, print the magnitude.
    */
    if (amount > 0)
        strcat(buffer, *magnitude);
}
void written_amount(unsigned int amount, char *buffer)
{
    if (amount == 0)
        /*
        ** Special case for zero.
        */
        strcpy(buffer, "ZERO ");
    else {
        /*
        ** Store an empty string in the buffer, then begin.
        */
        *buffer = '\0';
        do_one_group(amount, buffer, (char **)magnitudes);
    }
}
输出:

原文链接:https://blog.csdn.net/weixin_42385823/article/details/114890781 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40186813

你的能量无可限量。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值