C有多少种数据类型,这个你还真别先回答,我没有问你基本数据类型。 这个问题的答案是无数种,因为任何变量(非函数)声明去掉变量名就是类型。 比如 「void (*foo)(void)」 去掉 「foo」后, 「void (*)(void)」就是一个类型。 那么下面这段代码干了什么。
((void (*)(void)) 0)();
头没有看晕吧!这段代码没有错,你可以拿去编译,但是多半是执行不了的,除非 你搞了个特殊的嵌入式程序。如果这句话---任何变量(非函数)声明去掉变量名就是类型, 对你还没有起很大帮助,那么我好事做到底,帮你分析分析:- 后面一对括号告诉我们这是函数调用,那么前面内容一定是个函数指针了。
- 前面内容去掉括号变成(void (*)(void)) 0属于「(...) number」形式, 这就是「内型强转」。
- void (*)(void)是什么类型,我也叫不出名字了,不过什么意思我前面已经说过了。
有了上面的基础了解,下面我们来了解了解「数组」和「指针」这两个比较有意思的东西。
// 32-bit OS // 例 1 int A[10]; // 假设 A = 10000 // 那么下面这些表达式的值? A + 1; &A; &A + 1; // 例 2 int B[10][10] // 假设 B = 10000 // 求下面表达式的值 B + 1; &B; *B; &B + 1;
我们还需要明确一点,C编译器会把对数组的操作转化成对指针的操作, 因为数组变量保存的是地址,指针保存的也是地址。所以在一定程度上, 数组名可以当作指针来看,而且C程序运行时也确实是这么干的,但是在编译 阶段还是有一定差别,数组名还充当一个数组的属性标示,比如这个数组 占用了多大空间 ---- sizeof(A), 在编译期完成。例 1 分析:
- A + 1 = 10004, 首先 int *p = A, 这个p和A是等价的, p + 1 = 10004;
- &A = 10000, 因为A是一个具有10元素的数组, &A则是指向10个元素数组的指针, 相当于 int (*ap)[10] = A, &A = ap = 10000。(用开头介绍的技巧可以这样来, A 的类型是 int[10],那么 &A 的类型是 int(*)[10] )
- &A + 1 = 10040, &A + 1 = ap + 1 = 10040
- B + 1 = 10040
- &B = 10000
- *B = 10000
- &B + 1 = 10400
版权声明
本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者Saturn和本文原始地址:
https://ndtm-idea.blogspot.com/2013/08/blog-post.html
0 comments:
Post a Comment