c语言面试准备

  1. #define不能以分号结束,在宏中把参数用括号括起来

    • 写一个“标准”宏,这个宏输入两个参数并返回较小的:#define MIN(x, y) ((x)< (y)?(x):(y)) //结尾没有;
    • #是把宏参数转化为字符串的运算符,##是把两个宏参数连接的运算符。
    • 为避免头文件my_ head.h被重复包含,可在其中使用条件编译:
      1
      2
      3
      4
      #ifndef_ MY_ HEAD H
      #define_ MY_ HEAD_ H /*空宏*/
      /*其他语句*/
      #endif
  2. 预处理器直接计算常数表达式的值

  3. 死循环:while(1){}或for(;;){}

    • 两者相比for里面为空,编译执行之后没有判断的语句,而 while(1)始终都会有执行判断 1 = true,所以在单片机这种低速的、内存资源不多的环境,for(;;)是更好的选择。少执行判断语句,直接跳转(jump)到循环开始的代码继续执行。
  4. 用变量a给出下面的定义

    • 一个整型数: int a
    • 一个指向整型数的指针: int *a
    • 一个指向指针的指针,它指向的指针是指向一个整型数: int **a
    • 一个有10个整型数的数组: int a[10]
    • 一个有10个指针的数组,该指针是指向一个整型数的: int *a[10]
    • 一个指向有10个整型数数组的指针: int (*a)[10]
    • 一个指向函数的指针,该函数有一个整型参数并返回一个整型数: int (*a)(int)
    • 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数: int (*a[10])(int)
  5. 关键字static的作用

    • 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
    • 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
    • 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
  6. 关键字const有什么含意?

    • 它限定一个变量不允许被改变,产生静态作用。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一定帮助。
    • const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点
    • 便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
    • 可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!
    • 可以保护被修饰的东西,防止意外的修改,增强程序的健壮性,减少bug。
    • 可以节省空间,避免不必要的内存分配。
    • 意味着只读
      • const int a; 或int const a; 表示a是一个常整型数。
      • const int *a; 意味着a是一个指向常整型数的指针(整型数是不可修改的,但指针可以)。
      • int * const a; a是一个指向整型数的常指针(指针指向的整型数是可以修改的,但指针是不可修改的)。
      • int const * a const; 意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
      • int fun(const int a);int fun(const char *str);修饰函数形参,使得形参在函数内不能被修改,表示输入参数。
      • const char *getstr(void);使用: const *str= getstr);
        const int getint(void);使用: const int a =getint();修饰函数返回值,使得函数的返回值不能被修改。
  7. 关键字volatile有什么含义?

    • 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
      • 并行设备的硬件寄存器(如:状态寄存器)
      • 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
      • 多线程应用中被几个任务共享的变量
    • 搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。
    • 问题
      1. 一个参数既可以是const还可以是volatile吗?解释为什么。
        • 一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
      2. 一个指针可以是volatile 吗?解释为什么。
        • 一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
    • volatile指定的关键字可能被系统、硬件、进程/线程改变,强制编译器每次从内存中取得该变量的值,而不是从被优化后的寄存器中读取。例子:硬件时钟;多线程中被多个任务共享的变量等。
  8. extern关键宇的作用:

    • 于修饰变量或函数,表明该变量或函数都是在别的文件中定义的,提示编译器在其他文件找定义。
    • extern "C"的作用就是为了能够正确实现C+ +代码调其他C语言代码。
  9. 要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。

    1
    2
    3
    int *ptr; 
    ptr = (int *)0x67a9;
    *ptr = 0xaa55;
  10. 有关中断:

    • ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用。
    • ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。
    • 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
    • 与第三点一脉相承,printf()经常有重入和性能上的问题。
文章目录
|