The C Programming Language (second edition) 实践代码(置于此以作备份)

分手后的思念是犯贱 2021-12-13 05:06 261阅读 0赞

1、

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include<time.h>
  5. #define myPrint(expr) printf(#expr " =%d\n",expr);
  6. //2-3
  7. int htoi(char *s)
  8. {
  9. int n=0;
  10. while(*s!='\0')
  11. {
  12. if (*s=='x' || *s=='X')
  13. {
  14. n=0;
  15. }
  16. else if ('0'<=*s && *s<='9')
  17. {
  18. n=n*16+(*s-'0');
  19. }
  20. else if ('a'<=*s && *s<='z')
  21. {
  22. n=n*16+(*s-'a'+10);
  23. }
  24. else if ('A'<=*s && *s<='Z')
  25. {
  26. n=n*16+(*s-'A'+10);
  27. }
  28. s++;
  29. }
  30. return n;
  31. }
  32. void swap(int &x,int &y)
  33. {
  34. x^=y;
  35. y^=x;
  36. x^=y;
  37. }//x,y不能是数组的同一个元素
  38. unsigned getbits(unsigned x,int p,int n)
  39. {
  40. //从右向左数从0起,取从p开始向右的n个位,的值
  41. return (x>>(p+1-n)) & ~(~0<<n);
  42. }
  43. //2-6
  44. unsigned setbits(unsigned x,int p,int n,unsigned y)
  45. {
  46. //把x从右起从0起向右的n位置为y最右n位
  47. y&=~(~0<<n);//得到y最右n位
  48. y<<=(p+1-n);//最右n位左移到与x中间n位对应的位置上
  49. y|=x & (~(~0<<n));//使y最右n位与x最右n位一样
  50. x>>=(p+1);
  51. x<<=(p+1);//得到x里p位置左边的部分
  52. y|=x;
  53. return y;
  54. }
  55. //2-7
  56. unsigned invert(unsigned x,int p,int n)
  57. {
  58. //return setbits(x,p,n,~getbits(x,p,n));
  59. return x ^(~(~0<<n)<<(p-n+1));
  60. }
  61. //2-8
  62. unsigned rightrot(unsigned x,int n)
  63. {
  64. //0^a=a,1^a=~a
  65. return ((~(~0<<n) & x)<<(sizeof(unsigned)*8-n)) ^ (x>>n);
  66. }
  67. //递归,将一个整数作为字符串打印
  68. int isNegtive=1;
  69. void printd(int n)
  70. { if(n<0 && isNegtive)
  71. {
  72. putchar('-');
  73. isNegtive=0;
  74. }
  75. if (n/10)
  76. {
  77. printd(n/10);
  78. }
  79. //putchar((n%10<0)?(abs(n%10)+'0'):(n%10+'0'));//int最小值的相反数仍是该数
  80. putchar(abs(n%10)+'0');
  81. }
  82. //递归,将一个正整数作为字符串打印 void printd(unsigned int n) { if (n>=10) { printd(n/10); } putchar(n%10); }
  83. //快排的另一种写法
  84. void quickSort(int data[],int left,int right)
  85. {
  86. int i,last;
  87. if(left>=right)
  88. return;
  89. //partition
  90. last=left;
  91. for (i=left+1;i<=right;i++)
  92. {
  93. if ((data[i]<data[left]) && (++last!=i))
  94. {
  95. data[last]^=data[i];
  96. data[i]^=data[last];
  97. data[last]^=data[i];
  98. }
  99. }
  100. if(last!=left)
  101. {
  102. data[left]^=data[last];
  103. data[last]^=data[left];
  104. data[left]^=data[last];
  105. }
  106. //recursive
  107. quickSort(data,left,last-1);
  108. quickSort(data,last+1,right);
  109. }
  110. int binSearch(int data[],int n,int num)
  111. {
  112. int low,high,mid;
  113. low=0;
  114. high=n-1;
  115. while (low<=high)
  116. {
  117. mid=(low+high)/2;
  118. if (num==data[mid])
  119. return mid;
  120. else if (num>data[mid])
  121. low=mid+1;
  122. else
  123. high=mid-1;
  124. }
  125. return -1;
  126. }
  127. int main()
  128. {
  129. int c=1,d=2;
  130. swap(c,d);
  131. printf("c:%d d:%d\n",c,d);
  132. printf("%u\n",getbits(-2,2,3));
  133. printf("%u\n",setbits(25,4,3,1));
  134. printf("%u\n",invert(32,4,3));
  135. printf("%x\n",rightrot(0xff00ff,4));
  136. extern void mytest();
  137. mytest();
  138. int testdata[]={
  139. 4,3,2,5,6,9,8};
  140. quickSort(testdata,0,6);
  141. for (c=0;c<7;c++)
  142. {
  143. printf("%d ",testdata[c]);
  144. }
  145. printf("\na" " b%d\n",3);//前面的两个字符串将被连接起来
  146. myPrint(c);
  147. return 0;
  148. }
  149. void mytest()
  150. {
  151. extern int num;
  152. printf("\n%d\n",num);
  153. }
  154. int num=2;

