Skip to content

Problems and keys

Fall
  1. 假设某段C语言程序中定义了三个变量abc并且三个变量都不为0,则表达式a / b * ca * c / b是等价的,其值相同。(F)

    根据C语言的算术运算规则,表达式 a / b * c 和 a * c / b 并不总是等价的,其值可能不同。主要原因在于整数除法的截断行为(如果变量是整数类型)和浮点数的精度问题。

  2. 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问题"的解决方案。

  1. 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}; 的第二维为空,这是错误的,因为编译器无法确定第二维的大小,从而无法计算内存布局。

  2. 下列程序的输出结果是( ). 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. 存储位置:静态存储区(数据段)
注意事项:
可能使函数不可重入
增加内存占用
测试时需要特殊处理
  1. 关于C语言指针的运算:指针只有加减操作,没有乘除操作。指针可以加常数、减常数;相同类型的指针可以相加、相减。(F)

    在C语言中,指针确实没有乘法和除法操作,但指针的加减操作是有限制的。指针可以加或减一个整数常数(表示移动指针到相邻内存位置),但相同类型的指针不能相加——指针相加是非法的,因为它在语义上没有意义(例如,两个地址相加无法得到有效地址)。相同类型的指针可以相减,得到的是两个指针之间的元素个数。

  2. The remainder operator (%) can be used only with integer operands. (T)

  3. 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
  1. C语言中,编译预处理后,所有的符号常量名和宏名都用相应的字符串替换.(T) 符号常量指的是宏常量,const 定义的叫做常变量/只读变量.

  2. 随机操作只适用于二进制文件.(F) 文本文件也能使用 fseek 或 rewind(例如回到文件开头). 虽然二进制文件定位更精准(无换行符转换问题),但语法上随机操作并不排斥文本文件.

  3. The value of expression !("01/24/2019"+5)[5] is ? Key: 1. 字符串字面量退化为指向第一个字符 '0' 的地址的指针,先算小括号内的表达式,值为指向第二个 / 的指针, 再算 [5] ,值为指向字符串最后的 '\0' ,即 0,最后运算逻辑非,值为 1.

  4. For definitions: char s[2][3]=("ab" "cd"),*p=(char *)s; the expression ____ is correct and its value is equivalent to the element s[1][1]. A. *(s+3) B. *s+2 C. p[1][1] D. *++p+2

    Key: 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' 正确.

  5. 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题