Chapter 2 – Types, Operators and Expressions of TCPL

Chapter 2 – Types, Operators and Expressions

Exercise 2-1

Write a program to determine the ranges of char, short, int, and long variables, both signed and unsigned, by printing appropriate values from standard headers and by direct computation. Harder if you compute them: determine the ranges of the various floating-point types.

#include

#include

 

int

main ()

{

    printf("Size of char %d bits/n", CHAR_BIT);

    printf("Value of char max %d/n", CHAR_MAX);

    printf("Value of char min %d/n", CHAR_MIN);

    printf("Value of int min %d/n", INT_MIN);

    printf("Value of int max %d/n", INT_MAX);

    printf("Value of long min %ld/n", LONG_MIN);       /* RB */

    printf("Value of long max %ld/n", LONG_MAX);       /* RB */

    printf("Value of short min %d/n", SHRT_MIN);

    printf("Value of short max %d/n", SHRT_MAX);

    printf("Value of unsigned char %u/n", UCHAR_MAX);  /* SF */

    printf("Value of unsigned long %lu/n", ULONG_MAX); /* RB */

    printf("Value of unsigned int %u/n", UINT_MAX);    /* RB */

    printf("Value of unsigned short %u/n", USHRT_MAX); /* SF */

   

    return 0;

}

Exercise 2-2

Write a loop equivalent to the for loop above without using && or ||.

#include

 

#define MAX_LENGTH 100

 

int main(void)

{

    /*

    for (i = 0; i < lim-1 && (c=getchar()) != '/n' && c != EOF; ++i)

        s[i] = c;

    */

    int i = 0, lim = MAX_LENGTH, c;

    char s[MAX_LENGTH];

   

    while (i < (lim - 1)) {

        c = getchar();

       

        if (c == EOF)

            break;

        else if (c == '/n')

            break;

       

        s[i++] = c;

    }

   

    s[i] = '/0';   /* terminate the string */   

    return 0;

}

Exercise 2-3

