重读C Primer Plus,记录遗漏的、未掌握的、不清楚的知识点数组
一、ctype.h头文件里包含了一些列用于字符判断的函数,包括判断数字、大小写字母,控制字符,可打印字符等一些列函数以及转换字母大小写的字符映射函数。安全
二、C99标准要求编译器支持至少127层if-else嵌套。函数
三、包含iso646.h头文件,可使用and、or、not代替 &&、||、!,这是为了适应世界各地的键盘符号。优化
四、 缓冲区分为彻底缓冲和行缓冲,彻底缓冲在缓冲区满时清空,行缓冲在遇到换行时清空,例如文件输入(彻底)和标准输入(行),缓冲区大小取决于操做系统,512和4096字节是常见的值。spa
五、在多数Unix环境下,用[Ctrl+D]能够模拟产生一个文件尾信号,用以通知读取标准输入的程序已读取完,可能这也和交互模式下Python用这个快捷键关闭交互模式有关。操作系统
六、Unix下的重定向运算符,输入重定向<,输出重定向>,两个运算符能够组合使用。他们只能够链接可执行文件和数据文件,同类型不能链接,同时输入和输出不能重定向到一个以上的文件。命令行
七、同时Unix还具备追加数据运算符>>,管道运算符 |,具体用法就要参照Unix相关书籍了,这并非C的一部分。指针
八、注意设置递归的结束条件,以及指针的用法,没有其他须要注意的内容。rest
九、C99标准支持初始化特定项目,如:code
1 int arr[10] = {1,2,3,[5]=31}
未被初始化的项目都将被置为0。
十、 对于一个二维(多维)数组arr[n][m]而言,arr+1和arr[0]+1是不一样的。
十一、对于二维数组来讲,arr时地址的地 址,要取两次值才能够获得一般的数值。
1 这里添一句题外话,在《C Primer Plus》第五版中,P267程序清单10.15的代码和代码输出 2 结果不一致,两个二维数组的下标写反了。 3 在输出中: 4 zippo[1][2] 应写为 zippo[2][1] 5 *(*(zippo+1)+2) 应写为 *(*(zippo+2)+1)
十二、int (*arr)[2] 表示指向一个包含两个int的数组的指针;
int *arr[2] 表示包含两个int类型指针的数组,出现这个差异的缘由在于运算符的结合性。
arr[m][n] 等价于 *(*(arr+m)+n)
1三、对于N维数组,int arr[][10][20][30] 等价于 int (*ar) [10][20][30]
第一个方括号中能够不写,由于它将被认为是一个数组的指针,后面的数字则肯定了具体的数据类型,必须填写。
1四、C99标准支持变长数组,指维数能够用变量声明的数组,并非维数可变,在函数参数中省略变量名时,应用星号代替维数,int sum(int, int, int [*][*]);
1五、C99标准支持复合文字,例如(int [2])= {10, 20},由于是匿名变量,因此必须是声明时马上使用,或者用指针保存其地址。目前还没用过这个特性。
1六、用数组的方法初始化一个字符串时,数组尾部未被使用的内存所有被初始化为\0,并非只有字符串结尾处被赋值\0。
1七、char *m3 = "hello" 和 char m3[] = "hello" 在声明上做用几乎相同。不一样的是,数组名是常量,没法修改其值,但指针是能够的。
1 这里又发现一处本书的错误: 2 P285中间偏下的位置 const char *m3[] = "....省略....." 应该为 3 const char *m3 = "....省略....."
1八、对于char arr[m][n] 和 char* arr[] 来讲,前者是一个字符串数组,也是一个矩形数组,然后者是一个字符串类型的指针数组,它其实也是矩形的,但其中存储的是地址,而字符串存储在程序用来存储常量的那部分,因此没有被浪费掉的空间,可是这些串是不能被修改的。
1九、fgets函数相比gets更加安全,能够指定读入的数据长度,遇到换行符也一样读入,同时能够指定从哪个文件读入,标准输入UNIX下可指定为stdin。
20、对于命令行中的参数,操做系统默认以空格划分一个个字符串,UNIX也容许使用引号把多个单词集中在一个参数里,例:
1 repeat "I am hungry" now
2一、字符串转换为整数,经常使用atoi,还有atof,atol。复杂的有,strtol,strtoul,strtod,能够找出第一个非数字字符,而且能够转换相应进制,不经常使用。
2二、对于具备文件做用域的变量(即一般所说的全局变量),static代表其连接类型维内部连接,只有这个文件中的函数能够访问这个变量。
2三、五种存储类:
存储类 | 时期 | 做用域 | 连接属性 | 声明方式 |
自动 | 自动 | 代码块 | 空 | 代码块内 |
寄存器 | 自动 | 代码块 | 空 | 代码块内,使用关键字register |
具备外部连接的静态 | 静态 | 文件 | 外部 | 全部函数以外 |
具备内部连接的静态 | 静态 | 文件 | 内部 | 全部函数以外,使用关键字static |
空连接的静态 | 静态 | 代码块 | 空 | 代码块内,使用关键字static |
2四、对于下列代码:
1 double *ptd = (double*) malloc (30 * sizeof(double))
在C中,类型指派(double*)是可选的,但在C++中必须有,所以使用类型指派可以使程序由C移植到C++更容易。
2五、分配内存时,calloc函数接收两个参数,而且会将申请到的块内存所有置为0,但有些硬件系统浮点值并不所有用0表示。
2六、一个位于*前的const使得指向的数据成为常量,位于*后的const使得指针成为常量。
2七、restrict只能用来修饰指针,且这个指针指向的数据块由该指针初始且惟一访问,编译器会将根据这一点,对多条涉及这个指针的运算进行优化。
2八、在C99标准下,有一些旧关键字能够出如今新的位置。
1 void fun(int a1[const], int a2[restrict], int n) 2 void fun(double ar[static 20])