《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
總結
以上是生活随笔為你收集整理的《C程序设计语言》-第2章-习题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10自带无线投屏功能(含无安装失败
- 下一篇: 解决戴尔电脑禁用无线网络问题