Joh*_*ith 6 c string casting character
在编写一些C代码时,我遇到了一个小问题,我必须将字符转换为"字符串"(一些内存块,其开头由char*指针给出).
我的想法是,如果sourcestr设置了某个指针(不是NULL),那么我应该将它用作我的"最终字符串",否则我应该将给定charcode转换为另一个数组的第一个字符,然后使用它.
出于这个问题的目的,我们假设变量的类型不能事先改变.换句话说,我不能只将我存储charcode为一个const char*而不是一个int.
因为我倾向于懒惰,所以我想:"嘿,我不能只使用角色的地址并将该指针视为字符串吗?".这是我写的一小段(不要把我的头撞到墙上!):
int charcode = FOO; /* Assume this is always valid ASCII. */
char* sourcestr = "BAR"; /* Case #1 */
char* sourcestr = NULL; /* Case #2 */
char* finalstr = sourcestr ? sourcestr : (char*)&charcode;
Run Code Online (Sandbox Code Playgroud)
现在我当然试过了,正如我所料,它确实有效.即使有一些警告标志,编译器仍然很高兴.但是,我有这种奇怪的感觉,这实际上是未定义的行为,我不应该这样做.
我认为这种方式的原因是因为char*数组需要以空值终止才能正确打印为字符串(我希望我的是!).然而,我不确定值&charcode + 1是否为零,因此我可能最终会出现一些缓冲区溢出的疯狂.
是否有一个实际的原因,它为什么它正常工作,或者我只是幸运在我尝试时在正确的地方得到零?
(请注意,我不是在寻找其他方式来实现转换.我可以简单地用一个char tmp[2] = {0}变量,并把我的角色在索引0我也可以使用像sprintf或者snprintf,只要我有缓冲区溢出不够细心.有无数的方法,我只是对这个特定的演员操作的行为感兴趣.)
编辑:我看到有几个人称这个hackery,我们要明确:我完全同意你的看法.在释放的代码中我实际上做这个是不够的受虐狂.这只是我好奇;)
您的代码定义明确,因为您始终可以转换为char*.但有些问题:
请注意,这"BAR"是一个const char*文字 - 所以不要试图修改内容.那将是不确定的.
不要尝试将其(char*)&charcode用作C标准库中任何字符串函数的参数.它不会以空值终止.所以从这个意义上说,你不能把它当成一个字符串.
指针算术(char*)&charcode 将在标量之前有效且包括一个charcode.但是不要试图取消引用任何超出charcode自身的指针.的范围内n的量,表达(char*)&charcode + n是有效取决于sizeof(int).
这绝对是未定义的行为,原因如下:
char是一个有符号整数,int当您的 char 是负值时(即char>127在具有 8bits 的机器上char),如果您按照下面的代码分配值,则可能会由于符号扩展而失败代码:
char ch = FOO;
int charcode = ch;
Run Code Online (Sandbox Code Playgroud)
PS关于第3点:在具有正值的小端机器中,您的字符串确实会以NULL结尾sizeof(int)>sizeof(char)char,因为int的MSB将为0,并且这种字节顺序的内存布局是LSB-MSB(LSB在前)。