阅读笔记

4.1 闰年判断语句(先处理最为特殊的情况)

if( year % 400 == 0 )
    leap_year = 1;
else if( year % 100 == 0 )
    leap_year = 0;
else if( year % 4 == 0 )
    leap_year = 1;
else
    leap_year = 0;

4.2 计算一个正数的平方根

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

int
main()
{
    float new_guess, last_guess, num;

    printf( "Enter a number: " );
    scanf( "%f", &num );
    if( num < 0 ){
        printf( "Cannot compute the square root of a "
               "negative number!\n" );
        return EXIT_FAILURE;
    }

    new_guess = 1;
    do {
        last_guess = new_guess;
        new_guess = ( last_guess + num / last_guess ) / 2;
        printf( "%.15e\n", new_guess );
    } while( new_guess != last_guess );

    printf( "Square root of %g is %g\n", num, new_guess );

    return EXIT_SUCCESS;
}


5.1 请编写函数unsigned int reverse_bits( unsigned int value );

这个函数的返回值是把value的二进制位模式从左到右变换一下后的值。编写函数时要注意不要让它依赖于你的机器上整型值的长度

unsigned int
reverse_bits( unsigned int value )
{
    unsigned int answer, i;
    answer = 0;
    
    /*
    ** 只要i不是0就继续进行。这就使循环与机器的字长无关,从而避免了可移植性问题。
    */    
    for( i = 1; i != 0; i << 1 ){
        answer << 1;
        if(value & 1)
            answer |= 1;
        value >> 1;
    }
    
    return answer;
}


6.1 编写函数reverse_string,它的原型如下:

void reverse_string( char *string );

函数把参数字符串中的字符反向排列。请使用指针而不是数组下标,不要使用任何C函数库中用于操纵字符串的函数。提示:不要声明一个局部数组来临时存储参数字符串

void reverse_string( char *str )
{
    char *last_char;
    
    for( last_char = str; *last_char != '\0'; last_char++ )
        ;
    last_char--;
    
    while( str < last_char ){
        char temp;
        
        temp = *str;
        *str++ = *last_char;
        *last_char-- = temp;
    }
}

8.1 编写一个函数,用于执行两个矩阵的乘法。函数的原型应该如下:

void matrix_multiply( int *m1, int *m2, int *r, int x, int y, int z );

void matrix_multiply( int *m1, int *m2, register int *r, int x, int y, int z )
{
    register int *m1p;
    register int *m2p;
    register int k;
    int row;
    int column;
    
    for( row = 0; row < x; row += 1 ){
        for( column = 0; column < y; column += 1 ){
            m1p = m1 + row * y;
            m2p = m2 + column;
            *r = 0;
            
            for( k = 0; k < y; k += 1 ){
                *r += *m1p * *m2p;
                m1p += 1;
                m2p += z;
            }
            
            r++;
        }
    }
}

9.1 编写一个程序,对标准输入进行扫描,并对单词“the”出现的次数进行计数。进行比较时应该区分大小写,所以“The”和“THE”并不计算在内。你可以认为各单词由一个或多个空格字符分隔,而且输入行在长度上不会超过100个字符。计数结果应该写到标准输出上。

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

char const whitespace[] = " \n\r\f\t\v";

int
main()
{
    char buffer[101];
    int count = 0;

    while( gets( buffer ) ){
        char *word;

        for( word = strtok( buffer, whitespace );
           word != NULL;
           word = strtok( NULL, whitespace ) ){
           if( strcmp( word, "the" ) == 0 )
               count++;
        }
    }

    printf( "%d\n", count );

    return EXIT_SUCCESS;
}

9.2 标准I/O库并没有提供一种机制,在打印大整数时用逗号进行分隔。在这个练习中,你需要编写一个程序,为美元数额的打印提供这个功能。函数把一个数字字符串(代表以美分为单位的金额)转换为美元形式,下面是函数的原型:

void dollars( char *dest, char const *str );

#include <stdio.h>

void
dollars( register char *dst, register char const *src )
{
    int len;
    
    if( dst == NULL || src == NULL )
        return;
    
    *dst++ = '$';
    len = strlen( src );
    
    if( len >= 3 ){
        int i;
        
        for( i = len - 2; i > 0; ){
            *dst++ = *src++;
            if( --i > 0 && i % 3 == 0 )
                *dst++ = ',';
        }
    }
    else
        *dst++ = '0';
    
    *dst++ = '.';
    *dst++ = len < 2 ? '0' : *src++;
    *dst++ = len < 1 ? '0' : *src;
    *dst = 0;
}

