[the c programming language]-2章:类型、运算符与表达式

来源:互联网 发布:免费发外链软件 编辑:程序博客网 时间:2024/05/17 21:38

不是很喜欢在网上做笔记。开来得学习下思维导图或者熟悉下印象笔记了。觉得这种技术类图书的笔记,没必要把书上的东西挪出来。也不喜欢很杂乱的笔记。简单的就好。

这次没有在本子上写笔记,中途的疑惑灵感什么酒都忘记了。就敲段标题关键字的简介,然后贴代码吧。待会儿把贪吃蛇放上来。

    运算符指定将要进行的操作。    表达式则把变量与常量组合起来生成新的值。    对象的类型决定该对象可取值的集合以及可以对该对象执行的操作。

-

/*2-1.编写一个程序以确定分别由signed及unsigned限定的char、short、int与long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。 *//*//第一种,用标准头文件的符号常量 #include <stdio.h>#include <limits.h> int main(){printf("char_bit = %d\n",CHAR_BIT);printf("char_max = %d\n",CHAR_MAX);printf("char_min = %d\n",CHAR_MIN);printf("int_max = %d\n",INT_MAX);printf("int_min = %d\n",INT_MIN);printf("long_max = %ld\n",LONG_MAX);printf("long_min = %ld\n",LONG_MIN);printf("schar_max = %d\n",SCHAR_MAX);printf("schar_min = %d\n",SCHAR_MIN);printf("short_max = %d\n",SHRT_MAX);printf("short_min = %d\n\n",SHRT_MIN);printf("uchar_max = %u\n",UCHAR_MAX);printf("ushort_max = %u\n",USHRT_MAX);printf("uint_max = %u\n",UINT_MAX);printf("ulong_max = %lu\n",LONG_MAX);return 0;}*///第二种,直接计算 #include <stdio.h>#include <limits.h>  //用到CHAR_BIT ,char类型的位数 int main(){printf("signed char min = %d\n",(char)((unsigned char)~0  <<(CHAR_BIT-1)) ); //书上的方法是 -(char)((unsigned char)~0 >> 1) 输出的-127,有点蠢诶。不过给了指点。 当然,也可以-1后得到。 -(char)((unsigned char)~0 >>1) -1 printf("signed char max = %d\n",(char)((unsigned char)~0 >> 1)); printf("signed short min = %d\n",-(short)((unsigned short) ~0 >> 1) -1);  printf("signed short max = %d\n",(short)((unsigned short) ~0 >> 1)); printf("signed int min = %d\n",-(int)((unsigned int)~0 >>1) -1); printf("signed int max = %ld\n",(int)((unsigned int)~0 >>1));printf("signed long min = %ld\n",-(long)((unsigned long)~0 >>1) -1);printf("signed long max = %d\n\n",(long)((unsigned long)~0 >>1));printf("unsigned char max = %u\n",(unsigned char) ~0);printf("unsigned short max = %u\n",(unsigned short) ~0);printf("unsigned int max = %u\n",(unsigned int) ~0);printf("unsigned long max = %lu\n",(unsigned long) ~0);return 0;}

/*2-2.在不使用运算符&&或||的条件下编写一个与上面的for循环语句等价的循环语句。 */#include <stdio.h>int main(){int i=0,c;const int lim = 20;  //maxchar s[lim] ;/*for(i=0; i<lim-1 && (c=getchar())!='\n' && c!=EOF; ++i)s[i]=c; *///改写for ,不用 && || 运算符。while(i<lim-1) {c=getchar() ;if(c =='\n')break;if(c==EOF)break;s[i++]=c;}s[i]='\0';printf("%s\n",s);return 0;}

看到习题2.3想起还写了个2-36的进制转换,等下也贴出来。

/*2-3.编写函数htoi(s),把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值。字符串中允许包含的数字包括:0~9、a~f、A~F。*/#include <stdio.h>int htoi(char s[]){  //把书上的atoi里的for修改一下就好了。 int i,n=0;for(i=0; s[i]!='\0' ;++i){if(s[i]>='0' && s[i]<='9')n=16 * n + (s[i] - '0');else if(s[i]>='a' && s[i]<='f'){n=16 * n + (s[i]-'a'+10);} else if(s[i]>='A' && s[i]<='F'){n=16 * n + (s[i]-'A'+10);} //printf("i=%d s[%d]=%c  n=%d \n",i,i,s[i],n);}return n;} int main(){const int MAX=20;int i,c;char s[MAX];for(i=0; i<MAX-1 && (c=getchar())!='\n' && c!=EOF;++i){s[i]=c;}s[i]='\0';long n=htoi(s);printf("%ld\n",n);return 0;}

