K&R The C Programming language 2

本文探讨了C语言中不同数据类型(如char、short、int、long等)的取值范围,并通过标准头文件limits.h进行了展示。此外,还介绍了字符串转十六进制整数、字符搜索、位操作等实用函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2-1打印标准头文件中的响应值,确定signed & unsigned限定的char / short / int / long类型变量的取值范围。

#include <stdio.h>
#include <limits.h>
int main(void)
{
	printf("Size of Char %d.\n", CHAR_BIT);
	printf("Size of Char MAX %d.\n", CHAR_MAX);
	printf("Size of Char MIN %d.\n", CHAR_MIN);
	printf("Size of INT MIN %d.\n", INT_MIN);
	printf("Size of INT MAX %d.\n", INT_MAX);
	printf("Size of LONG MIN %d.\n", LONG_MIN);
	printf("Size of LONG MAX %d.\n", LONG_MAX);
	printf("Size of SHORT MIN %d.\n", SHRT_MIN);
	printf("Size of SHORT MAX %d.\n", SHRT_MAX);
	printf("Size of UNSIGNED SHORT MAX %d.\n", USHRT_MAX);
	printf("Size of UNSIGNED LONG MAX %lu.\n", ULONG_MAX);
	printf("Size of UNSIGNED INT MAX %lu.\n", UINT_MAX);
	printf("Size of UNSIGNED CHAR MAX %d.\n", UCHAR_MAX);
	getchar();
	return 0;
}

limits.hC标准函数库中的头文件,定义了整数类型的一些极限值。

  • CHAR_BIT 字节的最小位数:8
  • SCHAR_MIN 有符号字符类型的最小值:-128
  • SCHAR_MAX 有符号字符类型的最大值:+127
  • UCHAR_MAX 无符号字符类型的最大值:255
  • CHAR_MIN 字符类型的最小值
  • CHAR_MAX 字符类型的最大值
  • MB_LEN_MAX 多字节字符在任何locale中可能的最长字节数:4/5/8/16
  • SHRT_MIN 短整型最小值:-32768,即- 215
  • SHRT_MAX 短整型最大值:+32767,即 215 - 1
  • USHRT_MAX 无符号短整型最大值:65535 ,即 216 - 1
  • INT_MIN 整型最小值:-2147483648,即 -(231)
  • INT_MAX 整型最大值:+2147483647 ,即231 - 1
  • UINT_MAX 无符号整型最大值:4294967295,即232 - 1
  • LONG_MIN 长整型最小值:-2147483648 ,即-(231 )
  • LONG_MAX 长整型最大值:+2147483647 ,即231 - 1
  • ULONG_MAX 无符号长整型最大值:4294967295 ,即232 - 1
  • LLONG_MIN 长长整型最小值:-9223372036854775808 ,即-(263 )
  • LLONG_MAX 长长整型最大值:+9223372036854775807 ,即263 - 1
  • ULLONG_MAX 无符号长长整型最大值:18446744073709551615 ,即264- 1

2.2

for(i=0;i<lim-1&&(c=getchar())!='\n' && c!=EOF;++i)

等价写出,不用&&    ||两种运算符

while()写法:

i=0;

while(i<lim-1)

{

if((c=getchar())=='\n')

break;

else if(c==EOF)

break;

for的循环体;

i++;

}

for()写法:

