📜  C语言 |设置 3

📅  最后修改于: 2021-09-28 09:59:39             🧑  作者: Mango

以下问题已在 GATE CS 考试中提出。

1.假设如下C变量声明

int *A [10], B[10][10];  

以下表达式中
IA[2]
II A[2][3]
三乙[1]
IV B[2][3]
如果在 C 程序 (GATE CS 2003) 中用作赋值语句的左侧,它不会产生编译时错误?

a) 仅 I、II 和 IV
b) 仅限 II、III 和 IV
c) 仅限 II 和 IV
d) 仅 IV

答案(一)
见下面的程序

int main()
{ 
  int *A[10], B[10][10];    
  int C[] = {12, 11, 13, 14};
  
  /* No problem with below statement as A[2] is a pointer 
     and we are assigning a value to pointer */
  A[2] = C; 
  
  /* No problem with below statement also as array style indexing 
      can be done with pointers*/
  A[2][3] = 15;
  
  /* Simple assignment to an element of a 2D array*/
  B[2][3]  = 15;
  
  printf("%d %d", A[2][0], A[2][3]);
  getchar();
}  

2. 考虑以下 C 语言中“二维数组”的声明:

char a[100][100]; 

假设主内存是字节寻址的,并且数组从内存地址 0 开始存储,a[40][50] 的地址是 (GATE CS 2002)
一)4040
b) 4050
c) 5040
d) 5050

答案(二)

Address of a[40][50] = 
     Base address + 40*100*element_size + 50*element_size
     0 + 4000*1 + 50*1
     4050

3.C语言是。 (GATE CS 2002)
a) 上下文无关语言
b) 上下文敏感的语言
c) 常规语言
d) 只能由图灵机完全解析

答案(二)
C 和 C++ 是上下文相关的语言。

有几个原因:

  1. 要解析 C 和 C++,首先要使用非常强大的预处理器。这些预处理器不可避免地是手工编写的(它们不是基于正则表达式或上下文无关语法等理论基础)。
  2. 语法不明确:它有 LR 冲突,例如 if-then-else 冲突。解析器通常使用上下文来解决这个问题(“else”匹配最接近的“if”)。
  3. C 和 C++ 词法分析器需要词法反馈来区分 typedef 名称和标识符。也就是说,上下文敏感词法分析器需要“上下文无关”解析器的帮助来区分标识符“foo”和类型定义名称“foo”。在这个片段中,
    int foo;
    typedef int foo;
    foo x;

    第一个“foo”是一个标识符,而第二个和第三个是 typedef 名称。您需要解析 typedef 声明来解决这个问题(并且由于类型具有嵌套括号,这绝对至少与解析上下文无关语言一样困难)。
    这意味着解析器和词法分析器是相互递归的,所以说解析器是上下文无关的而词法分析器是上下文敏感的是没有意义的。

参考:C 和 C++ 不是上下文无关的


4 最适合以下配对的匹配 (GATE CS 2000)

X: m=malloc(5); m= NULL;        1: using dangling pointers
Y: free(n); n->value=5;         2: using uninitialized pointers
Z: char *p; *p = ’a’;           3. lost memory is:

(a) X—1 Y—3 Z-2
(b) X—2 Y—1 Z-3
(C) X—3 Y—2 Z-1
(d) X—3 Y—1 Z-2

答案 (d)
X -> 一个指针被分配给 NULL 而不释放内存,所以这是内存泄漏的一个明显例子
Y -> 在释放悬空指针后尝试检索值。
Z -> 使用未初始化的指针

5. 考虑以下 C 程序:

void foo(int n, int sum)
{
  int k = 0, j = 0;
  if (n == 0) return;
    k = n % 10; 
  j = n / 10;
  sum = sum + k;
  foo (j, sum);
  printf ("%d,", k);
}
  
int main ()
{
  int a = 2048, sum = 0;
  foo (a, sum);
  printf ("%d\n", sum);
    
  getchar();
}

上面的程序打印什么? (GATE CS 2005)
(a) 8, 4, 0, 2, 14
(b) 8, 4, 0, 2, 0
(C) 2, 0, 4, 8, 14
(d) 2, 0, 4, 8, 0

答案 (d)
sum 在 foo() 中没有用,它只是为了混淆。函数foo() 只是打印一个数字的所有数字。在 main 中,在 foo() 之后还有一个 printf 语句,所以在 n 的所有数字之后又打印了一个 0。