/*2-4.重新编写函数squeeze(s1,s2),将字符串s1中任何与字符串 s2中字符匹配的 字符 都删除。 */#include <stdio.h>void squeeze(char s[],char s2[]){int i,j,k;for(i=k=0; s[i]!='\0';++i){for ( j=0; s[i] != s2[j] && s2[j]!='\0';j++) ;if(s2[j]=='\0');s[k++] = s[i];}s[k]='\0';}int main(){const int MAX=20;char s[MAX];int i,c;for(i=0; i<MAX-1 && (c=getchar())!='\n' && c!=EOF;++i){s[i]=c;}s[i]='\0';squeeze(s,"onion");printf("%s\n",s);return 0;}

/*2-5.编写函数any(s1,s2),将字符串s2中的任一字符在字符串s1中的第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1. */#include <stdio.h>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;}int main(){const int MAX=20;char s[MAX];int i,c;for(i=0; i<MAX-1 && (c=getchar())!='\n' && c!=EOF;++i){s[i]=c;}s[i]='\0';printf("%d\n",any(s,"cat"));return 0;}


2-6理解错误,搞了一个多小时,以为是p到n位设置到y到n位。其实是p到n位设置到y中最右边n位。orz...


/*2-6.编写一个函数setbits(x,p,n,y),该函数返回对x执行下列操作后的结果值 :将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变。 */#include <stdio.h>unsigned getbits(unsigned x,int p,int n,int y){ //靠,把这个解决,成功了。不过我自己都看不懂了。。趁还有印象,快加点注释 unsigned k;k=  (~0 << n)  & y; //k是 y中右边n位为0 return ( (x >> (p+1-n)) & ~(~0 << n) ) | k ; // |k之前的部分是需要的字段。即最右边n位为需要的x中p开始的n位。 } void zh(unsigned m){  //转换为2进制,并输出 printf("%u=",m);int i=0,d[50];while(m!=0){d[i]=m%2;m/=2;++i;}while(i--){printf("%d",d[i]);}printf("\n");}int main(){unsigned m;int p,n,y;scanf("%d %d %d %d",&m,&p,&n,&y);zh(m);zh(y);unsigned s=getbits(m,p,n,y);//printf("s=%u\n",s );zh(s);return 0;}

/*2-7.编写一个函数invert(x,p,n),该函数返回对x执行下列操作后的结果值:将x中从第p位开始的n个(二进制)位求反(即1变0,0变1),x的其余各位保持不变。 */#include <stdio.h>unsigned invert(unsigned x,int p,int n){return (~(~0<<n)) << (p+1-n) ^ x ;}/*void zh(unsigned m){  printf("%u=",m);int i=0,d[50];while(m!=0){d[i]=m%2;m/=2;++i;}while(i--){printf("%d",d[i]);}printf("\n");}int main(){unsigned m;int p,n;scanf("%d %d %d",&m,&p,&n);zh(m);unsigned s=invert(m,p,n);zh(s);return 0;}*/

/*2-8.编写一个函数rightrot(x,n),该函数返回将x循环右移(即从最右端移出的位从最左端移入)n(二进制)位后所得到的值。 */#include <stdio.h>int wordlength(){ //计算计算机unsigned字长 ,即位数。 int i;unsigned v=(unsigned)~0;for(i=1; (v>>=1)!=0;++i);//printf("\n字长=%d\n",i);return i;}unsigned rightrot(unsigned x,int n){while(n--){int i= (x & 1) << (wordlength()-1);x >>= 1;x |= i;}return x; } void zh(unsigned m){  printf("%u=",m);int i=0,d[50];while(m!=0){d[i]=m%2;m/=2;++i;}while(i--){printf("%d",d[i]);}printf("\n");}int main(){unsigned m;int p;scanf("%d %d",&m,&p);zh(m);m=rightrot(m,p);zh(m);return 0;}

/*2-9.在求对二的补码时,表达式x&=(x-1)可以删除x中最右边值为1的一个二进制位。请解释这样做的道理。用这一方法重写bitcount函数,以加快其执行速度。 */#include <stdio.h>int bitcount(unsigned x){int b;for(b=0; x!=0; x &= (x-1))b++;return b;}void zh(unsigned m){  printf("%u=",m);int i=0,d[50];while(m!=0){d[i]=m%2;m/=2;++i;}while(i--){printf("%d",d[i]);}printf("\n");}int main(){unsigned m;scanf("%d",&m);zh(m);m=bitcount(m);printf("1的二进制位数%u\n",m);return 0;}

/*2-10.重新编写将大写字母转换小写字母的函数lower,并用条件表达式替代其中的if-else结构。 加上了转大写功能。 */#include <stdio.h>int lower(int c){  //大写转小写 return (c>='A' && c<='Z') ? c+('a'-'A'):c; } int upper(int c){  //小写转大写 return (c>='a' && c<='z') ? c-('a'-'A'):c; }int main(){int c;while((c=getchar()) !=EOF){printf("%c",upper(c));}return 0;}


0 0
原创粉丝点击