for(i=0; ( c=getchar() )==EOF ? 0 : (c=='\n' ? 0 : (i<lim-1 ? 1 : 0) ; ++i)

2-3函数htoi(s),s是由十六进制数字组成字符串,将其转换为等价的整型值。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

unsigned int htoi(char *);
#define MAX 8
int main(void)
{
	char *s;
	s = (char *)malloc(MAX);
	unsigned int i,correct_i;
	while((gets_s(s,MAX))!="'\n'")
	{
		i = htoi(s);
		correct_i = strtoul(s, 0, 16);//一个转换字符串s到16进制无符号整数的函数,可用作验证
		if (i==correct_i)
		{
			printf("%d\n", i);
		}
		else
			printf("The function htoi() is wrong.\n");
	}
	getchar();
	return 0;
}
unsigned int htoi(char *s)
{
	if (strlen(s)==0)
	{
		exit(0);
	}
	unsigned int i,result=0,tmp;
	char c;
	for (i = 0; i <strlen(s);i++)
	{
		c = s[i];
		if (c=='0'&&((c=s[i+1])=='x'||c=='X'))
		{
			i++;
			continue;
		}
		if ((tmp = c - 'a') >= 0 && tmp <= 6)
			tmp = c - 'a'+10;
		else if ((tmp = c - 'A') >= 0 && tmp <= 6)
			tmp = c - 'A'+10;
		else
			tmp = c - '0';
		result = result * 16 + tmp;
		
	}
	
	return result;
}

2-5编写函数any(s1,s2),将字符串s2中的任一字符在字符串s1中第一次出现位置作为结果返回。如果s1中不包含s2中的字符,则返回-1.

/*这里有一个有趣的解法,刚开始我也以为二重for循环是必须的,
字符串s1的长度可以无限,但是所出现的字符的种类优先,定义
一个字符数组,里面有256个位置,在字符的int值相应位置存入
字符第一次出现的位置,整个过程需要对s1进行一次遍历,时间
复杂度为o(n)。再对字符串s2进行遍历比较,即可得到结果。因
为s1中可能不存在s2中的任意字符,需要对s2进行完整遍历。
整个过程时间复杂度为o(m+n)。主要用到了char类型有限的性质*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int any(char *, char *);
#define LEFT 3
#define RIGHT 3
int main(void)
{
	char *leftstr[] =
	{
		"gastrointestinal",
		"heterogeneousness",
		"incomprehensibility",
		"justifications",
		"knowledgeable",
		"lexicographically",
		"microarchitectures",
		"nondeterministically",
		"organizationally",
		"phenomenologically",
		"quantifications",
		"representationally",
		"straightforwardness"
	};
	char *rightstr[] =
	{
		"a",
		"the",
		"quick",
		"brown",
		"dog",
		"jumps",
		"over",
		"lazy"
	};
	//字符不只是小写英文字母,可以有\t  \n  ' '  *&*&^%^^ 各种
	int i = any(leftstr[LEFT], rightstr[RIGHT]);
	if (i)
		printf("The location of any char of rightstr in leftstr is %d.\n", i);
	else
		printf("There is no char of rightstr exist in leftstr.\n");
	getchar();
	return 0;
}
int any(char *left, char *right)
{
	int charList[128], location = 0,i=0;
	memset(charList, 0, sizeof(charList));
	for (; i < strlen(left);i++)
	{
		if (charList[int(left[i])]==0)
		{
			charList[int(left[i])] = i+1;//这里需要注意,在定义位置时候,i有为0的情况,但是默认charList全部为0,所以这里+1以表区别
		}
	}
	for (i=0; i<strlen(right); i++)
	{
		if (charList[right[i]]!=0)
		{
			location = charList[right[i]];
			break;
		}
	}
	return location;
}

2-6编写一个函数setbits(x,p,n,y),该函数返回对x执行下列操作后的结果值:将x中从第p位开始的n个(二进制)为设置为y中最右边n位的值,x的其余各位保持不变。

/*就是与0或保持原样,与1或全1;
	  与0与全0,与1与保持全1
起始数必须用~0,用1的话会出现最高位自动补零的情况
除了位数,设置参数为unsigned型,不然自动视最高位为符号位*/
#include <stdio.h>
#define N 3
#define P 5
unsigned setbits(int,int,int, int);
int main(void)
{
	unsigned x = 109,y=13,result;
	printf("%u\n",setbits(x,P,N,y));
	getchar();
	return 0;
}
unsigned  setbits(int x, int a, int b, int y)
{
	unsigned tmp1, tmp2,tmp3,tmp4;
	tmp1=~(~(~0 << b) << (a - b));
	tmp2 = x&tmp1;
	tmp3 = (~(~0 << b) & y) << (a - b);
	tmp4 = tmp2 | tmp3;
	return tmp4;
}

2-8编写函数rightrot(x,n),该函数返回将x循环右移(即从最右端移出的位将从最左端移入)n(二进制)位后所得到的值。

/*没有用>>,而是用除法*/
#include <stdio.h>
#define N 6
int main(void)
{
	int x = 341,n=N,tmp=1,num0=0;
	while (n--)
	{
		if (x % 2)
		{
			while ((tmp *= 2)*2 < x)
				;
			while (num0)
			{
				tmp *= 2;
				num0--;
			}
			x = x / 2 + tmp;
		}
		else
		{
			x = x / 2;
			num0++;
		}
		printf("%d\n", x);
		getchar();
		tmp = 1;
	}
	
	return 0;
}

但是这里有一个隐藏的bug:到底像101101这种数,如果用unsigned类型存入,在计算机中存储是101101前面补入26个0,然后按照题目的意思,是移一位后值为100000 00000 00000 00000 00000010110还是值为1101101?上面的方法给出的答案是按照后面一种结题思路进行,但是如果深究,可能是前面一种思路更符合题目的意思。

下面给出用>>的方法,默认是32位运算。

#include <stdio.h>
#define N 6
int main(void)
{
	unsigned x = 341,tmp,n=N;
	while (n--)
	{
		if (x&1)
		{
			x = (x >> 1)|(~(~0U >> 1));
		}
		else
			x = x >> 1;

		printf("%u\n", x);
		getchar();
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值