#define STRING(s) (((String*)s)-1)
世界上是什么(((String*)s)-1)
?
typedef struct String { int length; int capacity; unsigned check; char ptr[0]; } String;
你正在施放一个String *
。 然后你从中减去一个(使它指向以前的任何东西)。
任何更具体的东西都需要知道String
的定义 – 但是(WILD SPECULATION)我猜应用程序使用双VB / C风格的字符串(空终止,前面有长度),这个函数从适合的forms改变它C函数(指向第一个字符的指针)可用于另一个类型(指向长度的指针)。
在机械方面,宏可以像其他人已经描述的那样工作。 但是,在语义上,您可以将其视为从char *
s到String *
s的转换forms。
String
结构是计数字符串的标题,即您无需扫描NUL字节即可知道总长度的字符串。 此特定版本还保留分配的总数。 你可以创建一个如下:
struct String *str = malloc(sizeof(*s) + maxlen); str->length = 0; str->capacity = maxlen; str->checked = /* ??? */;
在某个地方应该有一些各种各样的function来操纵这些计数的字符串。
宏本身是一个黑客,从普通的char *
,假设指向上面分配的String
的第一个字符,返回String *
。 它将使用这样的东西:
/* allocate str as above */ char *s = str->p;
现在,通过一系列函数调用或返回,你以某种方式松散跟踪包含s
的String结构,你需要再次找到它。 你写:
String *str2 = STRING(s);
这不是在C中实现计数字符串的特别好的方法,但它演示了一种人们不时看到的技术。
其他人回答了你的问题。 在大小为零的struct String
中声明ptr
的技术被称为“ struct hack ”,并且在C99之前不可移植 (尽管它甚至在C99之前被广泛使用,并且似乎无处不在)。 这个想法是ptr
使用0个字节,所以如果你有一个指向ptr
的指针,并且想要一个指向原始结构,你可以使用STRING
宏。 您正在从ptr
成员的地址中减去struct
的大小,从而获得结构的起始地址。
在给定指向其任何成员的指针的情况下获取结构的起始地址的更好方法是使用stddef.h
定义的offsetof()
宏。 offsetof(struct type, member)
,顾名思义,给出struct type
中member
的偏移量:
#define STRING(x) ((String *)(((char *)(x) - offsetof(struct String, ptr))))
然后你可以这样做:
#include #include #include typedef struct String { int length; int capacity; unsigned check; char ptr[0]; } String; #define STRING(x) ((String *)(((char *)(x) - offsetof(struct String, ptr)))) int main(void) { String *s = malloc(sizeof *s + 100); String *t; char *mystring = s->ptr; t = STRING(mystring); assert(t == s); return EXIT_SUCCESS; }
offsetof()
在stddef.h
定义。
请注意,在C99中,“struct hack”会在struct
声明ptr
为:
char ptr[];
即,没有大小。
不知道为什么宏是这样做的。 可能String的定义需要这个,但这只是一个疯狂的猜测。
以上就是c/c++开发分享丑陋的宏观解释(仅1行)相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/550031.html