假设我创建了一个主要包含数值字段的结构体,然后,我想用ASCII字符的值初始化这些不同的字段,这样最后,我就可以将该结构体转换为char*
指针,并一次性打印出来,获得该结构体的每字节“Map”打印输出。
下面是编译的例子:
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
struct mystruct_s {
uint8_t id_tag[6];
uint8_t fld_one[2];
uint64_t fld_two;
uint16_t fld_three;
uint16_t fld_four;
uint16_t fld_five;
};
struct mystruct_s myrh = {
.id_tag = "123456",
.fld_one = "78",
.fld_two = (uint64_t) ((uint8_t[8]) { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' }),
};
int main() {
printf("size %zu (%zu) bytes\n", sizeof(myrh), sizeof(struct mystruct_s));
printf("as string:\n");
printf("%s\n", (char*)&myrh);
printf("char 10: '%c'\n", ((char*)&myrh)[9]);
return 0;
}
...但是,当它运行时,它会产生:
$ gcc -g main.c -o main.exe
$ ./main.exe
size 24 (24) bytes
as string:
12345678`�V
char 10: ''
......而我原本期望的是12345678TTTTTTT
(char 10也是“T”)。所以,很明显我的“类型转换”不太起作用。
那么,有没有某种语法可以让我用等价于char数组的值初始化一个结构体的数值字段呢?(注意,上面的例子显示了将.fld_two中的所有字节初始化为'T'的意图,也就是说,每个ASCII都是0x 54-但我最终感兴趣的是指定像这样的任意字符串,使用不同的字符)
第二件令我惊讶的事情是,如果我添加另一个字段初始化:
...
struct mystruct_s myrh = {
.id_tag = "123456",
.fld_one = "78",
.fld_two = (uint64_t) ((uint8_t[8]) { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' }),
.fld_three = (uint16_t) ((uint8_t[2]) { 'E', 'E' }),
};
...
...则构建失败,原因如下:
gcc -g main.c -o main.exe
main.c:18:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
.fld_three = (uint16_t) ((uint8_t[2]) { 'E', 'E' }),
^
main.c:18:16: error: initializer element is not constant
main.c:18:16: note: (near initialization for ‘myrh.fld_three’)
那么,为什么它没有检测到此行的错误:
.fld_two = (uint64_t) ((uint8_t[8]) { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' }),
...然而它 * 没有 * 发现一个错误在此行:
.fld_three = (uint16_t) ((uint8_t[2]) { 'E', 'E' }),
...即使两行显然在做同样的事情,只是大小和值不同?
3条答案
按热度按时间6yt4nkrj1#
(uint64_t) ((uint8_t[8]) { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' })
这将在使用它的相同作用域创建一个 compound literal。像任何数组一样,
uint8_t [8]
在表达式中使用时衰减为指向第一个元素的指针。因此,最终将 * address* 转换为uint64_t
,而不是数据。你可以用联合类型的双关语来解决这个问题。
然而这带来了另一个问题,即它不再是一个编译时常量表达式,当然理想的解决方法是首先不要使用草率的全局变量,但如果这不是一个选项(也许你需要
const
),你可以选择改变结构体成员的类型:eqqqjvef2#
嗯,我设法通过联合达到了我想要的效果--但是有太多的类型和样板,这违背了目的(我想在OP中使用语法,因为它看起来很容易:)
这将打印:
2o7dmzc53#
除了你自己的答案之外,你还可以使用新学的X宏来把变量定义和初始化字符串集中在一个地方: