《C程序设计语言》-第2章-习题

 

  本人写的代码可能与标准答案有出入,但运行是没问题的,欢迎大家相互参考学习。

 


C程序设计语言习题2-1

  编写一个程序以确定分别由signed及unsigned限定的char、short、int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现:

 1 void checkSize() {
 2     printf("采用打印标准头文件limits.h中的相应值:\n");
 3 
 4     //signed types
 5     printf("signed char min = %d\n", SCHAR_MIN);
 6     printf("signed char max = %d\n", SCHAR_MAX);
 7     printf("signed short min = %d\n", SHRT_MIN);
 8     printf("signed short max = %d\n", SHRT_MAX);
 9     printf("signed int min = %d\n", INT_MIN);
10     printf("signed int max = %d\n", INT_MAX);
11     printf("signed long min = %ld\n", LONG_MIN);
12     printf("signed long max = %ld\n", LONG_MAX);
13     //unsigned types
14     printf("unsigned char max = %u\n", UCHAR_MAX);
15     printf("unsigned short max = %u\n", USHRT_MAX);
16     printf("unsigned int max = %u\n", UINT_MAX);
17     printf("unsigned long max = %lu\n", ULONG_MAX);
18 /*
19 以下代码段来自linmits.h:
20 #define MB_LEN_MAX    5             // max. # bytes in multibyte char
21 #define SHRT_MIN    (-32768)        // minimum (signed) short value
22 #define SHRT_MAX      32767         // maximum (signed) short value
23 #define USHRT_MAX     0xffff        // maximum unsigned short value
24 #define INT_MIN     (-2147483647 - 1) // minimum (signed) int value
25 #define INT_MAX       2147483647    // maximum (signed) int value
26 #define UINT_MAX      0xffffffff    // maximum unsigned int value
27 #define LONG_MIN    (-2147483647L - 1) // minimum (signed) long value
28 #define LONG_MAX      2147483647L   // maximum (signed) long value
29 #define ULONG_MAX     0xffffffffUL  // maximum unsigned long value
30 #define LLONG_MAX     9223372036854775807i64       // maximum signed long long int value
31 #define LLONG_MIN   (-9223372036854775807i64 - 1)  // minimum signed long long int value
32 #define ULLONG_MAX    0xffffffffffffffffui64       // maximum unsigned long long int value
33 */
34     printf("采用直接计算方式实现:\n");
35     printf("signed char min = %d\n", ~((unsigned char)~0) >> 1);
36     /*首先对0取反,令此无符号char数二进制形式全为1,然后向右移1位,左边进0
37     (因为无符号char的关系,所以进0而不是1,此外该0还表示数字符号为正),这
38     个就是我们要找的有符号char数的最大值。再自反就得到了一个以符号位为1(0
39     取反后得到),其余位为0的数。下面的表达方式都可由此推知。*/
40     printf("signed char max = %d\n", ((unsigned char)~0) >> 1);
41     printf("signed short min = %d\n", ~((unsigned short)~0) >> 1);
42     printf("signed short max = %d\n", ((unsigned short)~0) >> 1);
43     printf("signed int min = %d\n", ~((unsigned int)~0) >> 1);
44     printf("signed int max = %d\n", ((unsigned int)~0) >> 1);
45     printf("signed long min = %ld\n", ~((unsigned long)~0) >> 1);
46     printf("signed long max = %ld\n", ((unsigned long)~0) >> 1);
47     //unsigned types
48     printf("unsigned char max = %u\n", (unsigned char)~0);
49     //直接对0取反,一气呵成
50     printf("unsigned short max = %u\n", (unsigned short)~0);
51     printf("unsigned int max = %u\n", (unsigned int)~0);
52     printf("unsigned long max = %lu\n", (unsigned long)~0);
53 }

 


C程序设计语言习题2-2

  在不是用运算符&&或者||的条件下编写一个与上面的for循环语句等价的循环语句:

主函数main:

1 int main()
2 {
3     char s[1000];
4     
5     noAOR(s);
6     printf("%s\n", s);
7 
8     system("pause");
9 }