Write the function htoi(s), which converts a string of hexadecimal digits (including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0 through 9, a through f, and A  through F.

#include

#include

 

/* ishexdigit: judge whether c is a hex digital */

int ishexdigit(int c) {

    if (c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f' || c >= '0' && c <= '9') {

        return true;

    }

    else

        return false;

}

 

/* intvalue: return the int value of a hex char */

int intvalue(int c) {

    int result  = -1;

    if (c >= 'A' && c <= 'F' ) {

        result = c - 'A'  + 10;

    } else if(c >= 'a' && c <= 'f') {

        result = c - 'a'  + 10;

    } else if(c >= '0' && c <= '9') {

        result = c - '0';

    }

    return result;

}

 

/* convert strings of hex numbers to int */

int htoi(const char s[])

{

    int i, n, sign;

    for (i = 0; isspace(s[i]); i++); /* skip white space */

    sign = (s[i] == '-') ? -1 : 1;

    if (s[i] == '+' || s[i] == '-') { /* skip sign */

        i++;

    }

 

    for (; s[i] == '0'; i++);

    for (; s[i] == 'x' || s[i] == 'X'; i++);

 

    for (n = 0; ishexdigit(s[i]); i++)

        n = 16 * n + intvalue(s[i]);

    return n;

}

 

int main() {

    char i[]  = "-0x1111";

   

    printf("%d/n", htoi(i));

 

    return 0;

}

Exercise 2-4

Write an alternate version of squeeze(s1,s2) that deletes each character in the string s1 that matches any character in the string s2 .

#include

 

/* squeeze: delete any character in s2 from s1 */

void squeeze(char s1[], char s2[]);

/* has: judge whether ch is in s */

int has(char s[], char ch);

 

 

int main() {

    char str1[] = "mmoimoa/n";

    char str2[] = "m";

    printf("%s", str1);

    squeeze(str1, str2);

    printf("%s", str1);   

    return 0;

}

 

/* squeeze: delete all s2 from s1 */

void squeeze(char s1[], char s2[]) {

    int i, j;

    for (i = 0, j = 0; s1[i] != '/0'; i++) {

        if (!has(s2, s1[i]))

            s1[j++] = s1[i];

    }   

    s1[j] = '/0';

}

 

 

/* has: judge whether ch is in s */

int has(char s[], char ch) {

    int k, flag;

    for (k = 0, flag = 0; s[k] != '/0'; k++) {

        if (s[k] == ch) {

            flag = 1;

            break;

        }

    }

    return flag;

}

Exercise 2-5

Write the function any(s1,s2) , which returns the first location in the string s1 where any character from the string s2 occurs, or -1 if s1 contains no characters from s2 . (The standard library function strpbrk does the same job but returns a pointer to the location.)

#include

 

int any(char *s1, char *s2)

{

    char array[256] = {0};

   

    int  i;

    if (s1 == NULL) {

        return s2 == NULL ? 0 : -1;

    }

   

    while(*s2 != '/0') {

        array[*s2] = 1;

        s2++;

    }

   

    for ( i = 0; s1[i] != '/0'; i++) {

        if (array[s1[i]])

            return (i);

    }

   

    return(-1);

}

 

int main() {

    char string[100] = "The 3 men and 2 boys ate 5 pigs/n";

    int idx;

    char * result = string;

  

    printf( "1: %s/n", string );

   

    idx = any( result, "0123456789" );   

    result += idx;

    printf( "2: %s/n", result++);

 

    idx = any( result, "0123456789" );

    result += idx;   

    printf( "3: %s/n", result++);

 

    idx = any( result, "0123456789" );

    result += idx;   

    printf( "4: %s/n", result);

   

    return 0;

}

Exercise 2-6

Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.

#include

 

/*

setbits: that returns x with the n bits that begin

at position p set to the rightmost n bits of y, leaving

the other bits unchanged.

*/

unsigned setbits(unsigned x, int p, int n, unsigned y);

 

 

int main() {

    int x = 100;

    int y = 23;

    printf("0x%x/n", x);

    printf("0x%x/n", y);

    setbits(x, 7, 4, y);

    printf("0x%x/n", setbits(x, 7, 4, y));

    return 0;

}

 

unsigned setbits(unsigned x, int p, int n, unsigned y)

{

   return (x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) |

       ((y & ~(~0 << n)) << (p + 1 - n));

}

Exercise 2-7

Write a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.

/*

Write a function invert(x,p,n) that returns x with

the n bits that begin at position p inverted (i.e.,

1 changed into 0 and vice versa), leaving the others

unchanged. */

 

#include

 

unsigned invert(unsigned x, int p, int n) {

    return x ^ ( ~0 << (p - n + 1) & (~(~0 << (p+1))) );

}

int main() {

    unsigned x = 0x7fff;

    printf("0X%x/n", x);

    printf("0X%x/n", invert(x, 3, 3));

    return 0;

}

/*

Result:

0X7fff

0X7ff1

*/

Exercise 2-8

Write a function rightrot(x,n) that returns the value of the integer x rotated to the right by n bit positions.

/*

Write a function rightrot(x,n) that returns the value of

the integer x rotated to the right by n bit positions.

*/

 

/* rightrot: returns the value of

the integer x rotated to the right by n bit positions.

*/

#include

#include

 

unsigned rightrot(unsigned x, int n);

 

int main() {

    unsigned x = 23;

    printf("0X%x/n", x);

    printf("0X%x/n", rightrot(x, 3));

    return 0;

}

unsigned rightrot(unsigned x, int n) {

    /* calculate number of bits in type */

    size_t s = sizeof(x) * CHAR_BIT;

    n = n % s;

   

    /* if either is zero then the original value is unchanged */

    if((0 == x) || (0 == n))

        return x;

   

    return (x >> n) | (x << (s - n));

   

}

Exercise 2-9

In a two's complement number system, x &= (x-1) deletes the rightmost 1-bit in x . Explain why. Use this observation to write a faster version of bitcount .

/*

In a two's complement number system, x &= (x-1) deletes

the rightmost 1-bit in x . Explain why. Use this observation

to write a faster version of bitcount .

*/

#include

/* count 1 bits in x */

int bitcount(unsigned x) {

    int b = 0;

    while (x != 0) {

        x &= (x - 1);

        b++;

    }

    return b;

}

int main() {

    unsigned x = 8;

    printf("%d/n", bitcount(x));

    return 0;

}

Exercise 2-10

Rewrite the function lower, which converts upper case letters to lower case, with a conditional expression instead of if-else.

#include

/* tolower: change ch to lower case */

int tolower(int ch);

int main()

{

    int c;

    while ((c = getchar()) != EOF) {

        putchar(tolower(c));

    }

    return 0;

}

int tolower(int ch) {   

    return (ch >= 'A' && ch <= 'Z') ? (ch + 32) : ch;

}

 

   

你可能感兴趣的:(C/C++/VC)