C符号的重载
C语言中有误导性质或是不适当的特性与C语言的简洁有关(部分与符号的过度复用有关),有些则与操作符的优先级有关。
C语言里,许多符号是被“重载”的——在不同的上下文环境里有不同的意义。甚至有些关键字也被重载而具有好几种意义,这也是C语言的范围规则对程序员不那么清晰的主要原因。
表展示C语言中类似的符号是如何具有多种不同意义的。
符号 | 意义 |
---|---|
static | 1.在函数内部,表示该变量的值在各个调用间一直保持延续性。 |
2.在函数这一级,表示该函数只对本文件可见 | |
extern | 1.用于函数定义,表示全局可见(属于冗余的) |
2.用于变量,表示它在其他地方定义 | |
void | 1.作为函数的返回类型,表示不返回任何值 |
2.在指针声明中,表示通用指针的类型 | |
3.位于参数列表中,表示没有参数 | |
* | 1.乘法运算符 |
2.用于指针,间接引用 | |
3.在声明中,表示指针 | |
& | 1.位的AND操作符 |
2.取地址操作符 | |
= | 1.赋值符 |
== | 1.比较运算符 |
<= | 1.小于等于运算符 |
<<= | 1.左移复合赋值运算符 |
< | 1.小于运算符 |
2.#include指令的左定界符 | |
() | 1.在函数中,包围形式参数表 |
2.调用一个函数 | |
3.改变表达式的运算次序 | |
4.强制类型转换 | |
5.定义带参数的宏 | |
6.包围sizeof操作符的操作数(如果它是类型名) |
除此之外,还有一些符号具有多个容易混淆的意思。重载存在的问题之处如下面语句所示:
1 | p = N * sizeof * q; |
这里是一个乘号还是两个乘号?
答案是这里只有一个乘号,因为sizeof操作符把指针q指向的东西(*q)作为操作数,它返回q所指向对象的类型的字节数,便于malloc函数分配内存。当sizeof的操作数是个类型名时,两边必须加上括号(这常常使人误以为它是个函数),但操作数如果是个变量则不必加括号。
一个更复杂的例子:
1 | a = sizeof(int) * p; |
是int的长度乘以p?或者是把未知类型的指针p强制转换为int,然后进行sizeof操作?
实际检验一下:
代码段1:
1 | int main(void){ |
编译出错:
1 | p = sizeof(int) * q; |
明显这样并不是把未知类型的指针p强制转换为int,然后进行sizeof操作,而是编译器把星号(*)当作乘号来处理了,但由于左右操作数类型不匹配而报错。
代码段2:
1 | int main(void){ |
这样写便为把未知类型的指针p强制转换为int,然后进行sizeof操作。
运行输出:
4
代码段3:
1 | int main(void){ |
对指针p的地址进行强制转换,指针p强制转换为int,然后乘上sizeof(int)。
代码段4:
另外一种对该句代码的合理解释
1 | int main(void){ |
q为int型变量,p = int的长度乘以q,结果输出:
8
让一个符号所表达的意思越多,编译器就越难检测到这个符号在你的使用中所存在的异常情况。
本文标题:C符号的重载
文章作者:Mr Bluyee
发布时间:2018-07-23
最后更新:2019-07-15
原始链接:https://www.mrbluyee.com/2018/07/23/C%E7%AC%A6%E5%8F%B7%E7%9A%84%E9%87%8D%E8%BD%BD/
版权声明:The author owns the copyright, please indicate the source reproduced.