2、

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include<time.h>
  5. #include <string.h>
  6. #include <limits.h>
  7. //2-3
  8. int htoi(char *s)
  9. {
  10. int n=0;
  11. while(*s!='\0')
  12. {
  13. if (*s=='x' || *s=='X')
  14. {
  15. n=0;
  16. }
  17. else if ('0'<=*s && *s<='9')
  18. {
  19. n=n*16+(*s-'0');
  20. }
  21. else if ('a'<=*s && *s<='z')
  22. {
  23. n=n*16+(*s-'a'+10);
  24. }
  25. else if ('A'<=*s && *s<='Z')
  26. {
  27. n=n*16+(*s-'A'+10);
  28. }
  29. s++;
  30. }
  31. return n;
  32. }
  33. unsigned getbits(unsigned x,int p,int n)
  34. {
  35. //从右向左数从0起,取从p开始向右的n个位,的值
  36. return (x>>(p+1-n)) & ~(~0<<n);
  37. }
  38. //2-6
  39. unsigned setbits(unsigned x,int p,int n,unsigned y)
  40. {
  41. //把x从右起从0起向右的n位置为y最右n位
  42. y&=~(~0<<n);//得到y最右n位
  43. y<<=(p+1-n);//最右n位左移到与x中间n位对应的位置上
  44. y|=x & (~(~0<<n));//使y最右n位与x最右n位一样
  45. x>>=(p+1);
  46. x<<=(p+1);//得到x里p位置左边的部分
  47. y|=x;
  48. return y;
  49. }
  50. //2-7
  51. unsigned invert(unsigned x,int p,int n)
  52. {
  53. //return setbits(x,p,n,~getbits(x,p,n));
  54. return x ^(~(~0<<n)<<(p-n+1));
  55. }
  56. //2-8
  57. unsigned rightrot(unsigned x,int n)
  58. {
  59. //0^a=a,1^a=~a
  60. return ((~(~0<<n) & x)<<(sizeof(unsigned)*8-n)) ^ (x>>n);
  61. }
  62. //2-9
  63. int bitcount(unsigned x)
  64. {
  65. //x的二进制形式中1的个数
  66. int n=0;
  67. while(x!=0)
  68. {
  69. // if (x & 1)
  70. // {
  71. // n++;
  72. // }//method1
  73. {
  74. x&=(x-1);
  75. n++;
  76. }//method2
  77. x>>=1;
  78. }
  79. return n;
  80. }
  81. char * reverse(char s[])
  82. {
  83. int i,j;
  84. for (i=0,j=strlen(s)-1;i<j;i++,j--)
  85. {
  86. s[i]^=s[j];
  87. s[j]^=s[i];
  88. s[i]^=s[j];
  89. }
  90. return s;
  91. }
  92. //3-4
  93. char * itoa(int num)
  94. {
  95. //num需在int范围内
  96. int i=0;
  97. bool isNegative=num<0?true:false;
  98. char s[100];//数的位数,包括可能的负号
  99. if (isNegative)
  100. {
  101. do
  102. {
  103. s[i++]=-(num%10)+'0';
  104. num/=10;
  105. } while(num!=0);
  106. s[i++]='-';
  107. }
  108. else
  109. {
  110. do
  111. {
  112. s[i++]=num%10+'0';
  113. num/=10;
  114. } while(num!=0);
  115. }
  116. s[i]='\0';
  117. reverse(s);
  118. return s;
  119. }
  120. int main()
  121. {
  122. char s[]="abcde423546g";
  123. printf("getbits: %u\n",getbits(-2,2,3));
  124. printf("setbits: %u\n",setbits(25,4,3,1));
  125. printf("invert: %u\n",invert(32,4,3));
  126. printf("rightrot:%x\n",rightrot(0xff00ff,4));
  127. printf("bitcount:%d\n",bitcount(131));
  128. printf("reverse: %s\n",reverse(s));
  129. printf("itoa: %s\n",itoa(INT_MIN));
  130. printf("itoa: %s\n",itoa(INT_MAX));
  131. return 0;
  132. }

