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

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

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

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

-

/*
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;  //max
	char 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值