C语言基础练习——Day03

目录

选择题

编程题

记负均正

旋转数组的最小数字


选择题

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
💡

解析:

本题考察了函数在调用过程中,实际参数和形式参数的匹配关系,本题函数原型为int fun(char b[10], int *a);,第一个形参是数组形式的参数,第二个形参是指针类型的参数,故在调用时传递的实际参数也需要为数组和指针类型(地址),所以第一个参数传数组的数组名,即数组首元素地址,第二个参数传变量d的地址

2、(多选题)请问下列表达式哪些会被编译器禁止

int a = 248, b = 4;
int const *c = 21;
const int *d = &a; 
int *const e = &b;
int const * const f = &a;
  • A *c = 32;
  • B *d = 43
  • C e=&a
  • D f=0x321f
答案:ABCD
💡

解析:

本题考察了用const修饰的指针类型,对于指针变量c,由于const修饰的是指针变量整体,即*c,而因为c并没有得到实际有效的地址,所以解引用c会导致野指针问题,并且因为被const修饰,所以不可以使用解引用操作符改变变量c指向的空间中的值,对于指针变量d,同样也是const修饰指针变量整体,但d得到了a变量的地址,故d当前指向a变量所在的空间,但是因为被const修饰,所以同样不可以使用解引用操作符通过指针变量d改变a空间中的内容,对于指针变量econst直接修饰变量,而不是修饰指针变量整体,并且指针变量e得到了b的地址,故此时可以使用*e修改b所在空间的内容,但是不可以改变指针变量e所指向的空间,对于指针变量f来说,同时被const修饰指针变量整体和变量名,此时既不可以改变f指向的地址,也不可以通过*f改变指向的空间的值

3、以下程序的输出结果为

#include <stdio.h>
int i;
void prt()
{
    for (i = 5; i < 8; i++)
        printf("%c", '*');
    printf("\t");
}
int main()
{
    for (i = 5; i <= 8; i++)
        prt();
    return 0;
}
  • A ***
  • B *** *** *** ***
  • C *** ***
  • D * * *
答案:A
💡

解析:

本题中的变量i为全局变量,作用域为整个文件中,生命周期为持续到程序结束,故main函数中的变量i改变时,prt函数中的i依旧会改变,所以总共就执行了三次打印

4、下面代码段的输出是

int main()
{
    int a=3; 
    printf("%d\n",(a+=a-=a*a));
    return 0;
}
  • A -6
  • B 12
  • C 0
  • D -12
答案:D
💡

解析:

本题考察了运算符的优先顺序以及C语言赋值运算符的赋值顺序,对于表达式a+=a-=a*a来说,先计算a*a结果为9,但是这个计算没有副作用,所以a变量中的值还是3,再执行a-=,即a = a - 9,因为a中当前为3,故a此时为3-9=-6,接着执行a+=,因为a当前值为-6,所以a=(-6)+(-6),故a的值为-12

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

  • A while(1){}
  • B for(;1;){}
  • C do{}while(1);
  • D for(;0;){}
答案:D
💡

解析:

在C语言中,循环执行的条件时判断表达式部分为真,而只要该部分中的值不为0即为真,故只有循环D无法实现死循环

编程题

记负均正

题目链接:记负均正_牛客题霸_牛客网 (nowcoder.com)

描述
首先输入要输入的整数个数n,然后输入n个整数。输出为n个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。
0即不是正整数,也不是负数,不计入计算。如果没有正数,则平均值为0。

数据范围:1≤ n ≤2000 ,输入的整数都满足 ∣val∣≤1000
输入描述:
首先输入一个正整数n,
然后输入n个整数。
输出描述:
输出负数的个数,和所有正整数的平均值。

思路解析:

本题处理好负数和0的个数即可,在最后求平均值的过程中需要考虑到除数为0的情况

参考代码:

#include <stdio.h>

int main() {
    int num = 0;
    int sum = 0;
    int input = 0;
    int count = 0;//记录负数的个数
    int zero = 0;//记录0的个数
    scanf("%d", &num);
    for(int i = 0; i < num; i++)
    {
        scanf("%d", &input);
        if(input > 0)
        {
            sum += input;
        }
        else if(input < 0){
            count++;
        }
        else {
            zero++;
        }
    }
    //如果输入的数值中不全是负数和0时计算平均数,否则不计算平均数
    if(num != count && num != zero)
    {
        printf("%d %.1f", count, (float)sum/(num - count - zero));
    }
    else {
        printf("%d %.1f", count, 0.0);
    }
    return 0;
}

旋转数组的最小数字

题目链接:旋转数组的最小数字_牛客题霸_牛客网 (nowcoder.com)

描述
有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:1≤ n≤10000,数组中任意元素的值: 0≤ val≤10000
要求:空间复杂度: O(1) ,时间复杂度: O( logn)

思路分析:

因为原数组是一个非降序(即非严格递增)的数组,所以旋转后的数组将被分为两个有序的数组,对于二分查找来说,只需要查找的数组是有序即可,对于本题,因为存在两个有序的部分,故需要分别进行判断,确定好边界后缩小范围再进行二分查找,故本题有三种情况

范围内的中间数值比右侧范围中的数值大。此时说明,数组中的最小数值在中间值的右侧,此时运用二分查找算法的思想,在右侧的部分中找最小值

范围内的中间数值比右侧范围中的数值小。此时说明,数组中的最小数值在中间值的左侧,此时运用二分查找算法的思想,在左侧的部分中找最小值

范围内的中间数值和右侧范围中的数值相等。此时无法判断数组中的最小数值在哪一侧,此时逐渐缩小区间,重复判断直到出现上面两种情况中的一种再执行上面的两种情况的处理方法

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param numsLen int nums数组长度
 * @return int整型
 */
int minNumberInRotateArray(int* nums, int numsLen ) 
{
    int left = 0;
    int right = numsLen - 1;

    while(left <= right)
    {
        //指向中间位置的变量
        int mid = (left + right) / 2;
        if(nums[mid] > nums[right])
        {
            //当中间值大于右侧的值
            //注意此处是left = mid + 1,left用于和right确定边界,当需要缩小范围时,mid位置的数值可以不再包括在内,因为当前数值已经比nums[right]大
            left = mid + 1;
        }
        else if(nums[mid] < nums[right])
        {
            //当中间值小于右侧的值
            //注意此处不是right = mid - 1,因为要与nums[right]进行比较从而确定边界,可能mid位置就是一侧边界
            right = mid;
        }
        else 
        {
            //当中间值等于右侧的值
            right--;
        }
    }
    return nums[left];
}
  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怡晗★

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值