第一本C语言进阶学习教材
1.字符与字符串
用单引号括起来的一个字符严格表示一个整数,而用双引号括起来的一个字符代表一个指针。
如char *slash='/'是错误的,因为'/'不是一个字符指针。同样,printf('\n')可能带来意想不到的错误。
现代编译器中,'yes'这种写法可能不会被编译器检查出错误,但是编译器会理解成"一个整数值,由'y','e','s'代表的整数值按特定编译器实现中定义的方法组合得到,与"yes"代表的含义完全不同--依次包含'y','e','s','\0'的四个连续内存单元的首地址。
2.关于指针
例如在float *g(),g是一个指针函数,()结合优先级高于*,这里等价于*(g()),g是一个函数,它返回值是一个指向浮点数的指针。在float (*h)()中,h是一个函数指针,h指向的函数返回浮点值。
一旦知道了如何申明一个给定类型的变量,那么该类型转换符就很容易得到:只需要把申明中的变量名和末尾的分号去掉,再把剩余的部分用一个括号整个封装起来。
如float (*h)()>>>>(float (*)())表示一个“指向返回值为浮点类型的函数的指针”的类型转换符。
下面分析(*void(*)())0)()。
首先这是一个(*)()的指针函数形式,进行剥离后得到(void(*)())0,这是一个强制类型转换,将0转换为“指向返回值为void的函数的指针”
3.指针与数组
- c语言只有一维数组,而数组的大小必须在编译器就作为一个参数确定下来。然而数组的元素可以是任意类型的对象,所以可以利用该特性仿真一个多维数组。
- 对于一个数组,我们只能做两件事:确定数组大小,获得指向该数组下标为0的元素的指针。其他的操作即使看起来是以数组下标进行操作,实际上都是通过指针进行的操作。
例如若我们定义int a[3]。该语句申明了a是一个拥有3个整型元素的数组。再定义int *p,若希望p指向该数组,p=&a是不正确的,因为&a是一个指向数组的指针而p是指向整数的指针。应写做p=a,即把a总下标为0的元素的地址赋给p。