【C程序设计语言】第二章-类型、运行符与表达式 | 练习

练习2-1 编写一个程序以确定分别有signed及unsigned限定的char、short、int、long类型变量的取值范围。
(1) 采用打印标准头文件中的相应值实现

#include <stdio.h>
#include <limits.h>

/* 
 * ANSI C标准规定:各种类型的取值范围必须在头文件<limits.h>中定义。
 * int、short、long类型在不同的硬件上有不同的长度。   
 */
main()
{
    printf("signed-----------\n");  
    printf("signed char: %d ~ %d\n", SCHAR_MIN, SCHAR_MAX);
    printf("singed int: %d ~ %d\n", INT_MIN, INT_MAX);
    printf("singed short: %d ~ %d\n", SHRT_MIN, SHRT_MAX);
    printf("singed long: %d ~ %d\n", LONG_MIN, LONG_MAX);

    printf("unsigned------------\n");
    /* %u:输入输出unsigned(无符号)类型的数值 */
    printf("unsigned char max: %u\n", UCHAR_MAX);
    printf("unsinged int max: %u\n", UINT_MAX); 
    printf("unsinged short max: %u\n", USHRT_MAX);
    printf("unsinged long max: %u\n", ULONG_MAX);
}

(2)直接计算

#include <stdio.h>

main()
{
    printf("signed char: %d ~ %d\n",
                -(char)((unsigned char) ~0 >> 1),
                (char)((unsigned char) ~0 >> 1));
    printf("signed int: %d ~ %d\n",
                -(int)((unsigned int) ~0 >> 1),
                (int)((unsigned int) ~0 >> 1));
    printf("signed char: %d ~ %d\n",
                -(short)((unsigned short) ~0 >> 1),
                (short)((unsigned short) ~0 >> 1));
    printf("signed char: %d ~ %d\n",
                -(long)((unsigned long) ~0 >> 1),
                (long)((unsigned long) ~0 >> 1));

    printf("unsigned char max: %u\n",
                        (unsigned char) ~0);           
    printf("unsigned int max: %u\n",
                        (unsigned int) ~0);            
    printf("unsigned short max: %u\n",
                        (unsigned short) ~0);          
    printf("unsigned long max: %lu\n",
                        (unsigned long) ~0);
}

练习2-2 在不使用运算符&&或||的条件下编写一个与下面for循环语句等价的语句

for(i=0; i<lim-1 && (c=getchar()) != '\n' && c!= EOF; ++i)
    s[i] = c; 
#include <stdio.h>

/* 使用枚举变量 */ 
main()
{
    enum loop{NO, YES};
    enum loop okloop = YES;

    i = 0;
    while(okloop == YES){
        if(i >= lim-1)
            okloop = NO;
        else if((c=getchar()) == '\n')
            okloop = NO;
        else if(c == EOF)
            okloop = NO;
        else{
            s[i] = c;
            ++i;
        }
    }
}

/* for循环 
main()
{ 
    for(i=0; i<lim-1; ++i)
        if((c=getchar()) != EOF)
            if(c != '\n')
                s[i] = c;
}
*/

练习2-3 编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值。字符串允许包含的数字包括:0-9、a-f、A-F

#include <stdio.h>
#include <math.h>

int htoi(char s[]);

main()
{
    int c, i;
    char n[100];

    i = 0;
    while((c=getchar()) != EOF && c != '\n'){
        n[i] = c;
        ++i;
    }
    printf("count: %d\n", htoi(n));
}

int htoi(char s[])
{
    int i;
    enum flag {N, Y};
    int hexdigit;
    int count;

    i = count = 0;
    enum flag ff = Y;
    if(s[i] == '0'){            /* 去'0x'或'0X' */
        ++i;
        if(s[i]=='x' || s[i]=='X')
            ++i;
    }
    for( ; ff==Y ; ++i){
        if(s[i] >= '0' && s[i] <='9')
            hexdigit = s[i] - '0';
        else if(s[i] >= 'a' && s[i] <= 'f')
            hexdigit = s[i] - 'a' + 10;
        else if(s[i] >= 'A' && s[i] <= 'F')
            hexdigit = s[i] - 'A' + 10;
        else 
            ff = N;
        if(ff == Y)
            count = 16 * count + hexdigit;
    }
    return count;
}

练习2-4 编写函数squeeze(s1, s2), 将s1中任何与s2中字符匹配的字符都删除

void squeeze(char s1[], char s2[])
{
    int i, j, k;

    for(i=k=0 ; s1[i]!='\0' ; i++){
        for(j=0; s2[j]!='\0' && s1[i]!=s2[j] ; j++)
            ;
        if(s1[i] != s2[j]){
            s1[k++] = s1[i];
        }   
    }
    s1[k] = '\0';
    printf("cankao:%s\n", s1);
}

练习2-5 编写函数any(s1, s2), 将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。若s1中不包含s2中的字符,则返回-1

int any(char s1[], char s2[])
{
    int i, j;

    for(i=0; s2[i]!='\0'; ++i)
        for(j=0; s1[j]!='\0'; ++j)
            if(s1[j] == s2[i])
                return j;
}

2-6 编写一个函数setbits(x, p, n, y),该函数返回对x执行下列操作后的结果值:将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变

unsigned setbits(unsigned x, int p, int n, unsigned y)
 {
    return x & ~(~(~0<<n) << (p-n+1)) | 
         (y & ~(~0<<n)) << (p-n+1)); 
 }

练习2-7 编写一个函数invert(x, p, n),该函数返回对x执行下列操作后的结果值:将z中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变

unsigned invert(unsigned x, int p, int n)
{
    return x ^ (~(~0 << n) << (p+1-n));
}

练习2-8 编写一个函数rightrot(x, n), 该函数返回将x循环右移(即从最右端移出的位将从最左端再移入)n位(二进制)后所得到的值

unsigned rightrot(unsigned x, int n)
{
    int wordlength(void);  /* 求运行程序的计算机的字长 */
    int rbit;

    while(n-- > 0){
        rbit = x << (wordlength() - 1);  /* 将最右移到最左 */
        x = x >> 1;
        x = x | rbit;
    }
    return x;
}

int wordlength(void)
{
    int i;
    unsigned v = (unsigned) ~0;

    for(i=0; (v>>=1)>0; ++i)
        ;
    return i;
}

练习2-9 在求对二的补码时,表达式 x &= (x-1)可以删除x中最右边为1的一个二进制位。请解释这样做的道理。用这一方法重写bitcount函数,以加快其执行速度。
//不懂这个和求对二的补码有什么关系

int bitcount(unsigned x)
{
    int b;

    for(b=0; x!=0; x&=x-1)
        ++b;
    return b;
}

练习2-10 重新编写将大写字母转换成小写字母的函数lower,并用条件表达式代替其中的if-else结构

int lower(int c)
{
    return c>='A' && c<='Z' ? c+'a'-'A' : c;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值