目录
选择题
考点一:函数的调用的理解和应用
已知函数的原型是: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
本题的主要考点:函数的调用
题目已给出函数的声明,此声明已给出此函数的所需的两个条件:
1.函数的返回类型为int
2.函数有两个参数:字符数组的地址和整形地址
char c[10]的数组名 c 就代表着字符数组的首元素地址,即
字符指针
,所以可以直接传数组名给函数
int d
便可以&d
从而获得这个整型的地址,那函数便也可以拿整型指针接收
考点二:const对指针的理解和应用
请问下列表达式哪些会被编译器禁止【多选】( )
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掌握的是否清楚
1.const如果在指针变量的“ * ”的左边(即 const int * a 和 int const * a的意义是相同的,作用是等价的)
表达的意思是:对指针变量a 解引用的值是保持不变的
只有a里面存放的地址改变了,解引用出来的值才会变化
2.const如果在指针变量的“ * ”的右边【即 int * const a】
表达的意思是: a里面存放的地址是保持不变
只有主动对 *a 赋值才能改变这个值,但a里面的地址是一直保持不变的
接下来我们分析题:
对于A和B:const在“ * ”的左面,则 const 就是用来修饰指针所指向的变量,即指针指向为常量,则此时的*c和*d不变
对于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
注意:这里出现转义字符 \t ,而 \t 代表为水平制表符,简单来说就是在键盘上按了TAB
的效果,也可以理解为缩进符
全局变量
创建在静态区中,作用域为整个程序且生命周期与主函数相同,只有程序结束,它才会销毁
全局变量 i ,在 main() 中修改为 5 ,第一次在 prt() 中执行循环输出三次 '*' , i 被修改为 8 ,回到 main() 中第二次调用 prt() 时,i<8 为假,循环结束没输出,执行一次 print("\t") ,再次回到主函数后 i++ 变为 9 , i<=8 为假,循环结束 ;
考点四:运算符优先级
下面代码段的输出是( )
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)
=-6
a+=a
=a = a + a
=-6 + (-6)
=-12
拓展:操作符优先级
考点五:循环条件的判断
下列不能实现死循环的是( )
while(1){} for(;1;){} do{}while(1); for(;0;){}
正确答案:D
只有条件为真时才进行循环, ABC 中 1 为真, D 中 0 为假
编程题
【牛客网题号:HJ97 记负均正】【难度:简单】
1、首先输入要输入的整数个数 n
,然后输入n
个整数。输出为 n
个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。
输入描述:首先输入一个正整数 n
,然后输入 n
个整数
输出描述:输出负数的个数,和所有正整数的平均值
题目传送门:OJ链接
#include <stdio.h>
int main()
{
int n = 0;
while (scanf("%d", &n) != EOF)
{
float ave = 0;
int i = 0;
int arr[1000] = { 0 };
int count1 = 0;
int sum = 0;
int count2 = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
if (arr[i] < 0)
{
count1++;
}
else if (arr[i] > 0)
{
sum += arr[i];
count2++;
}
}
printf("%d ", count1);
if(count2)
{
ave = (float)sum / count2;
printf("%.1lf\n", ave);
}
else
printf("0.0");
}
return 0;
}
【牛客网题号:JZ11 旋转数组的最小数字】【难度:简单】
2、有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值
数据范围:1≤ n ≤ 10000
数组中任意元素的值: 0 ≤ val ≤ 10000
题目传送门:OJ链接
思路:采用二分查找的思想
这个题主要分析三种旋转情况 [1, 2, 3, 4, 5],使用中间值与右端进行比较之所以选择右端点来比较,是因为原始数组是非递减(即一开始数据大的总是在右端),若中间>右边,则恒有左端点至中间>=右端点
[3, 4, 5, 1, 2] 中间大于右端:恒有左端点至中间>=右端点,则确定答案为 [mid+1...last]区间
[5 1 2 3 4] 中间小于右端:说明答案肯定不在[mid+1…last],但是arr[mid] 有可能是答案,所以答案在[first, mid]区间
[1 0 1 1 1] 中间等于右端:这时候需要缩小范围 right–;注意不能是left++,因为是非降序数组,所以要缩小右边范围,把较小值向右推,符合我们的判断规则
int minNumberInRotateArray(int* rotateArray, int rotateArrayLen ) {
if(rotateArrayLen == 0)
{
return 0;
}
int left = 0 ;
int right = rotateArrayLen-1;
while(left < right)
{
if(rotateArray[left] < rotateArray[right])//left即为最小值
{
return rotateArray[left];
}
int mid = (left + right) / 2;
if(rotateArray[mid] > rotateArray[right])//最小值在右侧
{
left = mid+1;
}
else if(rotateArray[mid] < rotateArray[right])//最小值在左侧
{
right = mid;
}
else//相等,需要调整
{
right--;
}
}
return rotateArray[left];
}