第八~十三章
第八章
-
考虑下面的数组声明:
int a[] = {4, 9, 1, 8, [0]=5, 7};
编译器在处理初始化式列表时,会记录下一个待初始化的数组元素位置。正常情况下,下一个元素是刚被初始化元素后面的那个。但是当列表中出现初始化式时,下一个元素会被强制为指示符对应的元素,即使该元素已经被初始化过了。
所以最终效果与下面的声明一样:
int a[] = {5, 7, 1, 8};
第九章
- 函数定义
- 如果省略返回类型,C89假定为
int
类型,在C99中是非法的。
- 如果省略返回类型,C89假定为
- 函数声明
- 函数声明可以放在另一个函数体内
- 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之前表明数组长度至少可以保证是3int 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个字符
网友评论