3、

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. void printIntArgs(int arg1, ...) /* 输出所有int类型的参数,直到-1结束 */
  5. {
  6. //变长参数表处理
  7. va_list ap;
  8. int i;
  9. va_start(ap, arg1);
  10. for (i = arg1; i != -1; i = va_arg(ap, int))
  11. printf("%d ", i);
  12. va_end(ap);
  13. putchar('\n');
  14. }
  15. void myPrintf(int a,char *format,...)
  16. {
  17. //变长参数表处理
  18. char *p;
  19. va_list ap;//参数指针
  20. va_start(ap,a);//初始化ap,指向某个有名参数
  21. printf("%s\n",va_arg(ap,int));//再次调用后,ap指向最后一个有名参数。
  22. //在处理格式串前,必须将ap指向最后一个有名参数
  23. for (p=format;*p;p++)
  24. {
  25. if (*p!='%')
  26. {
  27. putchar(*p);
  28. continue;
  29. }
  30. switch(*++p)
  31. {
  32. case 'd':
  33. printf("%d",va_arg(ap,int));
  34. break;
  35. case 'f':
  36. printf("%f",va_arg(ap,double));
  37. break;
  38. case 's':
  39. printf("%s",va_arg(ap,char *));
  40. break;
  41. case 'c':
  42. printf("%c",va_arg(ap,char));
  43. break;
  44. }
  45. }
  46. va_end(ap);
  47. }
  48. void myScanf(char *format,...)
  49. {
  50. //变长参数表处理
  51. char *p;
  52. va_list ap;//参数指针
  53. //在处理格式串前,必须将ap指向最后一个有名参数
  54. va_start(ap,format);
  55. for (p=format;*p;p++)
  56. {
  57. if (*p!='%')
  58. {
  59. continue;
  60. }
  61. ++p;
  62. switch(*p)
  63. {
  64. //myScanf实参如&a传的是地址,所以里面参数值就是地址值,因此调用scanf时只要能按指针4字节得到其值即可
  65. case 'd':
  66. scanf("%d",va_arg(ap,void *));
  67. break;
  68. case 'f':
  69. scanf("%f",va_arg(ap, void *));
  70. break;
  71. case 's':
  72. scanf("%s",va_arg(ap,void *));
  73. break;
  74. case 'c':
  75. scanf("%c",va_arg(ap,void *));
  76. break;
  77. }
  78. }
  79. va_end(ap);
  80. }
  81. void scanfFormatTest()
  82. {
  83. //scanf格式特性示例
  84. char s[20];
  85. sscanf("123456abcd","%[1-4a-z]",s);
  86. printf("%s\n",s);//1234
  87. s[0]='\0';
  88. sscanf("123456abcd","%[14az]",s);
  89. printf("%s\n",s);//1
  90. s[0]='\0';
  91. sscanf("123456abcd","%[^3-4]",s);
  92. printf("%s\n",s);//12
  93. s[0]='\0';
  94. sscanf("a123456abcd","%[3-4]",s);
  95. printf("%s\n",s);//空,虽然串中有34但不是从首字符起的
  96. s[0]='\0';
  97. sscanf("123456abcd","%3[0-9a-z]",s);
  98. printf("%s\n",s);//123,限定最多读取3个字符
  99. s[0]='\0';
  100. sscanf("a123456,abcd","%*c%s",s);
  101. printf("%s\n",s);//123456,abcd,* 表示跳过此数据不读入. (也就是不把此数据读入参数中)
  102. s[0]='\0';
  103. sscanf("iios/12DDWDFF@122","%*[^/]/%[^@]",s);
  104. printf("%s\n",s);//12DDWDFF,综合使用,某种程度上可以充当正则使用
  105. s[0]='\0';
  106. }
  107. struct stu
  108. {
  109. char name[10];
  110. int num;
  111. int age;
  112. char addr[15];
  113. }boya[2],boyb[2],*pp,*qq;
  114. void freadFwriteTest()
  115. {
  116. //fread、fwrite示例
  117. FILE *fp;
  118. char ch;
  119. int i;
  120. pp=boya;
  121. qq=boyb;
  122. if((fp=fopen("stu_list.txt","wb+"))==NULL)
  123. {
  124. printf("Cannot open file strike any key exit!");
  125. getchar();
  126. }
  127. printf("input data");
  128. for(i=0;i<2;i++,pp++)
  129. scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);
  130. pp=boya;
  131. fwrite(pp,sizeof(struct stu),2,fp);
  132. rewind(fp);
  133. fread(qq,sizeof(struct stu),2,fp);
  134. printf("name number age addr");
  135. for(i=0;i<2;i++,qq++)
  136. printf("%s %5d%7d%s",qq->name,qq->num,qq->age,qq->addr);
  137. fclose(fp);
  138. getchar();
  139. }
  140. void StderrExitTest(int argc,char *argv[])
  141. {
  142. FILE *fp;
  143. void filecopy(FILE *,FILE *);
  144. char *prog=argv[0];
  145. if(argc==1)
  146. filecopy(stdin,stdout);
  147. else
  148. {
  149. while (--argc>0)
  150. {
  151. if ((fp=fopen(*++argv,"r"))==NULL)
  152. {
  153. fprintf(stderr,"%s: can't open %s\n",prog,*argv);
  154. //exit(1);
  155. }
  156. else
  157. {
  158. filecopy(fp,stdout);
  159. fclose(fp);
  160. }
  161. }
  162. }
  163. if (ferror(stdout))
  164. {
  165. fprintf(stderr,"%s: error writing stdout\n",prog);
  166. exit(2);
  167. }
  168. exit(0);
  169. }
  170. void filecopy(FILE *ifp,FILE *ofp)
  171. {
  172. int c;
  173. while ((c=getc(ifp))!=EOF)
  174. {
  175. putc(c,ofp);
  176. }
  177. }
  178. void ungetcTest()
  179. {
  180. char str[100];
  181. FILE *fp=fopen("file2.txt","r+");//文件file2.txt的内容:jklmn
  182. putc(getc(fp),stdout);//j
  183. putc(getc(fp),stdout);//k
  184. ungetc ('e', fp);
  185. ungetc ('f', fp);
  186. ungetc ('g', fp);
  187. //fscanf(fp,"%s",str);
  188. //printf("**%s**\n",str);//**felmn**
  189. putc(getc(fp),stdout);//f
  190. putc(getc(fp),stdout);//e
  191. putc(getc(fp),stdout);//l
  192. ungetc ('a', fp);
  193. ungetc ('b', fp);
  194. ungetc ('c', fp);
  195. printf ("%c", getc(fp));//c
  196. printf ("%c", getc(fp));//b
  197. printf ("%c", getc(fp));//a
  198. printf ("%c", getc(fp));//m
  199. printf ("%c", getc(fp));//n
  200. }
  201. void mallocMemsetTest()
  202. {
  203. int * p=NULL;
  204. p=(int *)malloc(3*sizeof(int));//malloc不能自动初始化
  205. if(NULL==p){
  206. printf("Can't get memory!\n");
  207. return -1;
  208. }
  209. printf("%d\n\n",*p);//未初始化的不定乱值-842150451
  210. memset(p,1,2*sizeof(int)); //用c++的函数memset初始化前两个数
  211. printf("%d\n",*p);//初始化值16843009
  212. printf("%d\n",p[1]==0x01010101);//1,说明每个字节被0x01代替
  213. printf("%d\n",p[2]);//未初始化乱值-842150451
  214. *(p+2)=2;
  215. printf("%d\n\n",p[2]);//2
  216. free(p);//动态分配者在程序结束前必须释放,否则内存泄露
  217. printf("%d\n",*p);;//乱值-572662307。free后指针仍指向原来指向的地方,为野指针
  218. return 0;
  219. }
  220. void callocTest()
  221. {
  222. int * p=NULL;
  223. int i=0;
  224. int SIZE=10;
  225. //为p从堆上分配SIZE个int型空间
  226. p=(int *)calloc(SIZE,sizeof(int));
  227. //p=(int *)malloc(SIZE*sizeof(int));与上句功能一样,只不过没有自动初始化
  228. if(NULL==p){
  229. printf("Error in calloc.\n");
  230. return -1;
  231. }
  232. //输出各个空间的值
  233. for(i=0;i<SIZE;i++)
  234. printf("p[%d]=%d\n",i,p[i]);
  235. //为p指向的SIZE个int型空间赋值
  236. for(i=0;i<SIZE;i++)
  237. p[i]=i;
  238. //输出各个空间的值
  239. for(i=0;i<SIZE;i++)
  240. printf("p[%d]=%d\n",i,p[i]);
  241. free(p);
  242. p=NULL;
  243. return 0;
  244. }
  245. //模拟c语言中的带缓冲的getchar(), syscalls.h
  246. int myGetchar(void)
  247. {
  248. static char buf[100];
  249. static char *bufp=buf;
  250. static int n=0;
  251. if (n==0)
  252. {
  253. n=read(0,buf,sizeof(buf));
  254. bufp=buf;
  255. }
  256. return (n-->0)?(unsigned char)*bufp++:EOF;
  257. }
  258. int intAverage(int x,int y)
  259. {
  260. //x,y和为负时会出错,如-4、3结果会得到-1,正确为0
  261. return ( (x & y) + ( (x^y) >>1 ));
  262. }
  263. int intOpposite(int x)
  264. {
  265. //-x=~x+1=~(x+`)
  266. return (~x+1);//~(X+1)
  267. }
  268. int intAbs(int x)
  269. {
  270. //无分支取绝对值
  271. int y=x>>(8*sizeof(x)-1);
  272. return (x^y)-y;//(x+y)^y
  273. }
  274. //递归实现进制转换
  275. void decimalTranslate(int n,int desBase){
  276. if(desBase>16 || desBase<2){
  277. printf("error:desBase should be between[2,16]\n");
  278. exit(0);
  279. }
  280. if(n){
  281. decimalTranslate(n/desBase,desBase);
  282. printf("%x",n%desBase);
  283. }
  284. }
  285. int main(int argc,char *argv[])
  286. {
  287. char a;
  288. char b[20]="helloworld";
  289. int c;
  290. float d;
  291. //变长参数表处理
  292. //printIntArgs(2,1,3,4,-1);
  293. //myPrintf(3," char:%c\n int:%d\n double%f\n string:%s\n",'ab',12,12.2,"hello world" " good");
  294. //myScanf("%c%s%d%f",&a,b,&c,&d);
  295. //printf("%c %s %d %f\n",a,b,c,d);
  296. //scanf格式特性示例
  297. //scanfFormatTest();
  298. //fread fwrite示例
  299. //freadFwriteTest();
  300. //stdrr exit示例
  301. //StderrExitTest(argc,argv);
  302. //ungetc示例
  303. //ungetcTest();
  304. //存储管理函数示例
  305. //mallocMemsetTest();
  306. //callocTest();
  307. //putchar(myGetchar());
  308. //rename("fi.txt","file");
  309. printf("%+d %+d\n",-10,10);//加号,输出正负号
  310. printf("% d % d % d\n",-10,+10,10);//一个空格,若数的第一个字符为符号位,则代替该空格
  311. printf("%x\n",013);
  312. printf("hello%d %n",10,&c);printf("%d\n",c);//%n
  313. return 0;
  314. }

转载于:https://www.cnblogs.com/z-sm/p/4273181.html

发表评论

表情:
评论列表 (有 0 条评论,261人围观)

还没有评论,来说两句吧...

相关阅读