系统级程序设计笔记(1)

Preliminary of C


前言

本篇博客整理了系统级程序设计课程lecture0笔记。

相关材料见:SLP-Notes

待更新…

  • static
  • extern
  • lint splint-GCC
  • Declarations

Something about C

A simple test

  • How many parameters in a function definitionis supported at most?
  • 31.
  • How many arguments in a function call issupported at most?
  • 31.
  • How many characters in a source line issupported at most?
  • 509.
  • How many levels of nested parentheses in anexpression is supported at most?
  • 32.
  • What is the maximum value for a long int?
  • 0x7fffffff.

ANSI C

1

Assignment Operator

  • b -= 3;

    => b = b - 3;

  • epsilon = .001;

    => epsilon = 0.001;

    epsilon .= 001;

    => error: Expected identifier

  • value =! open;

    => 逻辑非,value = !open

    value != open;

    => comparison statement

const

详见博客:C语言中const的详细用法及声明规则.

提纲如下:

  • 常量的声明与赋值

    int const a = 0;

  • 指向常量的指针 & 常量指针

    int const *a;

    int *const a;

  • const与全局变量

    externstatic

  • const#define

Unsigned

  • 示例代码:

    #include <stdio.h>
    
    int array[] = { 23, 34, 12, 17, 204, 99, 16 };
    #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
    void main()
    {
        int d= -1, x;
        if (d <= TOTAL_ELEMENTS-2)
            x = array[d+1];
        else x = 0;
          
        printf("%d\n",x);
    }
    

    Output: 0

    原因:

    sizeof()返回类型为size_t,为一无符号数,又有:

    C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算返回0或1。

    因此,-1的位表示为0xffffffff,是无符号数中的最大数,故条件不成立,x = 0.

  • advice

    Avoid unnecessary complexity by minimizing your use of unsigned types. Specifically, don’t use an unsigned type to represent a quantity just because it will never be negative (e.g., “age” or “national_debt”).

    Use a signed type like int and you won’t have to worry about boundary cases in the detailed rules for promotingmixed types.

    Only use unsigned types for bitfields or binary masks. Usecasts in expressions, to make all the operands signed orunsigned, so the compiler does not have to choose the result type.


C Features

Sins of Commissions

  • Switch-Statement

    • 257 case labels for a switchstatement (ANSI C Standard)

    • [改错题] How to Fix?

      int i = 2
      int two = 2;
      switch (i) {
       case 1: printf("case 1 \n");
       case two: printf("case 2 \n");
       case 3: printf("case 3 \n");
       default: ;
      }
      

      报错信息: Expression is not an integer constant expression

      修改:const int two = 2;

    • Fall Through

    • [Expanded] Java

      public static void main(String[] args){
              final int a = 1;
              final int b = 2;
      
              int i = 3;
              switch (i){
                  case a:
                      System.out.println("a");
                      break;
                  case b:
                      System.out.println("b");
                      break;
                  default:
                      System.out.println("others");
                      break;
              }
      
          }
      
      • ab同样需要为声明为常量.
      • C语言中int const a等价于const int a,而Java中只有final int a.
  • static???????????????????

    • too wide scope

      function apple (){ /* visible everywhere */ }
      extern function pear () { /* visible everywhere */ }
      static function turnip(){ /* not visible outside this file */ }
      

Sins of ommissions

  • [简答题] Multiple-meanings

    4

    6

  • Precedence of Operators

    2

    • Right assosiativity: assignment-operators

      Left assosiativity: bitwise, and’s, or’s

    • Eg:

      int a, b = 1, c = 2;
      a = b = c;
      

      Output:

      a = 2, b = 2, c = 2

  • Unsafe semantics

    如不安全的gets()函数:

    If you have code like this:

    char s[10];
    gets( s );
    

    and you type in more than 10 characters when the program is run, you will overflow the buffer, causing undefined behaviour. The gets() function has no means of preventing you typing the characters and so should be avoided. Instead you should use fgets(), which allows you to limit the number of characters read, so that the buffer does not overflow.:

    char s[10];
    fgets( s, 10, stdin );
    

    fgets()函数原型:

    if (fgets(line, sizeof(line), stdin) == NULL)
        exit(1);
    

Sins of mission

  • [简答题] Return a Local Pointer

    Solutions:

    3

    假设为字符型,则:

    • 使用字符串字面量池。
    • 使用全局的数组变量。
    • 使用静态数组。
    • 显式申请堆空间。
    • 要求调用者传入指针参数。
  • main()

    if ( argv[argc-1][0] == '-' || (argv[argc-2][1]
    == 'f' ) )
      readmail(argc, argv);
    else
      sendmail(argc, argv);
    

    Usage:

    • mail -h -d -f /usr/zhu/mymailbox
    • mail effie liu

    [Expanded] C与Java的命令行参数:

    • C

      8

    • Java

      9

  • comments

    skills:

    int main (int argc, const char * argv[])
    {
    int d= -1, x;
    unsigned u_d=(unsigned)d; printf("%u\n",u_d);
    // if (d <= TOTAL_ELEMENTS-2)
    #if 0
    if (d <= (int)TOTAL_ELEMENTS-2)
    {
    x = array[d+1];
    printf("d is less\n"); }
    else
    printf("d is more\n");
    #endif
    return 0; }
    
  • ??? lint splint-GCC

Declarations

  • 函数声明:有关指针、数组???????????

    4

  • Keywords??????????????????

    • Quaifier: volatile, const
    • Type: int, float
    • Declarator
  • struct & union

    • Struct: P32-33 lvalue???????????
    • Memory layout????????????
  • enum

    • defalut value
  • The Precedence Rule??????????????(article)

    • char* const *(*next)();
    • char *(*c[10])(int **p);
  • typedef

    • [简答题] typedef & #define

      5

  • namespace

    • struct foo { int foo; } foo;

      So, sizeof(foo)????????

    • Eg:

      typedef struct baz { int baz; } baz;
      
      /* uses struct tag */
      struct baz a;
      
      /* uses struct type tag */
      baz b;
      
      struct err_baz { int baz; } err_baz;
      
      /* the following is an error */
      err_baz c;
      
      /* the following is the right tag */
      struct err_baz d;