C语言学习之经典练习题目

例 1

        不知道大家小时候是怎么背每个月有多少天的,我至今还记得我小学时候的背诵口诀,一三五七八十腊,三十一天永不差,四六九冬三十整。这是这道题的第一个关键点,我们也知道平年的二月是28天而闰年的2月是29天。这就是这道题的第二个关键点了。我们就从这两个地方下手去写程序。首先第一步先判断是否是闰年,如果是是闰年再判断是几月并对应输出,如果不是闰年同样也是判断输入为几月并对应输出。具体代码如下所示。

#include <stdio.h>

int leap_year(int y)
{
    if((y%4==0)&&(y%100!=0)||(y%400==0))
        return 1;
    else
        return 0;
}

int main() 
{
    int y=0;
    int m=0;

    while(scanf("%d %d",&y,&m)==2)
    {
        int ret=leap_year(y);
        if(ret==1)
        {
            if(m==2)
                printf("%d\n",29);
            else if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
                printf("%d\n",31);
            else
                printf("%d\n",30);
        }

        else  
        {
            if(m==2)
                printf("%d\n",28);
            else if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
                printf("%d\n",31);
            else
                printf("%d\n",30);
        }
          
    }

}

例 2

        这个题的思路就是当字符串输入后我们找到字符串的起始地址和末尾地址,通过中间变量来交换起始地址与末尾地址的值,然后将起始地址+1,末尾地址-1,这样循环下去,直至不能再交换为止。具体代码如下。

#include <stdio.h>
#include<string.h>
int main()
{
    char arr[100001]={0};
    gets(arr);

    char*left=arr;
    int len=strlen(arr);
    char*right=arr+len-1;

    while(left<right)
    {
        char temp=*left;
        *left=*right;
        *right=temp;
        left++;
        right--;
    }

    printf("%s",arr);

    return 0;
}

例 3

具体思路是将输入的数字存入数组后,定义两个变量当标记,比较相邻两个数字的大小,如果是顺序其中第一个标记的值+1,逆序则第二个标记的值+1。若标记的值等于输入的值N-1则,输入的值是有序的,若不等于N-1则无序具体代码如下。

#include <stdio.h>

int main()
{
    int i = 0;
    int N = 0;
    int count1 = 0;
    int count2 = 0;
    scanf("%d", &N);
    int arr[50];

    for (i = 0; i < N; i++)
    {
        scanf("%d", &arr[i]);
    }

    for (i = 0; i < N - 1; i++)
    {
        if (arr[i] >= arr[i + 1])
        {
            count1++;
        }
        else if (arr[i] <= arr[i + 1])
        {
            count2++;
        }

    }

    if (count1 == N - 1 || count2 == N - 1)
        printf("sorted");
    else
        printf("unsorted");

}

例 4

        这道题的具体思路就是从左往右找到一个偶数,然后从右往左再找到一个奇数,然后交换两个数。具体代码如下。

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int len = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = len - 1;
	while (left < right)
	{
		//从左往右找偶数
		while (arr[left] % 2 == 1)
		{
			left++;
		}
		//从右往左找奇数

		while (arr[right] % 2 == 0)
		{
			right--;
		}
		//交换

		int temp = 0;
		temp = arr[left];
		arr[left] = arr[right];
		arr[right] = temp;
	}

	int i = 0;
	for (i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

接下来我们练习几个有关与操作符的习题。


例 5

求一个数二进制中1的个数。

方法一,一个int类型的数字是4个字节也就是32位,可通过右移让其每一位 或1 就能够得到具体1的个数。

int main()
{
	int a = 0;  
	scanf("%d", &a);
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((a >> i) & 1) == 1)
			count++;

	}
	printf("%d", count);

	return 0;
}

        这样要循环32次效率会不会太慢了呢。在这里介绍一下第二种方法,一个数字a & (a-1)就能够将a二进制序列最右侧的1去掉,例如 1111 & 1110  结果将最右侧的1去掉就是1110,再举个例子00010000&00001111=0000 0000。这样我们就又有了新思路,具体代码如下。

int main()
{
	int a = 0;
	scanf("%d", &a);
	int i = 0;
	int count = 0;
	
	while (a)
	{
		a = a & (a - 1);
		count++;
	}
	printf("%d", count);

	return 0;
}

        经过测试我们第二个方法也能够完成功能。接下来我们再来练习几个这样的例子。


例 6

求0-100中2的幂次方的个数

2的幂次方的规律是2进制序列中都只有1个1。通过上面介绍的规律,程序的编写也就变的简单了。

int main()
{
	int i = 0;
	int a = 0;
	for (i = 0; i <= 100; i++)
	{
		
		if ((i & (i - 1))==0)
		{
			a++;
			printf("%d ", i);
		}
		
	}
	printf("\n");
	printf("%d", a);

	return 0;
}


例 7

两个int 类型的数二进制位不同的个数。

        两个数比较二进制位是否相同我们很容易就能够想到异或操作符,当两个二进制位异或不同为1,相同为0。若想实现题中所给的功能,我们可以将两个数进行 ^ 操作,然后再将 ^ 后的数字中有多少个1的个数求出,即可获得二进制位中不同的个数。

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);

	int count = 0;
	int num = 0;
	count = (a ^ b);

	while (count)
	{
		count = count & (count - 1);
		num++;
	}
	printf("%d", num);

}

        记录一下自己的做题记录,后续还会有很多的题目与大家分享。希望大家工作顺利,学习进步。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值