第一题
1. 以下选项中,对基本类型相同的指针变量不能进行运算的运算符是()
A:+
B:-
C:=
D:==
答案及解析 A
A:错误,指针不可以相加,因为指针相加可能发生越界,所以是不允许的;
B:正确,指针相减 是用来求里面的同数据类型的数据个数
C:指针允许被赋值
D:判断指针的相等,也就是看地址一不一样,地址相同了,那里面的变量也是一样的;
第二题
2. 下面程序段的输出结果为( )
int a, b;
b = (a = 3*5, a*4, a*5);
printf("%d",b);
A:60
B:75
C:65
D:无确定值
答案及解析 B
本题考查的是一个逗号表达式,逗号表达式是依次计算逗号之间的式子,但是逗号表达式的结果为里面最后一个式子的结果;
所以(a = 3*5 , a * 4 , a * 5)的结果分别为 (1,60,75)
要记住a在第一个表达式已经被赋值,所以后续a都是这个值
最后答案为75
第三题
3. 下列表达式与 ++*p 结果相同的是()
int a[]= {1,2,3,4,5};
int *p = a;
A:*++p
B:a[0]
C:a[0]++
D:*p++
答案及解析 A
本题考查的是优先级和指针的用法
虽然 前置++ 的优先级高于 * 的,但是前置++的结合性是从右到左的,必须先计算出左操作数的值,不能越过 * ,所以先算 *p = 1;之后再前置++,最后++*p = 2;
相关博客:C语言操作符优先级表格(建议收藏,每次看一下)-CSDN博客
A:*++p,前置++的优先级高于 * ,前置++返回++之后的值,所以*++p 相当于 *(p + 1) = 2;
B:a[ 0 ] = 1
C:a[ 0 ]++,后置++,返回的是++之前的值,所以a[ 0 ]++ 表达式的值为1;
D:*p++,后置++ 优先级高于 * ,但是后置++,是返回当前的值,那这个表达式的p的地址依旧是a,所以就相当于*p,*p = *a = 1;
第四题
4. int *p[4] 与选择项中的() 等价
A:int p[4]
B:int *p
C:int *(p[4])
D:int (*p)[4]
答案及解析 C
首先题目中的 int *p [4] 的 [ ]的优先级高于 *
所以p先跟[4]结合,形成数组,数组中的每个元素都是int *类型,这就是一个指针数组;
A:int p[ 4 ],整型数组;
B:int *p,整型指针;
C:int *(p[ 4 ])括号括起来了,是一个指针数组;
D:int (*p)[4]这是一个指针,指向的是一个数组,是数组指针;
第五题(细品!!!!!)
5. 假设函数原型和变量说明如下,调用非法的是()
void f3(int(*p)[4]);
int a[4]={1,2,3,4},
int b[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
A:f3(&a);
B:f3(b[1]);
C:f3(&b[1]);
D:f3(b);
答案及解析 B
其实函数传参数,就是要类型匹配;本题考查的就是那些事数组指针;
因为int (*p)[4],是一个指针数组的指针;而一个指针是如何才能指向整个数组的呢?一定是存的数组的地址,也就是说p的类型其实是&数组名,&a,p就相当于一个二级指针是int**,但是不同的是p还必须要有数组个数的匹配;
A:&a,a是数组名,&a就是表示整个数组的地址,所以和f3的参数类型匹配;
B:b[1],b是一个二维数组,那二维数组的行名,就是相当于每行的数组名,因为二维数组其实就是一维数组的数组,那每行就相当于一个一维数组,那行名不就是我们一维数组的数组名吗,所以b[1]就是数组名,数组名是首元素地址,b[1]这行的首元素是b[1][0],地址类型就是int*,跟我们的p类型不匹配
C:&b[1]才是对的,是整个数组的地址;
D:b是数组名,二维数组名,也就是二维数组的首元素的地址,二维数组的首元素就是整个的一维数组,所以b的数据类型其实就是一维数组的地址,和p类型匹配;因为你想想,一维数组的首元素是单个的数,而二维数组却是一维数组的数组,那二维数组的元素就必须是一个一个的一维数组!