保证年份为4位数且日期合法

发布时间:2025-06-24 07:47:58  作者:北方职教升学中心  阅读量:232


文章目录

  • C语言常考及易错题整理
  • 选择题
    • 全局、根据出现次数的奇偶性,可以使用异或运算求解。

      lowbit=xor & (−xor),**则 lowbit为 x 和 y 的二进制表示中的最低不同位,**可以用 lowbit区分 xy

      数据范围:1≤m≤100

      这道题的关键在于知道规律后,能够找到第 n 个数据立方的起始奇数,从这个起始奇数开始,组成连续的n个奇数项之和的表达式即可。

      C选项,a为数组首地址是常量不能改变,

      所以A,B,C都是错的,选择D


      编程题

      计算日期到天数转换

      根据输入的日期,计算是这一年的第几天。

      所以 a,c,d才是指针类型


      1. 以下程序结果输出是什么
      #include<stdio.h>#defineN2#defineMN+1#defineNUM(M+1)*M/2intmain(){printf("%dn",NUM);return0;}

      答案解析:

      正确答案:8

      宏只是替换,替换后NUM的样子是(2+1+1)*2+1/2,计算得8


      转义字符

      1. 以下程序段输出结果是什么:
      #include<stdio.h>intmain(){chars[]="123456123456t";printf("%dn",strlen(s));return0;}

      答案解析:

      正确答案:12

      这里考查转义字符,注意:\\表示字符'\'\123(ASCII码为83)表示字符'S'\t表示制表符,这些都是一个字符


      操作符

      1. 下面代码段的输出是:
      #include<stdio.h>intmain(){inta=3;printf("%dn",(a+=a-=a*a));return0;}

      答案解析:

      正确答案:-12

      a+=a-=a*a等价于a=a+(a=a-a*a),即先计算``a=a-a*a,所以此时a的值为3-3*3=-6,再计算-6+(-6)=-12赋值给a,所以a`的值 为-12,也就是整个表达式的值,就是-12

      循环

      1. 我们知道C语言的 break 语句只能跳出离它最近的一层循环,可是有时候我们需要跳出多层循环,下列跳出多层循环的做法正确的是【多选】( ) A: 将程序写成函数用return结束函数,便可跳出循环

      B: 修改外层循环条件例如

      for(inti =0;i <MAX1 ;i ++){for(intj =0;j <MAX2 ;j ++){if(condition ){i =MAX1;break;}}}

      C:在外层循环设置判断条件例如

      for(;symbol !=1&&condition2 ;){for(;symbol !=1&&condition3 ;){if(condition1 )symbol =1;}}

      D: 在外层循环后面加入break例如

      for(;condition2 ;){for(;condition3 ;){if(condition1 )symbol =1;}if(symbol ==1)break;}

      答案解析:

      正确答案:ABCD

      此题旨在整理跳出多层循环的方法,每个选项都是正确的,代码为伪代码,condition代表逻辑表达式


      1. 执行下面的程序段,语句3的执行次数为( )
      or(i =0;i <=n-1;i++)// (1)for(j =n;j >i;j--)// (2)state;// (3

      答案解析:

      正确答案:n(n+1)/2

      外循环有n次,当i=0,内循环为n次,当i=1,内循环为n-1次,当i=2时,内循环为n-2次,以此类推,总次数为 n+(n-1)+(n-2)+…+2+1,就是个等差数列,等于n(n+1)/2


      1. 对于下面说法:正确的是()
      t=0;while(printf("*")){t++;if(t<3)break;}

      A: 其中循环控制表达式与0等价
      B: 其中循环控制表达式与’0’等价
      C: 其中循环控制表达式是不合法的
      D: 以上说法都不对

      答案解析:

      正确答案:B

      print(“*”)函数的返回值是字符串中字符的个数,即为1。

      给定一个数组 nums代表了集合 S发生错误后的结果。

      1. 中间大于右边 [3, 4, 5, 1, 2],这种情况下,最小数一定在右边;则left = middle + 1

      2.中间等于右边 [1, 0, 1, 1, 1], 这个是[0, 1, 1, 1, 1] 旋转过来的,这时候需要缩小范围 right–;,注意不能是 left++,因为是非降序数组,所以要缩小右边范围,符合我们的判断规则。


      1. 设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是( )

      A: n=0;while(ch=getchar()!='\n') n++;

      B: n=0;while(getchar()!='\n') n++;

      C: for(n=0;getchar()!='\n';n++);

      D: n=0;for(ch=getchar();ch!='\n';n++);

      答案解析:

      正确答案:D

      对于for循环,其中第一项初始化表达式只执行一次,因此ch只从输入流中取一个字符,之后就再不会取字符,因此会死循环


      1. 若运行以下程序时,从键盘输入 ADescriptor<回车>,则下面程序的运行结果是( )
      #include<stdio.h>intmain(){charc;intv0=0,v1=0,v2=0do{switch(c=getchar()){case'a':case'A':case'e':case'E':case'i':case'I':case'o':case'O':case'u':case'U':v1 +=1;default:v0+=1;v2+=1;}}while(c!='\n');printf("v0=%d,v1=%d,v2=%d\n",v0,v1,v2);return0;}

      答案解析:

      正确答案:12 4 12

      代码switch语句中没有break,则每次找到入口进入后,顺序执行到代码块结束为止。

      例如:

      1^3=1

      2^3=3+5

      3^3=7+9+11

      4^3=13+15+17+19

      输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。

      int*findErrorNums(int*nums,intnumsSize,int*returnSize){int*newnums =(int*)malloc(2*sizeof(int));*returnSize =2;intxor =0;for(inti =1;i <=numsSize;i++){xor ^=i ^nums[i -1];}intlowbit =xor&(-xor);intnum1 =0;intnum2 =0;for(inti =0;i <numsSize;i++){if((lowbit &nums[i])==0)num1 ^=nums[i];elsenum2 ^=nums[i];}for(inti =1;i <=numsSize;i++){if((lowbit &i)==0)num1 ^=i;elsenum2 ^=i;}// 要求第一个是重复的数,第二个是丢失的整数for(inti =0;i <numsSize;i++){if(num1 ==nums[i]){newnums[0]=num1;newnums[1]=num2;returnnewnums;}}newnums[0]=num2;newnums[1]=num1;returnnewnums;}

      整数转换

      整数转换。

      输出描述:

      输入n行,如果密码合法,输出YES,不合法输出NO

      #include<stdio.h>#include<string.h>intmain(){intn;while(scanf("%d",&n)==1){for(inti =0;i <n;i++){charpassword[101]={0};intupper =0,lower =0,digit =0,other =0;scanf("%s",password);//捕捉输入的密码if(strlen(password)<8){//密码长度小于8printf("NOn");continue;}if(password[0]>='0'&&password[0]<='9'){//密码以数字开头printf("NOn");continue;}char*ptr =password;while(*ptr !='\0'){//统计各种字符个数if(*ptr >='a'&&*ptr <='z')lower++;elseif(*ptr >='A'&&*ptr <='Z')upper++;elseif(*ptr >='0'&&*ptr <='9')digit++;elseother++;ptr++;}if(other >0){// 有其他字符(注意:密码只能由数字和字母组成)printf("NOn");continue;}//大写,小写,数字,必须具有两种以上,而比较运算真则1,假则0if((upper>0)+(lower>0)+(digit>0)<2){// 密码只有一种字符printf("NOn");continue;}printf("YES\n");}}return0;}

      以上就是关于C语言常考及易错题的整理啦,各位大佬有什么问题欢迎在评论区指正,您的支持是我创作的最大动力!❤️

      在这里插入图片描述

得到 lowbit之后,可以将上述 2n 个数字分成两组,第一组的每个数字 a 都满足 a & lowbit=0,第二组的每个数字 b都满足 b & lowbit!=0

输入描述:输入一行,每行空格分割,分别是年,月,日。
3. 中间小于右边 [5, 1, 2, 3, 4], 这种情况下,最小数字则在左半边;则right = middle

说白了,最小数左右两边都非递减排列,并且左排序数组大于等于右边的值

intminNumberInRotateArray(int*nums,intnumsLen ){intright =numsLen -1;intleft =0;while(left <right){intmid =(right -left)/2+left;if(nums[mid]>nums[right])left =mid +1;elseif(nums[mid]<nums[right])right =mid;elseright--;}returnnums[left];}

错误的集合

集合 s包含从 1n的整数。局部和静态变量

  • #define与typedef
  • 转义字符
  • 操作符
  • 循环
  • 其他
  • 编程题
    • 计算日期到天数转换
    • 柯尼希定理
    • 旋转数组的最小数字
    • 描述
    • 错误的集合
    • 整数转换
    • 密码检查
  • C语言常考及易错题整理

    选择题

    全局、局部和静态变量

    1. 执行下面程序,正确的输出是:
    intx=5,y=7;voidswap(){intz;z=x;x=y;y=z;}intmain(){intx=3,y=8;swap();printf("%d,%dn",x,y);return0;}

    答案解析:

    正确答案:3,8

    swap函数调用时用的是全局变量,主函数中定义的变量只在主函数中有效,因为主函数也是一个函数,它与其他函数是平 行关系;输出语句这里,考虑局部优先的原则


    1. 如下函数的f(1)的值为:
    intf(intn){staticinti =1;if(n >=5)returnn;n =n +i;i++;returnf(n);}

    答案解析:

    正确答案: 7

    此题注意静态局部变量的使用,static改变了i的生命周期,第一次调用函数:i初值是1,递归第二次调用函数时,i还是第一 次那个变量,值已经变成了2,再一次调用函数时i就是3,依次类推


    1. 以下程序的输出结果为:
    #include<stdio.h>inti;voidprt(){for(i =5;i <8;i++)printf("%c",'*');printf("t");}intmain(){for(i =5;i <=8;i++)prt();return0;}

    答案解析:

    正确答案:***

    全局变量i,在main()中修改为5,第一次在prt()中执行循环输出三次'*'i被修改为8,执行一次print("\t"),回到主函数后i++变为9,i<=8为假,循环结束;


    #define与typedef

    1. test.c文件中包括如下语句,文件中定义的四个变量中,是指针类型的变量为:【多选】
    #define INT_PTR int*typedefint*int_ptr;INT_PTR a,b;int_ptr c,d;

    答案解析:

    正确答案:acd

    因为#define是宏定义,仅仅是直接替换,INT_PTR a, b; 进行宏替换后代码是这样的:int *a, b;这里的int *是a的类型,b的类型是int,故此次b只是int类型

    typedef是把该类型定义一个别名,别名是一个独立的类型了,使用这个类型创建的变 量都是这个类型的。

    暴力破解:遍历数组找出最小值即可

    更优思想:采用二分查找,这个题主要分析三种旋转情况 [1, 2, 3, 4, 5],使用中间值与右端进行比较。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字并且 有一个数字重复。请问,给定这样一个旋转数组,求数组中的最小值。例如当c'A'时,从case 'A'进入,先 后执行v1+=1;v0+=1;v2+=1;,而当c'p'时,从default进入,先后执行v0+=1;v2+=1;,容易看出最终v0v2是相等的


    其他

    1. 对于下面说法:正确的是()

    A. 对于struct X{short s;int i;char c;}sizeof(X)等于sizeof(s) + sizeof(i) + sizeof(c)

    B. 对于某个double变量 a,可以使用 a == 0.0来判断其是否为零

    C: 初始化方式 char a[14] = "Hello, world!";char a[14]; a = "Hello, world!";的效果相同

    D: 以上说法都不对

    答案解析:

    正确答案:D

    A选项,没有考虑内存对齐。

    B选项,考察double类型的比较,由于浮点数存在误差,不能直接判断两个数是否相等,通常采用比较两数之差的绝对值是否小于一个很小的数字(具体的可自己设定这样一个数,作为误差)来确定是否相等。

    示例1:

    输入:A = 29 (或者0b11101), B = 15(或者0b01111) 输出:2

    示例2:

    输入:A =1,B =2输出:2

    即求A与B异或的值中1的个数, 通过n&(n - 1)可以去掉一个数的二进制表示的最右边的1

    intconvertInteger(intA,intB){unsignedinttemp =A ^B;intcount =0;while(temp){temp &=(temp -1);count++;}returncount;}

    注意这里需要用unsigned int来存储两数异或的结果,因为如果用int类型,当两数异或结果为

    10000000000000000000000000000000

    int类型能表示的负数的最小值,-231

    此时再实施减一操作会超出范围,所以要转换为unsigned int类型


    密码检查

    小明同学最近开发了一个网站,在用户注册账户的时候,需要设置账户的密码,为了加强账户的安全性,小明对密码强度有一定要求:

    1. 密码只能由大写字母,小写字母,数字构成;
    2. 密码不能以数字开头;
    3. 密码中至少出现大写字母,小写字母和数字这三种字符类型中的两种;
    4. 密码长度至少为8

    现在小明受到了n个密码,他想请你写程序判断这些密码中哪些是合适的,哪些是不合法的。 其中需要注意的是平年和闰年的判断,而且是闰年的月份大于 2 的时候,也就是 2 月走完,总天数才能加 1 (比 如 2000年2月18日 ,虽然是闰年,但是 2月 都没走完那是不能加上闰年多出的一天的).

    #include<stdio.h>intis_leap_year(intyear){if(year %4==0&&year %100!=0||year %400==0){return1;}return0;}intmain(){intmonth_day[]={0,31,28,31,30,31,30,31,31,30,31,30,31};intyear,month,day;while(scanf("%d %d %d",&year,&month,&day)==3){inttotal_day =day;//先把当前月份天数加上if(is_leap_year(year)&&month >2){//若闰年,且月份大于2月,则在平年基础上+1total_day +=1;}for(inti =month -1;i >0;i--){total_day +=month_day[i];//向前累加每月的天数即可}printf("%d\n",total_day);}return0;}

    柯尼希定理

    验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。

    重复的数字在数组中出现 2 次,丢失的数字在数组中出现 0 次,其余的每个数字在数组中出现 1 次。

    保证年份为4位数且日期合法。如果在数组的 n 个数字后面再添加从 1 到 n 的每个数字,得到 2n 个数字,则在 2n 个数字中,重复的数字出现 3 次,丢失的数字出现 1 次,其余的每个数字出现 2 次。

    输出描述:输出是这一年的第几天

    这道题简单解法其实将每个月的天数枚举出来,然后根据当前月份向前累加满月的天数,然后再加上当前月所在的天数。

    输入描述:

    输入一个数n,接下来有n(n≤100)行,每行一个字符串,表示一个密码,输入保证字符串中只出现大写字母,小写字母和数字,字符串长度不超过100。

    用 x 和 y 分别表示重复的数字和丢失的数字。编写一个函数,确定需要改变几个位才能将整数A转成整数B。最终考虑平闰年的 2 月份区别是否增加一天。考虑上述 2n 个数字的异或运算结果 xor,由于异或运算 ⊕ 满足交换律和结合律,且对任何数字 a 都满足 a⊕a=0 和 0⊕a=a,因此 xor=x⊕x⊕x⊕y=x⊕y,即 x 和 y 的异或运算的结果。

    等差数列和为m^3,项数为m,公差d为2,求首项a1 :ma1 +(m(m -1)/2)*2=m^3最终得到起始奇数:a1=m *(m -1)+1
    #include<stdio.h>intmain(){intm;while(scanf("%d",&m)==1){intstart =m *(m -1)+1;//找到对应m^3的起始奇数charbuf[10240]={0};//sprintf(buf, format, ...) 与printf用法类似,格式化字符串但是不用于打印而是放到一个buf中sprintf(buf,"%d",start);//先将起始奇数转换成为字符串存入buf中for(inti =1;i <m;i++){//然后将紧随随后的m-1个奇数数字转换为字符串,按照指定格式放入buf中//%s+%d, 要求先有一个字符串,然后是+符号,然后是个数字的格式,对应是buf原先的数据,和奇数sprintf(buf,"%s+%d",buf,start+=2);}printf("%s\n",buf);}return0;}

    旋转数组的最小数字

    描述

    有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。所以while后面的条件恒为真,所以循环控制表达式与'0'是等 价的(字符'0'不是0)。由此可见,重复的数字和丢失的数字的出现次数的奇偶性相同,且和其余的每个数字的出现次数的奇偶性不同。

    请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。