混合炭和串C中的数组初始化
我知道以下2个初始化器是等效的:混合炭和串C中的数组初始化
char T1[]="abc";
char T2[]={'a', 'b', 'c', 0};
我有一个数组初始化这样的:
char T[]={0x10, 0xF, 0xF0, 'H', 'e', 'l', 'l', 'o', 0xC1, 0xD0};
撇开符号/无符号字符潜在的问题,有没有一种方法来混合2种样式的初始化,做类似的事情(这是行不通的):
char T[]={0x10, 0xF, 0xF0, "Hello", 0xC1, 0xD0};
你不能像那样混合他们。你可以做的是插入的十六进制代码withing一个字符串,如用什么:
char T[] = "\x10\x0f\xf0" "Hello" "\xc1\xd0";
请记住,这将会把一个\0
在该数组的结束,所以你可能需要调整,如果你“再利用sizeof
得到的字节计数:
size_t bytesInT = sizeof(T) - 1;
同样,不会处于Hello
的最后一个空,但您可以修复有:
char T[] = "\x10\x0f\xf0" "Hello\0" "\xc1\xd0";
您可能想知道为什么字符串被分成三个部分。这是有效的,因为汇编过程的一个非常早期的阶段涉及串联相邻字符串,这意味着"paxdiablo"
和"pax" "diablo"
在功能上是等同的。
一个原因是为了可读性,但是重要的是要确保十六进制规格不会“吞下”以下字符。但是,无论对于Hello
因为H
不是有效的十六进制字符,但你可以看到这里的问题:
#include <stdio.h>
int main(void) {
printf ("%d %d\n", sizeof("\x20Hi"), sizeof("\x20Bi"));
return 0;
}
这将输出4 3
尽管唯一的区别(貌似)在两个字符串是的改变一个字符。长度不同,因为Bi
中的B
实际上是作为十六进制数字消耗的,因此被视为\x20B
(尽管gcc
,例如gcc
会警告您结果值超出范围)。
虽然你必须小心'\ x'。例如'char T [] =“\ x10 \ x0f \ xf0Byee!\ xc1 \ xd0”;'不能按预期工作。使用字符串文字串联可以解决它:'char T [] =“\ x10 \ x0f \ xf0”“Byee!” “\ xc1 \ xd0”;' –
@Ian,好点,已将您的信息纳入答案。 – paxdiablo
不能混淆的两种风格,但你可以包括空值终止字符串HEX escape sequences内个十六进制字符:
// Instead of this
char T1[] = {0x10, 0xF, 0xF0, 'H', 'e', 'l', 'l', 'o', 0xC1, 0xD0};
// Do this:
char T2[] = "\x10\x0F\xF0" "Hello" "\xC1\xD0";
// or even this:
char T3[] = "\x10" "\x0F" "\xF0" "Hello" "\xC1" "\xD0";
以上和初始化,你有之间的唯一区别是,T2
和T3
在结尾处将会有一个额外的带有空终止符的字节。
上面的语法利用了C的特性,它自动连接多个由空格分隔的字符串文字。
也许在十六进制转义后启动文本时分隔字符串文字''\ x10 \ x0F \ xF0ByeBye \ xC1 \ xD0“;'是一个问题。 '“\ x10 \ x0F \ xF0”“ByeBye \ xC1 \ xD0”;'确定 – chux
@chux感谢您的建议,它也读得更好! – dasblinkenlight
不,我认为你不能按照你想要的方式去做。 –