文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>一行代码 [转]

一行代码 [转]

时间:2006-06-20  来源:agg230

转自:www.chinaunix.net
----------------------------------------------------------------------------
#define offsetof(s, m) (size_t)(&(((s *)0)->;m))
这是offsetof的标准实现,主要是计算出结构体里成员的相对地址偏移量。
这里使用0只是一个使用的技巧,方便计算出偏移量。


#define offsetof(s, m)  (size_t)(&(((s *)0)->;m))
这个宏用来求一个结构体成员相对于这个结构体首地址的偏移量,
例如:
struct zhx{int lanjuan;};
这个结构体里的成员lanjuan,它的相对偏移量就是4;
这个宏里的0是地址,(s *)0,这一步是把从0这个地址开始的一块大小的内存解释成这个结构体类型,&(((s *)0)->;m),这一步是取这个结构体程序m的地址,结合zhx这个结构体的例子,如果取成员lanjuan的地址,这个地址当然是4,对吧! 也就是说,通过这个技巧,我们可以很方便的得到了这个成员偏移量。
size_t其实就是无符号整形,也就是把上面得到的那个地址转成无符号整形

设有结构变量
struct tagX
{
......
<typeY>; y;
......
}x;
其中 typeY 是任意一个合法的类型名。
假设 ptrx 是指向 x 的指针。
那么,分量 y 的偏移量是指:“类型 tagX 的任意一个实例的地址与其分量 y 的地址的差”。
对于实例 x 来说,就是 &(ptrx->;y) - ptrx。
------------------------- ^ ------ ^
----------------------   实例的地址  分量的地址
如果我们用 offset 来表示这个差值,就有
      offset = &(ptrx->;y) - ptrx
这一点是显而易见的。
特别的,当 ptrx 等于 0 时(虽然事实上 ptrx 永远也不会等于 0 ),
我们有:
      offset = &( 0->;y )
由于常量 0 的类型必须明确指定,所以就写作
      offset = &( ((struct tagX *)0) ->; y )
说到这儿就比较明显了,如果我们定义宏
# define offset     (&( ((struct tagX *)0) ->; y ) )
那么该宏的值就是 struct tagX 结构中的分量 y 相对于实例首址的偏移量。
其中 tagX 和 y 只是一个例子,一个更广泛使用的做法是用含有参数的宏将
tagX 和 y 代换:
# define offset( tagX, y )    ( &( ((tagX *)0) ->; y )
至于 size_t,它表示一个尺寸的类型,在大多数的系统中,它是基本类型
unsigned int 的一个宏。

--------------------------------------------------------------------------------
发表主题: c中怎么表示16进制的字符串  
或者怎么把一串16进制的或者2进制的数字写到char 数组里面
for examele 40 3c 需要写到char [2]里面去

无双 答:char a[]={0x40,0x3c}; 注意因为中间可能会有\0 所以这时使用strcpy等要小心 它们都是遇到\0就认为字符串结束
----------------------------------------------------------------------------------
typedef会在预处理中处理掉吗?
无双答:http://e.swjtu.edu.cn/jiaowu/jxzd/wykj/cpro/chp9/9-10-1.htm
typedef与#define有相似之处,
如:typedef int COUNT;和 #define COUNT int 的作用都是用COUNT代表int。但事实上,它们二者是不同的。

#define在预编译时处理的,它只能作简单的字符串替换,而typedef是在编译时处理的。实际上它并不是作简单的字符串替换,例如:typedef int NUM[10];并不是用NUM[10]去代替int,而是采用如同定义变量的方法那样来定义一个类型(就是前面介绍过的将原来的变量名换成类型名)。
-----------------------------------------------------------------------
const可用来限制指针不可变。也就是说指针指向的内存地址不可变,但可以随意改变该地址指向的内存的内容。

CODE:
[Copy to clipboard]
void main(void)

{

    char* const str = "Hello, World";    //常指针,指向字符串

    *str = 'M';            //可以改变字符串内容

    str = "Bye, World";        //错误,如能改变常指针指向的内存地址

} const也可用来限制指针指向的内存不可变,但指针指向的内存地址可变。

CODE:
[Copy to clipboard]
void main(void)

{

    const char* str = "Hello, World";    //指针,指向字符串常量

    *str = 'M';        //错误,不能改变字符串内容

    str = "Bye, World";    //修改指针使其指向另一个字符串

    *str = 'M';        //错误,仍不能改变字符串内容

} 看完上面的两个例子,是不是糊涂了?告诉你一个诀窍,在第一个例子中,const用来修饰指针str,str不可变(也就是指向字符的常指针);第二个例子中,const用来修饰char*,字符串char*不可变(也就是指向字符串常量的指针)。
排行榜 更多 +
飞艇大战

飞艇大战

飞行射击 下载
三维空间战斗机

三维空间战斗机

飞行射击 下载
战斗机教练

战斗机教练

飞行射击 下载