11.1 编写一个函数,从标准输入读取一列整数,把这些值存储于一个动态分配的数组中并返回这个数组。函数通过观察EOF判断输入列表是否结束。数组的第1个数是数组包含的值的个数,它的后面就是这些整数值。

#include <stdio.h>
#include <malloc.h>
#define DELTA 100

int *
readints()
{
    int *array;
    int size;
    int count;
    int value;
    
    size = DELTA;
    array = malloc( ( size + 1 ) * sizeof( int ) );
    if( array == NULL )
        return NULL;
    
    count = 0;
    while( scanf( "%d", &value ) == 1 ){
        count++;
        if( count > size ){
            size += DELTA;
            array = realloc( array, ( size + 1 ) * sizeof( int ) );
            if( array == NULL )
                return NULL;
        }
        array[ count ] = value;
    }
    
    if( count < size ){
        array = realloc( array, ( count + 1 ) * sizeof( int ) );
        if( array == NULL )
            return NULL;
    }
    
    array[ 0 ] = count;
    return array;
}

13.1 编写一个程序,从标准输入读取一些字符,并根据下面的分类计算各类字符所占的百分比:

控制字符

空白字符

数字

小写字母

大写字母

标号字母

不可打印字母


这些字符的分类是根据ctype.h中的函数定义的。不能使用一系列的If语句。

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

int is_not_print( int ch )
{
    return !isprint( ch );
}

static int(*test_func[])( int ) = {
    iscntrl,
    isspace,
    isdigit,
    islower,
    isupper,
    ispunct,
    is_not_print
};

#define N_CATEGORIES\
    ( sizeof( test_func ) / sizeof( test_func[ 0 ] ) )

char *label[] = {
    "control",
    "whitespace",
    "digit",
    "lower case",
    "upper case",
    "punctuation",
    "non-printable"
};

int count[ N_CATEGORIES ];
int total;

int
main()
{
    int ch;
    int category;

    while( ( ch = getchar() ) != EOF ){
        total++;

        for( category = 0; category < N_CATEGORIES; category++ ){
            if( test_func[ category ]( ch ) )
                count[ category ] += 1;
        }
    }

    if( total == 0 )
        printf( "No characters in the input!\n" );
    else{
        for( category = 0; category < N_CATEGORIES; category++ ){
            printf( "%3.0f%% %s characters\n",
                   count[ category ] * 100.0 / total,
                   label[ category ] );
        }
    }

    return EXIT_SUCCESS;
}


15.1 UNIX的fgrep程序从命令行接受一个字符串和一系列文件名作为参数。然后,它逐个查看每个文件的内容。对于文件中每个包含命令行中给定字符串的文本行,程序将打印出它所在的文件名、一个冒号和包含该字符串的行。编写这个程序。首先出现的是字符串参数,它不包含任何换行字符。然后是文件名参数。如果没有给出任何文件名,程序应该从标准输入读取。在这种情况下,程序所打印的行不包括文件名和冒号。你可以假定个文件所有文本行的长度都不会超过510个字符。

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

#define BUFFER_SIZE 512

void
search( char *filename, FILE *stream, char *string )
{
    char buffer[ BUFFER_SIZE ];

    while( fgets( buffer, BUFFER_SIZE, stream ) != NULL ){
        if( strstr( buffer, string ) != NULL ){
            if( filename != NULL )
                printf( "%s:", filename );
            fputs( buffer, stdout );
        }
    }
}

int
main( int ac, char **av )
{
    char *string;

    if( ac <= 1 ){
        fprintf( stderr, "Usage: fgrep string file ...\n" );
        exit( EXIT_FAILURE );
    }

    string = *++av;

    if( ac <= 2 )
        search( NULL, stdin, string );
    else{
        while( *++av != NULL ){
            FILE *stream;

            stream = fopen( *av, "r" );
            if( stream == NULL )
                perror( *av );
            else{
                search( *av, stream, string );
                fclose( stream );
            }
        }
    }

    return EXIT_SUCCESS;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值