第八~十三章

第八~十三章

第八章

  • 考虑下面的数组声明:

    int a[] = {4, 9, 1, 8, [0]=5, 7};
    

    编译器在处理初始化式列表时,会记录下一个待初始化的数组元素位置。正常情况下,下一个元素是刚被初始化元素后面的那个。但是当列表中出现初始化式时,下一个元素会被强制为指示符对应的元素,即使该元素已经被初始化过了。

    所以最终效果与下面的声明一样:

    int a[] = {5, 7, 1, 8};
    

第九章

  • 函数定义
    • 如果省略返回类型,C89假定为int类型,在C99中是非法的。
  • 函数声明
    • 函数声明可以放在另一个函数体内
  • C99中在调用一个函数之前,必须先对其进行声明或定义
  • 变长数组的形参
    • 一维

      int sum_array(int a[], int n);
      int sum_array(int n, int a[n]);
      int sum_array(int n, int a[*]);
      int sum_array(int, int [*]);
      int sum_array(int, int []);
      int sum_array(int n, int a[]);
      
    • 二维

      int sum_two_dimensional_array(int n, int m, int a[n][m]);
      int sum_two_dimensional_array(int n, int m, int a[*][*]);
      int sum_two_dimensional_array(int n, int m, int a[][m]);
      int sum_two_dimensional_array(int n, int m, int a[][*]);
      
  • 数组参数声明中使用static
    • 下例中,将static放在数字3之前表明数组长度至少可以保证是3

      int sum_array(int a[static 3], int n)

    • 如果数组是多维的,static仅可用于第一维

  • 复合字面量
    • 复合字面量是通过指定其包含的元素而创建的没有名字的数组
    • 格式:先在一堆圆括号内给定类型名,随后在一对花括号内设定所包含元素的值

第十二章

表达式 含义
*p++*(p++) 自增前表达式值是*p,以后再自增p
(*p)++ 自增前表达式值是*p,以后再自增p
*++p*(++p) 先自增p,自增后表达式的值是*p
++*p++(*p) 先自增*p,自增后表达式的值是*p

第十三章

  • strlen的精简史

    size_t strlen(const char *s) {
        size_t n;
        for (n = 0; *s != '\0'; s++) {
            n++;
        }
        return n;
    }
    

    n的初始化移到声明,*s != '\0'*s != 0是一样的,测试*s != 0*s是一样的

    size_t strlen(const char *s) {
        size_t n = 0;
        for (; *s; s++) {
            n++;
        }
        return n;
    }
    

    同一个表达式中对s进行自增,并测试*s是可行的

    size_t strlen(const char *s) {
        size_t n = 0;
        for (; *s++;) {
            n++;
        }
        return n;
    }
    

    while语句替换for语句

    size_t strlen(const char *s) {
        size_t n = 0;
        while (*s++) {
            n++;
        }
        return n;
    }
    

    看起来精简很多,但事实上速度根本没提升,至少对于一些编译器下面的版本确实会快一点

    size_t strlen(const char *s) {
        const char *p = s;
        while (*s++) 
            ;
        return s - p;
    }
    

    速度的提升得益于不需要在while循环中对n进行自增

  • 搜索字符串结尾

    while (*s++) 
        ;
    
    while (*s) 
        *s++;
    

    注意两个版本结束时s指向的位置

  • 字符串复制

    while (*s++ = *p++) 
        ;
    

    循环在赋值空字符后停止,不需要单独添加空字符

  • C89规定,编译器必须最少支持509个字符长的字符串字面量(没错,就是509,不要怀疑);C99是4095个字符

你可能感兴趣的:(第八~十三章)