• 【C刷题】day3


    一、选择题

    1、已知函数的原型是: int fun(char b[10], int *a); ,设定义: char c[10];int d; ,正确的调用语句是( )

    A: fun(c,&d); B: fun(c,d); C: fun(&c,&d); D: fun(&c,d);

    【答案】:

    A

    【解析】:

    考点:&的使用(可以看这篇文章:一招教你scanf什么时候要加&,什么时候不用加&

    如果要传地址:

    对于本身无法表示地址信息的,要加&;

    本身表示的就是地址信息的,既不需要加&

    c数组本来就表示地址,那么就不需要加&

    d只是一个变量,但是fun的第二个参数要传地址,那就把d的地址取出来即&b


    2、请问下列表达式哪些会被编译器禁止【多选】( )
    1. nt a = 248, b = 4;
    2. int const *c = 21;
    3. const int *d = &a;
    4. int *const e = &b;
    5. int const * const f = &a;

    A: *c = 32; B: *d = 43 C: e=&a D: f=0x321f
    【答案】:

    ABCD

    【解析】:

    考点:指针常量和常量指针

    const在*的左侧:表示指针指向的是常量,那么*c和*d不可修改

    const在*的右侧:表示指针是个常量指针,那么e和f不可修改

    总结来说:就是const后面跟的是啥,啥就不能直接改变


    3、以下程序的输出结果为( )
    1. #include
    2. int i;
    3. void prt()
    4. {
    5. for (i = 5; i < 8; i++)
    6. printf("%c", '*');
    7. printf("\t");
    8. }
    9. int main()
    10. {
    11. for (i = 5; i <= 8; i++)
    12. prt();
    13. return 0;
    14. }

    A: *** B: *** *** *** *** C: *** *** D: * * *
    【答案】:

    A

    【解析】:

    考点:for循环的逻辑+全局变量

    整个代码的逻辑:

    main函数中的i=5进入prt(),再次进入另一个for循环,

    i=5打印一个*,i++

    i=6打印一个*,i++

    i=7打印一个*,i++

    i=8,不满足循环条件i<8,结束循环,又回到main函数

    回到main函数时i=8,此时main函数中的for循环i=5的一次循环已经结束,i++

    所以i=9,那么又不满足for循环的条件,跳出循环


    4、下面代码段的输出是( )
    1. int main()
    2. {
    3. int a=3;
    4. printf("%d\n",(a+=a-=a*a));
    5. return 0;
    6. }

    A: -6 B: 12 C: 0 D: -12
    【答案】:

    D

    【解析】:

    考点:操作符的优先级

    赋值操作符的优先级很低,那么就先计算a*a也就得到9

    那么表达式也就是a+=a-=9,也就是a=a+(a=a-9)(此时a=3)

    那么a=a+(-6)(此时的a=-6),那么a=-6+(-6)=-12


    5、下列不能实现死循环的是( )

    A: while(1){ } B: for(;1;){ } C: do{ }while(1); D: for(;0;){ }

    【答案】:

    D

    【解析】:

    考点:C语言中0表示假,非0表示真

    前三个判断条件都为1,恒为真,那么就会死循环

    最后一个判断条件为0,恒为假,直接就不会进入循环


    二、编程题

    1.记负均正

    e25f594061a64f0c9d745b70fd6768d0.png

    【参考答案】: 

    输入n个整数时,一次输入就sum就加和

    注意:被除数为0的情况要单独考虑

    1. #include
    2. int main()
    3. {
    4. int n = 0;
    5. int count1 = 0;
    6. int count2 = 0;
    7. int a = 0;
    8. double sum = 0;
    9. scanf("%d", &n);
    10. //输入n个整数
    11. for (int i = 0; i < n; i++)
    12. {
    13. scanf("%d", &a);
    14. //统计正数
    15. if (a > 0)
    16. {
    17. sum += a;
    18. count1++;
    19. }
    20. //统计负数
    21. else if (a < 0)
    22. count2++;
    23. }
    24. //注意被除数为0的情况
    25. if (count1 != 0)
    26. printf("%d %.1lf", count2, sum / count1);
    27. else
    28. printf("%d 0.0", count2);
    29. return 0;
    30. }

    2.旋转数组的最小数字

    fac41414552240aabdf74b1162dcb810.png

    【参考答案】:  

    本题考察:二分查找

    思路:在正常的二分查找的基础上不断改进

    首先通过规律发现,由于原数组是升序的,那么旋转数组的最小值左边一定是升序,右边是降序

    然后就是循环的部分:

    (1)当中间值大于最右边说明:mid在最小值的左边

    (2)中间值小于最右边说明:mid在最小值的右边(或者就是mid)

    注意1:

    这里不能像正常的二分查找一样,left=mid+1;right=mid-1;(+1或者-1都可能跳过min)

    那么就让left=mid;right=mid,

    结果发现这样永远无法跳出循环

    不断实验就让right=mid-1

    注意2:

    如果就像上面这样写,结果还是不正确

    eg:【2,2,2,1,2】

    这个情况的中间值等于最右边的值,那么就让right--(只能一个一个减,大幅度就会跳过最小值)

    1. * @param nums int整型一维数组
    2. * @param numsLen int nums数组长度
    3. * @return int整型
    4. */
    5. int minNumberInRotateArray(int* nums, int numsLen )
    6. {
    7. int left=0;
    8. int right=numsLen-1;
    9. //找有升序有降序(最小值的左边升序,右边降序)
    10. while(left
    11. {
    12. int mid=(left+right)/2;
    13. if(nums[mid]>nums[right])//中间值大于最右边说明:mid在最小值的左边
    14. {
    15. left=mid+1;
    16. }
    17. else if(nums[mid]//中间值小于最右边说明:mid在最小值的右边(或者就是mid)
    18. {
    19. right=mid;//这里不能直接像二分查找一样right=mid-1
    20. }
    21. else //这里是为了排除重复的情况,但是又不能直接right=mid,就一个一个减
    22. {
    23. right--;
    24. }
    25. }
    26. return nums[left];
    27. }

  • 相关阅读:
    Linux下ThinkPHP5实现定时器任务 - 结合crontab
    【VIM】初步认识VIM-2
    《软件方法》应用-订单拣选和阿布思考法
    利用生产管理看板系统实现生产线的平衡和优化
    【数据结构练习】二叉树相关oj题集锦一
    MySQL 远程连接1130问题
    前端搜索框防抖函数应用
    Linux symfonos
    Nginx莫名奇妙返回了404
    C++基础第9章:序列与关联容器(2)——序列容器
  • 原文地址:https://blog.csdn.net/qq_73017178/article/details/132979595