「C2_koizumi」の編集履歴(バックアップ)一覧はこちら
「C2_koizumi」(2009/11/22 (日) 14:40:20) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
#comment()
&bold(){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.
#highlight(linenumber.c){{
#include<stdio.h>
#include<limits.h>
int pr2_1()
{
printf("CHAR: %d ~ %d\n", CHAR_MIN, CHAR_MAX);
printf("UCHAR: %d ~ %d\n", 0, UCHAR_MAX);
printf("SHORT: %d ~ %d\n", SHRT_MIN, SHRT_MAX);
printf("USHORT: %d ~ %d\n", 0, USHRT_MAX);
printf("LONG: %ld ~ %ld\n", LONG_MIN, LONG_MAX);
printf("ULONG: %lu ~ %lu\n", 0, ULONG_MAX);
printf("LONGLONG: %llu ~ %llu\n", LONG_LONG_MIN, LONG_LONG_MAX);
//printf("ULONGLONG: %d ~ %llu\n", 0, ULONG_LONG_MAX);
return 0;
}
}}
&bold(){Exercise 2-2.}Write a loop equivalent to the for loop above without using && or || .
#highlight(linenumber.c){{
i = 0;
while(1) {
if(i < lim-1) {
if(c = getchar() != '\n') {
if(c != EOF) {
s[i] = c;
}
}
}
i++;
}
}}
&bold(){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 .
#highlight(linenumber.c){{
int htoi(char* hex_str)
{
hex_str += 2; //skip 0x or 0X
int num;
int hex_ch;
int result;
result = 0;
while((hex_ch = *hex_str++) != '\0') {
switch(hex_ch) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
num = hex_ch - '0';
break;
case 'A':
num = 10;
break;
case 'B':
num = 11;
break;
case 'C':
num = 12;
break;
case 'D':
num = 13;
break;
case 'E':
num = 14;
break;
case 'F':
num = 15;
break;
default:
printf("invalid charctor: %d\n", hex_ch);
exit(1);
}
result = result * 16 + num;
}
return result;
}
}}
&bold(){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 .
#highlight(linenumber.c){{
void squeeze(char s1[], char s2[] )
{
int i, j, k;
for(k = 0; s2[k] != '\0'; k++) {
for(i = j = 0; s1[i] != '\0'; i++)
if(s1[i] != s2[k])
s1[j++] = s1[i];
s1[j] = '\0';
}
}
}}
&bold(){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.)
#highlight(linenumber.c){{
int any(char *s1, char *s2)
{
int minIndex, s1Len;
int i,j;
minIndex = s1Len = strlen(s1);
for(j = 0; s2[j] != '\0'; j++)
for(i = 0; s1[i] != '\0'; i++)
if(s1[i] == s2[j])
if(minIndex > i)
minIndex = i;
if(minIndex == s1Len)
return -1;
return minIndex;
}
}}
&bold(){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.
#highlight(linenumber.c){{
unsigned int getbits(unsigned int x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
unsigned int setbits(unsigned int x, int p, int n, unsigned int y) {
unsigned int bit_x;
bit_x = getbits(x, p, n);
return bit_x | ((y >> n) << n); //bit_x OR number which set the rightmost n bits of y to 0
}
}}
&bold(){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.
#highlight(linenumber.c){{
//for debug
void printBinary(unsigned int x)
{
int i;
int n;
n = sizeof(x) * 8;
for( i = n-1; i >= 0; i--)
printf("%d", (x >> i) & 0x01);
printf("\n");
}
unsigned int getbits(unsigned int x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
//from Exercise 2-6
unsigned int setbits(unsigned int x, int p, int n, unsigned int y) {
unsigned int bit_x;
bit_x = getbits(x, p, n);
return bit_x | ((y >> n) << n); //bit_x OR number which set the rightmost n bits of y to 0
}
//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.
unsigned int invert(unsigned int x, int p, int n)
{
unsigned int retrieved, y;
y = x >> (p-n+1);
//printBinary(y);
y = setbits(~x, p, n, y);
//printBinary(y);
y = y << (p-n+1);
y = setbits(x, p-n, p-n+1, y);
return y;
}
}}
&bold(){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.
#highlight(linenumber.c){{
//a function rightrot(x,n) that returns the value of the integer x
//rotated to the right by n bit positions.
static unsigned int rightrot(unsigned int x, int n)
{
unsigned int tmp, size;
size = 8 * sizeof(x); //get number of x's bit
tmp = getbits(x, n-1, n); //get the rightmost n bits of x
//printBinary(tmp);
x = x >> n;
tmp = tmp << size-n; //set tmp's bits to the leftmost n bits of x
return x | tmp;
}
}}
&bold(){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 .
#highlight(linenumber.c){{
int bitcount(unsigned x)
{
int b;
for(b = 0; x!=0; x = x&(x-1))
b++;
return b;
}
}}
&bold(){Exercise 2-10.}Rewrite the function lower, which converts upper case letters to lower case, with a conditional expression instead of if-else .
#highlight(linenumber.c){{
char mylower(char ch)
{
return ('A' <= ch && ch <= 'Z') ? ch + 0x20 : ch;
}
}}
- Exercise 2-2が無限ループになってますよ -- ushiku (2009-11-22 14:40:20)
#comment()
&bold(){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.
#highlight(linenumber.c){{
#include<stdio.h>
#include<limits.h>
int pr2_1()
{
printf("CHAR: %d ~ %d\n", CHAR_MIN, CHAR_MAX);
printf("UCHAR: %d ~ %d\n", 0, UCHAR_MAX);
printf("SHORT: %d ~ %d\n", SHRT_MIN, SHRT_MAX);
printf("USHORT: %d ~ %d\n", 0, USHRT_MAX);
printf("LONG: %ld ~ %ld\n", LONG_MIN, LONG_MAX);
printf("ULONG: %lu ~ %lu\n", 0, ULONG_MAX);
printf("LONGLONG: %llu ~ %llu\n", LONG_LONG_MIN, LONG_LONG_MAX);
//printf("ULONGLONG: %d ~ %llu\n", 0, ULONG_LONG_MAX);
return 0;
}
}}
&bold(){Exercise 2-2.}Write a loop equivalent to the for loop above without using && or || .
#highlight(linenumber.c){{
i = 0;
while(1) {
if(i < lim-1) {
if(c = getchar() != '\n') {
if(c != EOF) {
s[i] = c;
}
}
}
i++;
}
}}
&bold(){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 .
#highlight(linenumber.c){{
int htoi(char* hex_str)
{
hex_str += 2; //skip 0x or 0X
int num;
int hex_ch;
int result;
result = 0;
while((hex_ch = *hex_str++) != '\0') {
switch(hex_ch) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
num = hex_ch - '0';
break;
case 'A':
num = 10;
break;
case 'B':
num = 11;
break;
case 'C':
num = 12;
break;
case 'D':
num = 13;
break;
case 'E':
num = 14;
break;
case 'F':
num = 15;
break;
default:
printf("invalid charctor: %d\n", hex_ch);
exit(1);
}
result = result * 16 + num;
}
return result;
}
}}
&bold(){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 .
#highlight(linenumber.c){{
void squeeze(char s1[], char s2[] )
{
int i, j, k;
for(k = 0; s2[k] != '\0'; k++) {
for(i = j = 0; s1[i] != '\0'; i++)
if(s1[i] != s2[k])
s1[j++] = s1[i];
s1[j] = '\0';
}
}
}}
&bold(){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.)
#highlight(linenumber.c){{
int any(char *s1, char *s2)
{
int minIndex, s1Len;
int i,j;
minIndex = s1Len = strlen(s1);
for(j = 0; s2[j] != '\0'; j++)
for(i = 0; s1[i] != '\0'; i++)
if(s1[i] == s2[j])
if(minIndex > i)
minIndex = i;
if(minIndex == s1Len)
return -1;
return minIndex;
}
}}
&bold(){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.
#highlight(linenumber.c){{
unsigned int getbits(unsigned int x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
unsigned int setbits(unsigned int x, int p, int n, unsigned int y) {
unsigned int bit_x;
bit_x = getbits(x, p, n);
return bit_x | ((y >> n) << n); //bit_x OR number which set the rightmost n bits of y to 0
}
}}
&bold(){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.
#highlight(linenumber.c){{
//for debug
void printBinary(unsigned int x)
{
int i;
int n;
n = sizeof(x) * 8;
for( i = n-1; i >= 0; i--)
printf("%d", (x >> i) & 0x01);
printf("\n");
}
unsigned int getbits(unsigned int x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
//from Exercise 2-6
unsigned int setbits(unsigned int x, int p, int n, unsigned int y) {
unsigned int bit_x;
bit_x = getbits(x, p, n);
return bit_x | ((y >> n) << n); //bit_x OR number which set the rightmost n bits of y to 0
}
//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.
unsigned int invert(unsigned int x, int p, int n)
{
unsigned int retrieved, y;
y = x >> (p-n+1);
//printBinary(y);
y = setbits(~x, p, n, y);
//printBinary(y);
y = y << (p-n+1);
y = setbits(x, p-n, p-n+1, y);
return y;
}
}}
&bold(){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.
#highlight(linenumber.c){{
//a function rightrot(x,n) that returns the value of the integer x
//rotated to the right by n bit positions.
static unsigned int rightrot(unsigned int x, int n)
{
unsigned int tmp, size;
size = 8 * sizeof(x); //get number of x's bit
tmp = getbits(x, n-1, n); //get the rightmost n bits of x
//printBinary(tmp);
x = x >> n;
tmp = tmp << size-n; //set tmp's bits to the leftmost n bits of x
return x | tmp;
}
}}
&bold(){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 .
#highlight(linenumber.c){{
int bitcount(unsigned x)
{
int b;
for(b = 0; x!=0; x = x&(x-1))
b++;
return b;
}
}}
&bold(){Exercise 2-10.}Rewrite the function lower, which converts upper case letters to lower case, with a conditional expression instead of if-else .
#highlight(linenumber.c){{
char mylower(char ch)
{
return ('A' <= ch && ch <= 'Z') ? ch + 0x20 : ch;
}
}}