目录
1.统计二进制中1的个数
写一个函数返回参数二进制中 1 的个数。
比如: 15 00001111 4 个 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
方法1:
//15 % 2 = 1;
//15 / 2 = 7;00000111
//7 % 2 = 1;
//7 / 2 = 3; 00000011
//3 % 2 = 1;
//1 / 2 = 0; 00000000
int N(unsigned int n)//unsigned无符号整形
{
int count = 0;
while (n)
{
if (n % 2 == 1)
{
count++;
}
n = n / 2;
}
return count;
}
方法2:
//11111111 11111111 11111111 11111111
//00000000 00000000 00000000 00000001
//00000000 00000000 00000000 00000001
int N(int n)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if ((n >> i) & 1 == 1)
{
count++;
}
}
return count;
}
方法3:
//n & (n - 1)
//n = 15;
//1111 -n
//1110 -n-1
//1110 -n
//1101 - n-1
//1100 - n
//1011 - n-1
//1000 - n
//0111 - n-1
//0000 - n
int N(int n)
{
int i = 0;
int count = 0;
while(n)
{
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
int n = 15;
int ret = N(n);
printf("%d", ret);
return 0;
}
类似:写一个代码判断一个数字是不是2的n次方 n&(n-1)
2.求两个数二进制中不同位的个数
编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
输入例子:
1999 2299
输出例子:7
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
int i = m^n;
int count = 0;
while (i)
{
i = i&(i - 1);
count++;
}
printf("%d\n", count);
return 0;
}
3.打印整数二进制的奇数位和偶数位
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
void Printbit(int num)
{
for (int i = 31; i >= 1; i -= 2)
{
printf("%d ", (num >> i) & 1);
}
printf("\n");
for (int i = 30; i >= 0; i -= 2)
{
printf("%d ", (num >> i) & 1);
}
printf("\n");
}
int main()
{
int n = 0;
scanf("%d", &n);
Printbit(n);
return 0;
}
4.求下面代码的输出结果
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
short *p = (short*)arr;
int i = 0;
for (i = 0; i<4; i++)
{
*(p + i) = 0;
}
for (i = 0; i<5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
10进制:1
二进制:00000000 00000000 00000000 00000001
16进制:00 00 00 01
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
00 00 00 00 00 00 00 00
5.将一句话的单词进行倒置,标点不倒置。
每次测试会输入1个测试用例, 输入用例的长度不超过100
依次输出倒置之后的字符串,以空格分割
输入:i like beijing
输出:beijing. like i
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void reverse(char* left, char* right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[100] = { 0 };
gets(arr);
//1.字符串整体翻转
int len = strlen(arr);
reverse(arr,arr+len-1);
//2.每个单词逆序
char* start = arr;
while (*start)
{
char* end = start;
while (*end != ' ' && *end !='\0')
{
end++;
}
//逆序一个单词
reverse(start, end - 1);
if (*end == ' ')
start = end + 1;
else
start = end;
}
printf("%s\n",arr);
return 0;
}
6.代码示例(补充)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int i = 0;
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//在Debug版本和release版本中不同
printf("%p\n",&i);
printf("%p\n",&arr[9]);
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("HeHe\n");
}
return 0;
}
i和arr是局部变量
因为局部变量是放在栈区上的
栈区的使用习惯是:先使用高地址,在使用低地址
数组随着下标的增长,地址是有低到高变化的,for循环中,i的内容是从0,一直增加到12,而数组只有10个空间,因此会越界,每次访问arr数组i号位置时,都会将该位置内容设置为0,当访问到arr[12]时,也会将该位置的内容设置成0,而位置恰好为i的位置,即arr[12]恰巧将 i 设置为0,因此造成死循环。
在VC6.0环境下——跳过0个整型
gac环境下——1个整型
VS2013——2019跳过2个整型
在release版本中,对代码进行优化,不会陷入死循环。