交换两个变量(不创建临时变量)
不允许创建临时变量,交换两个整数的内容
情况如下:
按位异或(相同为0,不相同未1):" ^ ";
a ^ a = 0;
a ^ 0 = a;
//就有
3 ^ 5 ^3 = 5;
#include
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d\n", a, b);
return 0;
}
输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。
#include
int main()
{
int n = 0;
int sum = 0;
scanf("%d", &n);
while (n != 0)
{
n = n & (n - 1);//n为00101000;n - 1得到00100111;n & (n - 1)得到00100000
//就会去掉一个1
sum++;
}
printf("%d\n", sum);
return 0;
}
更好的详细解题:
/*
方法一:
思路:
循环进行以下操作,直到n被缩减为0:
1. 用该数据模2,检测其是否能够被2整除
2. 可以:则该数据对应二进制比特位的最低位一定是0,否则是1,如果是1给计数加1
3. 如果n不等于0时,继续1
*/
int count_one_bit(int n)
{
int count = 0;
while(n)
{
if(n%2==1)
count++;
n = n/2;
}
return count;
}
/*
上述方法缺陷:进行了大量的取模以及除法运算,取模和除法运算的效率本来就比较低。
方法二思路:
一个int类型的数据,对应的二进制一共有32个比特位,可以采用位运算的方式一位一位的检测,具体如下
*/
int count_one_bit(unsigned int n)
{
int count = 0;
int i = 0;
for(i=0; i<32; i++)
{
if(((n>>i)&1) == 1)
count++;
}
return count;
}
/*
方法二优点:用位操作代替取模和除法运算,效率稍微比较高
缺陷:不论是什么数据,循环都要执行32次
方法三:
思路:采用相邻的两个数据进行按位与运算
举例:
9999:10 0111 0000 1111
第一次循环:n=9999 n=n&(n-1)=9999&9998= 9998
第二次循环:n=9998 n=n&(n-1)=9998&9997= 9996
第三次循环:n=9996 n=n&(n-1)=9996&9995= 9992
第四次循环:n=9992 n=n&(n-1)=9992&9991= 9984
第五次循环:n=9984 n=n&(n-1)=9984&9983= 9728
第六次循环:n=9728 n=n&(n-1)=9728&9727= 9216
第七次循环:n=9216 n=n&(n-1)=9216&9215= 8192
第八次循环:n=8192 n=n&(n-1)=8192&8191= 0
可以观察下:此种方式,数据的二进制比特位中有几个1,循环就循环几次,而且中间采用了位运算,处理起来比较高效
*/
int count_one_bit(int n)
{
int count = 0;
while(n)
{
n = n&(n-1);
count++;
}
return count;
}
打印整数二进制的奇数位和偶数位
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
#include
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
//奇数位
for (i = 0; i < 32; i += 2)
{
printf("%d ",(n >> i) & 1);
}
printf("\n");
//偶数位
for (i = 1; i <= 31; i += 2)
{
printf("%d ", (n >> i) & 1);
}
return 0;
}
输入两个整数,求两个整数二进制格式有多少个位不同
#include
int main()
{
int a = 0;
int b = 0;
int n = 0;
int i = 0;
int count = 0;
scanf("%d %d",&a, &b);
n = a ^ b;
for (i = 0; i < 32; i++)
{
if (((n >> i) & 1) == 1)
count++;
}
printf("%d\n",count);
return 0;
}
更好的方法:
/*
思路:
1. 先将m和n进行按位异或,此时m和n相同的二进制比特位清零,不同的二进制比特位为1
2. 统计异或完成后结果的二进制比特位中有多少个1即可
*/
#include
int calc_diff_bit(int m, int n)
{
int tmp = m^n;
int count = 0;
while(tmp)
{
tmp = tmp&(tmp-1);
count++;
}
return count;
}
int main()
{
int m,n;
while(scanf("%d %d", &m, &n) == 2)
{
printf("%d\n", calc_diff_bit(m, n));
}
return 0;
}
输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。
#include
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a ,&b);
int arr1[1000] = {0};
int arr2[1000] = {0};
int i = 0;
for (i = 0;i < a;i++)
{
scanf("%d",&arr1[i]);
}
for (i = 0; i < b; i++)
{
scanf("%d", &arr2[i]);
}
int q = 0;
int j = 0;
int n = 0;
int arr3[1000] = { 0 };
i = 0;
while (j < a && n < b)
{
if (arr1[j] < arr2[n])
{
arr3[i] = arr1[j];
i++;
j++;
}
else
{
arr3[i] = arr2[n];
i++;
n++;
}
}
if (j == a && n < b)
{
for (; n < b; n++)
{
arr3[i] = arr2[n];
i++;
}
}
else
{
for (; j < a; j++)
{
arr3[i] = arr1[j];
i++;
}
}
q = i;
for (i = 0; i < q; i++)
{
printf("%d ",arr3[i]);
}
return 0;
}
输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。
#include
int main()
{
int count1 = 0;
int count2 = 0;
int n = 0;
scanf("%d", &n);
int i = 0;
int arr[50] = { 0 };
for (i = 0; i < n; i++)
{
scanf("%d ",&arr[i]);
}
for (i = 0; i < n-1; i++)
{
if (arr[i] >= arr[i + 1])
{
count1++;
}
if (arr[i] <= arr[i + 1])
{
count2++;;
}
}
if (count1 == n - 1)
{
printf("sorted");
}
else if (count2 == n - 1)
{
printf("sorted");
}
else
{
printf("unsorted");
}
return 0;
}
KiKi想获得某年某月有多少天,请帮他编程实现。输入年份和月份,计算这一年这个月有多少天。
多组输入,一行有两个整数,分别表示年份和月份,用空格分隔。
针对每组输入,输出为一行,一个整数,表示这一年这个月有多少天
#include
int is_year(int year)
{
return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}
int main()
{
int year = 0;
int month = 0;
int sum = 0;
while (scanf("%d %d", &year, &month) == 2)
{
int day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
sum = is_year(year);
if (sum == 1)
{
day[2] = 29;
}
printf("%d\n",day[month]);
}
return 0;
}
使用指针打印数组内容
写一个函数打印arr数组的内容,不使用数组下标,使用指针。
arr是一个整形一维数组。
#include
#include
void print(int* arr,int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
printf("%d ",*(arr+i));
}
}
int main()
{
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int len = 0;
len = sizeof(arr) / sizeof(arr[0]);
print(arr,len);
return 0;
}
将一个字符串str的内容颠倒过来,并输出
int main()
{
char str[10000] = { 0 };
gets(str);
int sz = strlen(str);
/*print(str, sz);*/
int i = 0;
for (i = 0; i < sz; i++)
{
char tmp = 0;
tmp = str[i];
str[i] = str[sz - 1];
str[sz-- - 1] = tmp;
}
printf("%s\n", str);
return 0;
}
用C语言在屏幕上输出以下图案:
#include
int main()
{
int line = 0;
scanf("%d", &line);
int i = 0;
int j = 0;
//上半部分
for (i = 0; i <= line/2; i++)
{
for (j = 0; j < (line-2*i)/2; j++)
{
printf(" ");
}
for (j = 0; j < 2 * i + 1; j++)
{
printf("*");
}
printf("\n");
}
//下半部分
for (i = 1; i <= line / 2; i++)
{
for (j = 0; j <= i-1; j++)
{
printf(" ");
}
for (j = 0; j < (line - (2 * i)); j++)
{
printf("*");
}
printf("\n");
}
return 0;
}
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,
如 : 153=1 ^ 3+5 ^ 3+3 ^ 3,则153是一个“水仙花数”。
#include
#include
int Daffodil(int i)
{
int sum = 0;
int n = 1;
int tmp = i;
while (tmp / 10)
{
n++;
tmp /= 10;
}
tmp = i;
while (tmp)
{
sum =(int)pow(tmp % 10,n) + sum;
tmp = tmp / 10;
}
return sum == i;
}
int main()
{
int i = 0;
for (i = 0; i < 100000; i++)
{
if (Daffodil(i))
{
printf("%d ", i);
}
}
return 0;
}
求Sn = a + aa + aaa + aaaa + aaaaa的前5项之和,其中a是一个数字,
例如:2 + 22 + 222 + 2222 + 22222
#include
int Sn(int a)
{
int sum = 0;
int i = 0;
int n = a;
for (i = 0; i < 5; i++)
{
sum = a + sum;
a = n + a * 10;
}
return sum;
}
int main()
{
int a = 0;
int sum = 0;
scanf("%d", &a);
sum = Sn(a);
printf("%d\n", sum);
return 0;
}
下面代码的结果是:
#include
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
A.>
B.<
C.不输出
D.程序有问题
C语言中,0为假,非0即为真。
全局变量,没有给初始值时,编译其会默认将其初始化为0。
i的初始值为0,i--结果-1,i为整形,sizeof(i)求i类型大小是4,按照此分析来看,结果应该选择B,但是sizeof的返回值类型实际为无符号整形,因此编译器会自动将左侧i自动转换为无符号整形的数据,-1对应的无符号整形是一个非常大的数字,超过4或者8,
下列程序段的输出结果为( )
unsigned long pulArray[] = {6,7,8,9,10};
unsigned long *pulPtr;
pulPtr = pulArray;
*(pulPtr + 3) += 3;
printf("%d,%d\n",*pulPtr, *(pulPtr + 3));
unsigned long pulArray[] = {6,7,8,9,10};
unsigned long *pulPtr;
pulPtr = pulArray; // 数组名代表数组首元素地址,因此pulptr指向的是数组中第一个元素的位置
*(pulPtr + 3) += 3; // pulptr+3访问的是数组中第三个元素(数组下标从0开始),故将9改为9+3=12
printf("%d,%d\n",*pulPtr, *(pulPtr + 3)); // 打印第一个和第三个元素,因此:打印6和12
下面关于指针运算说法正确的是:( )
A.整形指针+1,向后偏移一个字节
B.指针-指针得到是指针和指针之间的字节个数
C.整形指针解引用操作访问4个字节
D.指针不能比较大小
注意:此题是有问题的,说法不严谨,如果将整形指针理解成int*类型的指针,那么一下说法解析如下
A:错误,整形指针+1,向后便宜一个整形类型的大小,即4个字节
B:错误,两个指针相减,指针必须指向一段连续空间,减完之后的结构代表两个指针之间相差元素的个数
C:正确,整形指向的是一个整形的空间,解引用操作访问4个字节
D:指针中存储的是地址,地址可以看成一个数据,因此是可以比较大小的