函数noAOR:(no and & OR)

 1 void noAOR(char s[]) {
 2     int i, lim = 1000;
 3     char c;
 4     
 5     for (i = 0; (c = getchar()) != '\n'; ++i) {
 6         if (i >= lim - 1) { 
 7             break; 
 8         } else if (c == EOF) {
 9             break;
10         } else{
11             s[i] = c;
12         }
13     }
14     s[i] = '\0';
15 
16 }

 

 


C程序设计语言习题2-3

  编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值:(我用了三个简单字符串进行测试)

主函数:

 1 int main()
 2 {
 3     char s1[1000] = " 0xff905";
 4     char s2[1000] = " 0XaF905";
 5     char s3[1000] = " 0xFa905";
 6 
 7     printf("hex:(int)%7d (hex)%7o to int:%7d\n", 0xff905, 0xff905, htoi(s1));
 8     printf("hex:(int)%7d (hex)%7o to int:%7d\n", 0XaF905, 0XaF905, htoi(s2));
 9     printf("hex:(int)%7d (hex)%7o to int:%7d\n", 0xFa905, 0xFa905, htoi(s3));
10 
11     system("pause");
12 }

函数htoi:

 1 int htoi(char s[]) {
 2     int i = 0;
 3     int num = 0;
 4     while (s[i] == ' ') i++;//除去前面的空格
 5     while (s[i] != '\0') {
 6         if (s[i] == '0' && (s[i + 1] == 'X' || s[i + 1] == 'x')) {
 7             i = i + 2;
 8             continue;
 9         }
10 
11         if (s[i] >= '0'&&s[i] <= '9') {
12             num = num * 16 + s[i] - '0';
13         } else if (s[i] >= 'A'&&s[i] <= 'F') {
14             num = num * 16 + s[i] - 'A' + 10;
15         } else if (s[i] >= 'a'&&s[i] <= 'f') {
16             num = num * 16 + s[i] - 'a' + 10;
17         } else {
18             printf("输入格式有误,请检查并重新输入!\n");
19         }
20         i++;
21     }
22 
23     return num;
24 }

 


C程序设计语言习题2-4

  重新编写函数squeeze(s1,s2),将字符串s1种任何与字符串s2中字符匹配的字符都删除:(原理和书中样例一样只是将一次if检测换成了for遍历)

主函数:

 1 int main()
 2 {
 3     char s1[1000] = " 0xff905";
 4     char s2[1000] = " 0XaF905";
 5 
 6     printf("s1:%s\ns2:%s\n", s1, s2);
 7     squeeze(s1, s2);
 8     printf("after:\ns1:%s\n", s1);
 9 
10     system("pause");
11 }

 

函数:squeeze

 1 void squeeze(char s1[], char s2[]) {
 2     int i, j, k, equal;
 3 
 4     for (i = k = 0; s1[i] != '\0'; i++) {
 5         equal = 0;
 6         for (j = 0; s2[j] != '\0'; j++) {
 7             if (s1[i] == s2[j]){
 8                 equal = 1;
 9                 break;
10             }
11         }
12         if (!equal)
13             s1[k++] = s1[i];
14     }
15     s1[k] = '\0';
16 }

 


C程序设计语言习题2-5

  编写函数any(s1,s2),将字符串s2中任一字符在字符串s2中第一次出现的位置作为返回结果:

主函数:

 1 int main()
 2 {
 3     char s1[1000] = "ABCcba";
 4     char s2[1000] = "abc";
 5 
 6     printf("s1:%s\ns2:%s\n", s1, s2);
 7     
 8 
 9     printf("s2 first in s1:location=%d\n", any(s1, s2));
10 
11     system("pause");
12 }

函数any:

int any(char s1[], char s2[]) {
    int i, j;
    for (i = 0; s1[i] != '\0'; i++) {
        for (j = 0; s2[j] != '\0'; j++)
            if (s1[i] == s2[j])
                return i;
    }

    return -1;
}

 


 

C程序设计语言习题2-6

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

