第三章 :语义“陷阱”
3.1 指针与数组
(1)C语言中的数组值得注意的地方有以下两点:
a. C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。然而,C语吉中数组的元素可以是任何类型的对象,当然也可以是另外一个数组。这样,要“仿真”出一个多维数组就不是难事。
b. 对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其他有关数组的操作,哪怕它们乍看上去是以数组下标进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算,因此我们完全可以依据指针行为定义数组下标的行为。
考虑下面例子的描述方法:
int calendar [12][31] ;
这个语句声明了calendar是一个数组,该数组拥有12个数组类型的元素,其中每个元素都是一个拥有31个整型元素的数组。
Calendar是一个指向数组的指针。
(2)如果两个指针指向的是同一个数组中的元素,可以把这两个指针相减。
(3)a 和 & a
&a是一个指向数组的指针,而a是一个指向整型变量的指针,它们的类型不匹配。
(4)除了a被用作运算符sizeof 的参数这一情形(整个数组a的大小),在其他所有的情形中数组名a都代表指向数组a中下标为0的元素的指针。
(5)
(6)清空calendar[12][31]数组
a. 数组遍历
b. 指针遍历
3.2 非数组的指针
我们如何借助strcpy和strcat将两个字符串(s和t)放到一个字符串(r)里面呢?
(1)不能确定r指向何处;r所指向的地址处有足够的内存空间。
(2)不够确保r足够大。
(3)使用malloc和strlen解决问题
注意以下三点:
- malloc函数有可能无法提供请求的内存(返回空指针);
- 给r分配的内存在使用完之后应该及时释放(本例存储局部变量,及时释放);
- 作为结束标志的空字符并未计算在内。
3.3 作为参数的数组声明
(1)C语言中会自动地将作为参数的数组声明转换为相应的指针声明。
完全相同的写法: