C语言日常小练习-2.2

1. .编写函数
unsigned int reverse_bit(unsigned int value);
这个函数的返回值value的二进制位模式从左到右翻转后的值。
如:
在32位机器上25这个值包含下列各位:
00000000000000000000000000011001
翻转后:(2550136832)
10011000000000000000000000000000
程序结果返回:
2550136832

/*
1.编写函数:
unsigned int reverse_bit(unsigned int value);
这个函数的返回值value的二进制位模式从左到右翻转后的值。

如:
在32位机器上25这个值包含下列各位:
00000000000000000000000000011001
翻转后:(2550136832)
10011000000000000000000000000000
程序结果返回:
2550136832
*/
#include<stdio.h>  
#include<windows.h>  

/*value的二进制序列共32位,而b的值是从第一位开始左移的,故只能循环31次。*/
int reverse_bit1(unsigned int value)
{
	int a = 0;
	int b = 0;
	int i = 1;
	for (; i < 32; i++)
	{
		a = value & 1; //取value的最后一位  
		value = value >> 1; //value的数值右移,取前一位  
		b = a | b;//将a(value)的最后一位赋给b  
		b = b << 1;//b左移一位,空出最后一位给value的最后一位  
	}
	return b;
}

int reverse_bit2(unsigned int value)
{
	int a = 0;
	int b = 0;
	int i = 1;
	for (; i <= 32; i++)
	{
		a = value & 1;//将value的最后一位赋给a  
		if (1 == a)
			b |= (1 << (32 - i));//直接将value中的数按位置准确放入b中  
		value = value >> 1;
	}
	return b;
}

int main()
{
	printf("%u\n", reverse_bit1(25));
	printf("%u\n", reverse_bit2(25));

	system("pause");
	return 0;
}

2. .不使用(a+b)/2这种方式,求两个数的平均值。

#include<stdio.h>  
#include<windows.h>  
/* (a + b) / 2 ,存在溢出*/
int add_1(int a, int b)
{
	return (a + b) >> 1;
}

int add_2(int a, int b)
{
	if (b > a)
	{
		a ^= b;
		b ^= a;
		a ^= b;
	}
	return b + ((a - b) >> 1);
}
/*用a和b相同的部分加上a和b不同的地方,
a和b相同的部分为(a&b),
a和b不同的部分为(a^b),不同的部分除以二就是(a^b>>1)
*/
int add_3(int a, int b)
{
	return  (a&b) + ((a^b) >> 1);
}

int main()
{
	printf("%u\n",add_1(12,4));
	printf("%u\n",add_2(4,12));
	printf("%u\n", add_3(4, 12));

	system("pause");
	return 0;
}

3.编程实现:
一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。
请找出这个数字。(使用位运算)

#include <stdio.h>  
#include <windows.h>
int main()
{
	int arr[] = { 1, 5, 5, 1, 7, 6, 7, 8, 8,9,9 };
	int i = 0;
	int len = sizeof(arr) / sizeof(arr[0]);

	for (i = 1; i < len; i++)
	{
		arr[0] = arr[0] ^ arr[i];//^异或运算符,相异为1想同为0.
	}
	printf("%d\n", arr[0]);

	system("pause");
	return 0;
}

4.
有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
要求:
不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)。
这个题要求不能使用库函数,那就可以自己写一个strlen函数。
做这个题的思路就是:先将整个字符串反转过来,然后再对单个单词进行反转。

#include<stdio.h>
#include<assert.h>
#include <windows.h>

void reverse(char *start, char *end)
{
	assert(start);
	assert(end);
	while (start < end)
	{
		/*char temp = *start;
		*start = *end;
		*end = temp;*/

		*start ^= *end;
		*end ^= *start;
		*start ^= *end;
		start++;
		end--;
	}
}

int my_strlen(char *str)//得到数组长度定义求取字符串长度的函数
{
	int count = 0;
	while (*str++)
	{
		count++;
	}
	return count; //返回count指向int型的具体值
}

void reverse_str(char *str, int sz)
{
	assert(str);               //检测传入的字符串
	char *str1 = str;
	char *left = str;
	char *right = str + sz - 1;
	reverse(left, right);         //将字符串整体反转
	while (*str1)
	{
		left = str1;
		while ((*str1 != '\0') && (*str1 != ' ')) //找到单词,此处一定要加(*str1 != '\0')条件限制,因为找到最后一个单词的时候,*str1永远也不为空格
		{
			str1++;
		}
		right = str1 - 1;               //此时str1指向单词后方的空格,需要减一方能指向单词的最后一个字母
		reverse(left, right);               //继整体反转后再次反转单词,能使单词拼写顺序恢复过来
		if (*str1 == ' ')             //等于空格让指针后移一位否则不能参与下次循环。
		{
			str1++;
		}
	}
}

int main()
{
	char arr[] = "student a am i";
	int sz = my_strlen(arr);
	reverse_str(arr, sz);
	printf("%s\n", arr);
	
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39026129/article/details/80300632