第一题
1.设a为整型变量,不能正确表达数学关系:10
A:10
B:a==11|| a==12 || a==13 || a==14
C:a>10 && a<15
D:!(a<=10) && !(a>=15)
答案及解析 A
A:C语言中这种的表达式,10 < a < 15 的结合性是从左往右,所以会先算出10 < a 为真假性,但是无论是真1还是假0都是都是小于15的,所以这个表达式最后的恒为真,无法比较我们想要的结果;
B:因为在数学表达式10 < a < 15 ,其中的整数是11,12,13,14.只要满足一个就是,所以是逻辑或;
C:这才是用C语言正确表示10 < a < 15;
D:因为!是逻辑取反,所以!(a <= 10 )相当于a > 10 ,!(a >= 15) 相当于 a < 15 ;
最后表达式就相当于10 < a < 15;
第二题
2. 假设i=2,执行下列语句后i的值为()
switch( i ) { case 1 : i ++; case 2 : i --; case 3 : ++ i; break; case 4 : -- i; default : i ++; }
A:1
B:2
C:3
D:4
答案及解析 B
一旦符合case的条件就会进入,但是case后面只要没有break,就会进入下一个case,所以我们i = 2;进入case 2:这个语句,执行i--,但是case 2没有break,继续进入case 3:
之后++i,这个时候有break,就跳出switch语句,i值为2;
第三题
3. 对于以下变量定义,正确的赋值是()
int *p[3], a[3];
A:p=a
B:*p=a [0]
C:p=&a [0]
D:p[0]=&a[0]
答案及解析 D
本题考查的是类型匹配的问题,我们先看int *p[3],[]的优先级比*高,所以先形成数组,之后数组的元素类型是int*,这是一个指针数组,存放的是一级指针,这很重要;
后面就是正常定义int a[3]的整型数组;
A C:p是指针数组的数组名,数组地址不可修改,是指针常量,不可以做赋值操作符的左值,因为赋值操作符左边必须为变量;
B:*p,是堆二级指针解引用,是一级指针,等价于p[0];a[0]是整型,类型不匹配;
D:p[0]是一级指针,&a[0]是一级指针,类型匹配,可以赋值
第四题
4. 已知int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, *p = a;,不能表示数组a中元素的式子是()
A:*a
B:*p
C:a
D:a[ p-a ]
答案及解析 C
A:a是数组名,代表首元素地址 ,*a代表首元素,a[0]
B:*p = a ,也就是我们定义了一个指针变量指向的是首元素的地址,解引用就是首元素a[0]
C:a是首元素地址,不是数组元素
D:a[p-a],由于p和a都代表的是首元素地址,地址相减为0,a[p-a] 等价于 a[0]
第五题(难点)
5. 下列关于const和#define定义常量的区别,说法不正确的有()
A:define宏是在预处理阶段展开。const常量是编译运行阶段使用
B:宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查
C:define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。const常量会在内存中分配(可以是堆中也可以是栈中)
D:const定义和#define定义的常量在程序运行过程中只有一份拷贝
答案及解析 D
A:正确,在预处理阶段会进行处理预处理指令的处理,#define定义的宏是在预处理阶段进行替换的,注意是仅替换,并不会检查合法性。const常量是在编译、运行阶段进行使用的。
B:正确:所有的宏替换只是替换,就替换完就OK,所以并不会检查其合法性,而const定义的常量是内置类型(int,double,float等)所以会对其进行类型检查。
C:正确:宏定义在程序中使用了几次在预处理阶段就会被展开几次,并不会增加内存占用,但是宏定义每展开一次,代码的长度就要发生变化,而const常量也会为其分配内存,如果const修饰的是由malloc,realloc等开辟的空间,就是在堆上分配的。
D:错误:const定义的常量只有一次拷贝,而define定义的变量在内存中并没有拷贝,因为所有的预处理指令都在预处理时进行了替换,并不分配内存。