Problems and keys
Fall
-
假设某段C语言程序中定义了三个变量
a、b和c并且三个变量都不为0,则表达式a / b * c和a * c / b是等价的,其值相同。(F)根据C语言的算术运算规则,表达式
a / b * c和a * c / b并不总是等价的,其值可能不同。主要原因在于整数除法的截断行为(如果变量是整数类型)和浮点数的精度问题。 -
What is the output of the following program?
int main()
{
int a = 2, b = -1, c = 2;
if(a < b)
if(b < 0)
c = 0;
else c++;
printf("%d\n",c);
return 0;
}
最终输出c的值是2没有改变。 本题考查C语言中else与if的配对规则:在C语言中,else总是与同一作用域内最近的、尚未匹配的if语句匹配。这个规则被称为"最近匹配原则"或"dangling else问题"的解决方案。
-
Among the following statements which intend to define arrays, which one is wrong?
A.
int x[2][]={1,2,4,6}; B.int m[][3]={1,2,3,4,5,6}; C.int a[1][3]; D.int x[2][2]={1,2,3,4};key: A 在C语言中,定义多维数组时,只有第一维的大小可以省略(当有初始化列表时),但其他维度的大小必须明确指定。选项A中,
int x[2][]={1,2,4,6};的第二维为空,这是错误的,因为编译器无法确定第二维的大小,从而无法计算内存布局。 -
下列程序的输出结果是( ). A. (6,6) B. (3,6) C. (6,12) D. (3,3)
# include <stdio.h>
int f(int n){
static int k, s;
n--;
for(k=n; k>0; k--)
s += k;
return s;
}
int main(void){
int k;
k=f(3);
printf("(%d,%d)", k, f(k));
return 0;
}
key: B
静态变量基本特点:
1. 生命周期:程序运行期间一直存在
2. 只初始化一次,默认初始化为0
3. 存储位置:静态存储区(数据段)
注意事项:
可能使函数不可重入
增加内存占用
测试时需要特殊处理
-
关于C语言指针的运算:指针只有加减操作,没有乘除操作。指针可以加常数、减常数;相同类型的指针可以相加、相减。(F)
在C语言中,指针确实没有乘法和除法操作,但指针的加减操作是有限制的。指针可以加或减一个整数常数(表示移动指针到相邻内存位置),但相同类型的指针不能相加——指针相加是非法的,因为它在语义上没有意义(例如,两个地址相加无法得到有效地址)。相同类型的指针可以相减,得到的是两个指针之间的元素个数。
-
The remainder operator (%) can be used only with integer operands. (T)
-
The following code fragment prints out .
int a=2,b=9;
do{
b-=a;
a++;
}while(b--<0);
printf("a=%d,b=%d\n",a,b);
A.a=1,b=-1
B.a=2,b=8
C.a=3,b=6
D.a=3,b=7
key:C
1. 注意循环执行次数;
2. 注意循环条件的表达式的副作用.
Winter
-
C语言中,编译预处理后,所有的符号常量名和宏名都用相应的字符串替换.(T) 符号常量指的是宏常量,
const定义的叫做常变量/只读变量. -
随机操作只适用于二进制文件.(F) 文本文件也能使用
fseek或rewind(例如回到文件开头). 虽然二进制文件定位更精准(无换行符转换问题),但语法上随机操作并不排斥文本文件. -
The value of expression
!("01/24/2019"+5)[5]is ? Key: 1. 字符串字面量退化为指向第一个字符'0'的地址的指针,先算小括号内的表达式,值为指向第二个/的指针, 再算[5],值为指向字符串最后的'\0',即 0,最后运算逻辑非,值为 1. -
For definitions:
char s[2][3]=("ab" "cd"),*p=(char *)s;the expression____is correct and its value is equivalent to the elements[1][1]. A.*(s+3)B.*s+2C.p[1][1]D.*++p+2Key: D. 字符串在对字符数组初始化时不会退化为指针. s数组的初始化情况为 |
'a'|'b'|'\0'| |'c'|'d'|'\0'| (实际上在内存中顺序排列)s[1][1]的值即为'd'. 表达式*p=(char *)s中,s首先退化为指向第一个3元数组首地址的指针,即&s[0],再被显式类型转换为字符指针,即&s[0][0](地址是相同的,只是指针的步长和指向地址存储的数据类型改变了),赋值给 p.A 表示对不存在的 s 二维数组第四行解引用的结果,是 UB;
B
*s等价于s[0],即得到二维数组 s 的第一行的数组,表达式中进一步退化为指向数组首地址的指针,即&s[0][0],则原表达式等价于&s[0][0]+2,得到指向'\0'地址的指针.C p 只是一个一级字符指针,不能进行两次
[]运算,会编译错误.D 先算
++p得到&s[0][1],再解引用,得到'b',最后+2得到'd'正确. -
The following code fragment will output
_____.
char *week[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}, **pw = week;
char c1, c2;
c1 = (*++pw)[1];
c2 = *++pw[1];
printf("%c#%c#",c1,c2);
Key: u#e#
注意表达式的副作用,对c1赋值的表达式中移动了pw指针.
- 鹤翔万里50题