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

来源:互联网 发布:linux根目录满了 后果 编辑:程序博客网 时间:2024/06/08 16:09

练习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
原创粉丝点击