主函数main:我用两个unsigned int值进行测试,n设为4,p设为(4+1=)5,然后由于两个int我用的是16进制就很容易知道,只要结果显示y中最后一个替换了x中第二个值就可以了。

 1 int main()
 2 {
 3     unsigned int x = 0X1234;
 4     unsigned int y = 0Xabcd;
 5     int p = 5;
 6     int n = 4;
 7     printf("result:%x\n", setbits(x, p, n, y));
 8 
 9     system("pause");
10 }

函数setbits(x,p,n,y):

 1 unsigned setbits(unsigned x, int p, int n, unsigned y) {
 2     //第一步,对x中间的n位清零
 3     x = x&((~0 << (p + n - 1)) | ~(~0 << n));
 4     /*第二步,将y最右边n位保留,其余置零,然后再将保留部分移
 5     ~ 到中间,与x对应。
 6     ~ */
 7     y = (y&~(~0 << n)) << (p - 1);
 8     
 9     return x | y;
10 }

 


 

C程序设计语言习题2-7

  编写一个函数invert(x,p,n),该函数返回对x执行下列操作后的结果值:

主函数main:

1 int main()
2 {
3     unsigned int x = 0X1234;
4     int n = 4;
5     int p = 5;
6 
7     printf("result:%x\n", invert(x, p, n));
8     system("pause");
9 }

函数invert:

 1 unsigned invert(unsigned x, int p, int n) {
 2     /*第一步,新建一个变量y,将x中间部分放到最右边copy下来并且取
 3     ~ 反,然后再将其余部分置为0,再放到中间,与x对应。
 4     ~ */
 5     unsigned y = (~(x >> p - 1)&~(~0 << n)) << p - 1;
 6     /*第二步,对x中间的n位清零。
 7     ~ */
 8     x = x&((~0 << (p + n - 1)) | ~(~0 << n));
 9     /*第三步,对x和y取或,即copy。
10     ~ */
11     return x | y;
12 }

 


 

C程序设计语言习题2-8

  编写一个函数rightrot(x,n),(。。权力的腐烂?这函数名什么鬼)该函数返回将x循环右移n位所得到的值:

  这道题老实说没做出来,上网一看加一个wordlength来求出专门的长度应该是最简单的。

主函数:结果显示将4“搬运”到最左边就可以了。

int main()
{
    unsigned int x = 0X1234;
    int n = 4;

    printf("result:%x\n", rightrot(x, n));
    system("pause");
}

 

函数rightrot:其中y是一个最左边n位同x相同的数,然后将y和向右前进n位的x数相或就可以了!

1 unsigned rightrot(unsigned x, int n) {
2     unsigned y = ((~0 << n) | x) << (wordlength(x) - n);
3     
4     return (x >> n) | y;
5 }

函数wordlength:这个很简单,知道要的效果就可以很快写出来了。

 1 int wordlength(unsigned x) {
 2     unsigned y = x;
 3     int i = 0;
 4 
 5     y = ~0;
 6     while (y != 0) {
 7         y = y >> 1;
 8         i++;
 9     }
10     return i;
11 }

 


 

C程序设计语言习题2-9

  在求对二的补码时,表达式x&=(x-1)可以删除x中最右边值为1的一个二进制位。请解释这样做的道理。并重写bitcount函数:

  如果搞懂了原理,那这道题就很容易了,我懒得去写主函数测试了。

函数bitcount:

/*道理很简单:一个非零二进制数最右边的情况只能是1个1加上n个零,当
~ n为0时,(x-1)让x从???1变成了???0,当n为i时,x从?
~ ??1后边连上i个0,变成了???0后边连着i个1,再和x一相与,就全
~ 变0光蛋。
~ */
int bitcount(unsigned x) {
    int b;

    while (x != 0) {
        b++;
        x &= (x - 1);
    }

    return b;
}

 


 

C程序设计语言习题2-10

  重新编写将大写字母转换为小写字母的函数lower(书中p34),并用条件表达式替代其中的if-else结构:

  这个实在太简单了,我懒得测试了。

1 int lower(int c) {
2     
3     return (c >= 'A'&&c <= 'Z') ? c + 'a' - 'A' : c;
4 }

 

转载于:https://www.cnblogs.com/GShell-Hzn/p/7050267.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值