- 💓博客主页:江池俊的博客
- ⏩收录专栏:C语言刷题专栏
- 👉专栏推荐:✅C语言初阶之路 ✅C语言进阶之路
- 💻代码仓库:江池俊的代码仓库
- 🎉欢迎大家点赞👍评论📝收藏⭐
文章目录
- 🌴选择题
- 🌴编程题
- 📌记负均正
- 📌旋转数组的最小数字
🎈前言:
- 本专栏每篇练习将包括
5个选择题 + 2个编程题
,将涵盖C语言的不同方面,包括基础语法、数据类型、控制结构、数组、指针和函数等。通过练习,你将逐步掌握C语言的基础知识和常见问题,提高你的编程技巧和解决问题的能力。- 我希望这个博客能够为你提供有价值的练习资源,让你在实践中不断进步。同时,我们也鼓励你在练习过程中进行思考和创新,尝试使用不同的编程方法和技巧。
- 让我们一起挑战C语言练习题,攻克每一个难点,不断提升自己的编程技能!
在评论区分享你的练习心得和问题,与我们一起交流和成长。
🌴选择题
- 已知函数的原型是:
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
【解析】:
参数a
是指针,要接收地址,所以BD错误。参数b
可以接收的是char*
,而&c
的类型是char(*)[10]
,C错误
- 请问下列表达式哪些会被编译器禁止【多选】( )
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
【解析】:
- A:
*c = 32;
- 这是错误的,因为c
是一个指向常量整数的指针,意味着不能通过这个指针来修改所指向的值。编译器会禁止这个操作。- B:
*d = 43;
- 这是错误的,因为d
是一个指向整数的指针,尽管它指向一个非常量整数a
,但是由于指针本身被声明为指向常量的,所以不能通过这个指针来修改所指向的值。编译器会禁止这个操作。- C:
e = &a;
- 这是错误的,因为e
被声明为一个指向整数的常量指针,一旦指针被初始化,就不能再指向其他变量。编译器会禁止这个操作。- D:
f = 0x321f;
- 这是错误的,因为f
被声明为一个指向常量整数的常量指针,一旦指针被初始化,就不能再指向其他变量。编译器会禁止这个操作。
【拓展】:
- 如果
const
位于*
的左侧,则const
就是用来修饰指针所指向的变量,即指针指向为常量;即*c
和*d
不能变。- 如果
const
位于*
的右侧,则const
就是修饰指针本身,即指针本身是常量;即e
和f
不能变。
- 以下程序的输出结果为( )
#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()
中修改为5
,第一次在prt()
中执行循环输出三次'*'
,i
被修改为8
,回到main()
中第二次调用prt()
时,i<8
为假,循环结束没输出,执行一次print("\t")
,再次回到主函数后i++
变为9
,i<=8
为假,循环结束。
- 下面代码段的输出是( )
#include<stdio.h>
int main()
{
int a = 3;
printf("%d\n", (a += a -= a * a));
return 0;
}
A: -6 B: 12 C: 0 D: -12
🔎正确答案:
D
【解析】:
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
,也就是整个表达式的值,所以应选择D
- 下列
不能实现
死循环的是( )
A: while(1){} B: for(;1;){} C: do{}while(1); D: for(;0;){}
🔎正确答案:
D
【解析】:
只有条件为真时才进行循环,ABC中1为真,D中0为假
🌴编程题
📌记负均正
【牛客网链接:HJ97 记负均正】
【题目信息】:
【答案解析】:
- 这道题其实通过
scanf
捕捉数据即可,统计负数个数,以及正数个数,并且在统计正数个数的过程中求取正数总和,最后计算得出平均数即可。需要注意的是所有数字中0是不统计在内的。
#include <stdio.h>
int main()
{
int n;
while (~scanf("%d", &n))//多组输入 (也可以写成 scanf("%d",&n)!=EOF )
{
int count1 = 0, count2 = 0, tmp;
double sum = 0;
for (int i = 0; i < n; i++)
{
scanf("%d", &tmp);//对每次输入的整数进行判断
if (tmp < 0)
{
count1++; //统计负数个数
}
else if (tmp > 0)
{
sum += tmp; //正数求和
count2++; //统计大于0的正数个数,这样是因为题目说明0不算在内
}
}
printf("%d ", count1);
if (count2==0)//如果没有正数,则平均值为0
{
printf("%.1lf\n",0.0);
}
else//若有正数,则平均值为所有正数的和除以正数的个数
{
printf("%.1lf\n",sum / count2);
}
}
return 0;
}
📌旋转数组的最小数字
【牛客网链接:JZ11 旋转数组的最小数字】
【题目信息】:
【答案解析】:
- 暴力破解:遍历数组找出最小值即可(时间复杂度:O(N) )
//暴力破解:遍历数组找出最小值即可
int minNumberInRotateArray(int* nums, int numsLen) {
int i = 0;
for (i = 0; i < numsLen - 1; i++)
{
if (nums[i] > nums[i + 1])//只要出现降序则说明出现了最小值,比如[4,5,1,2,3] :5到1是降序,则1就是最小值;
return nums[i + 1];
}
return nums[0];//如果没出现降序,说明没旋转,则第一个数就是最小值。
}
- 更优思想:采用二分查找,这个题主要分析三种旋转情况
[1, 2, 3, 4, 5]
,使用中间值与右端进行比较。
(时间复杂度:O(logN) )- 中间大于右边
[3, 4, 5, 1, 2]
,这种情况下,最小数一定在右边;则left = middle + 1
- 中间等于右边
[1, 0, 1, 1, 1]
, 这个是[0, 1, 1, 1, 1]
旋转过来的,这时候需要缩小范围right--
;,注意不能是left++
,因为是非降序数组,所以要缩小右边范围,把较小值向右推,符合我们的判断规则。 - 中间小于右边
[5, 1, 2, 3, 4]
, 这种情况下,最小数字则在左半边;则right = middle
- 中间大于右边
//更优思想:采用二分查找
int minNumberInRotateArray(int* nums, int numsLen) {
int left = 0;
int right = numsLen - 1;
while (left < right)
{
int mid = left + (right - left) / 2;//避免整数溢出
if (nums[mid] > nums[right])
{
left = mid + 1;//最小值在[left+1,right]
}
else if (nums[mid] == nums[right])
{
right--;//缩短数组,将最小值范围右移
}
else
{
right = mid;//最小值在[left,mid]
}
}
return nums[left];
}
🔥今天的内容就到这里了,有什么问题的话欢迎大家在评论区讨论,也可以私信博主为你解答,如果觉得博主的文章还不错的话, 请👍三连支持一下博主哦🤞