Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中字符串作为整数打印的混淆_C_String_Integer - Fatal编程技术网

C语言中字符串作为整数打印的混淆

C语言中字符串作为整数打印的混淆,c,string,integer,C,String,Integer,我想知道字符串是如何用整数表示的,所以我编写了以下程序 #include <stdio.h> int main(int argc, char *argv[]){ char name[4] = {"@"}; printf("integer name %d\n", *(int*)name); return 0; } 这是可以理解的,因为@是整数形式的64,即十六进制形式的0x40 现在我将程序更改为: #include <stdio.h> int m

我想知道字符串是如何用整数表示的,所以我编写了以下程序

#include <stdio.h>

int main(int argc, char *argv[]){
  char name[4] = {"@"};  
  printf("integer name %d\n", *(int*)name);  
  return 0;
}
这是可以理解的,因为
@
是整数形式的
64
,即十六进制形式的
0x40

现在我将程序更改为:

#include <stdio.h>

int main(int argc, char *argv[]){
  char name[4] = {"@@"};  
  printf("integer name %d\n", *(int*)name);  
  return 0;
}
我不明白。因为
@
是十六进制的
0x4040
。所以它应该是
2^12+2^6=4160

如果我在字符串末尾计算
'\0'
,那么它应该是
2^16+2^10=66560


有人能解释一下
16448
从哪里来吗?

你的数学错了:
0x4040==16448
。两个4分别是第6位和第14位。

您的代码实际上调用了未定义的行为,因为您不能将
char*
别名为
int*
。这就是我们所知道的。只需查看一个不允许的原因,考虑如果代码运行在一个大的Endiad机器上,否则会发生什么。

如果想查看字符串的十六进制模式,只需在其字节上循环并打印出每个字节

void
print_string(const char * strp)
{
  printf("0x");
  do
    printf("%02X", (unsigned char) *strp);
  while (*strp++);
  printf("\n");
}
当然,您可以将字节转换为整数(很快就会溢出)并最终输出该整数,而不是打印字节。当你这么做的时候,你将被迫站在“你”的立场上

/* Interpreting as big endian. */
unsigned long
int_string(const char * strp)
{
  unsigned long value = 0UL;
  do
    value = (value << 8) | (unsigned char) *strp;
  while (*strp++);
  return value;
}
/*解释为big-endian*/
无符号长
整数字符串(常量字符*strp)
{
无符号长值=0UL;
做

value=(value这就是
16448
的实现方式:

0x4040可以这样写为二进制:

   4    0    4    0   -> Hex
 0100 0000 0100 0000  -> Binary
 2^14      2^6        =  16448
因为这里设置了第6位和第14位。

希望您能理解:)

64+64*2^8->16448您的体系结构是little endian。因此,4个字符的系列(即整数的大小)是0x40400000,看着它,就好像它是big-endian=0x0000400。现在,将十六进制转换为十进制实际上是16448,这是一个简单的数学错误。另外,您的原始nemory内容是40000000和40400000十六进制,小endian,所以是整数0x00000040和0x0000400。
printf(“%02X”,*strp)当
*strp
为负值时,
会遇到小问题。可能是
printf(“%02hhX”,*strp)
别名a
char*
int*
也是由于对齐要求。错误对齐的
char*
可能会导致总线故障。学究,实际上这是不允许的,因为标准是这样说的,而不是因为endianness。你指出它仍然很好。@chux很好的一点,ASCII不应该出现这种情况,但我添加了一个cast to
unsigned char
以防万一。这应该可以解决这个问题。@2501当然。我想这会变得很清楚,它是被禁止的,但如果可能的话,我总是想给出一个简短的理由来解释为什么标准不允许某些东西。为了更清楚地说明这一点,我现在加入了术语严格别名规则,并链接到相关的q这个问题已经有了很好的答案。
/* Interpreting as big endian. */
unsigned long
int_string(const char * strp)
{
  unsigned long value = 0UL;
  do
    value = (value << 8) | (unsigned char) *strp;
  while (*strp++);
  return value;
}
   4    0    4    0   -> Hex
 0100 0000 0100 0000  -> Binary
 2^14      2^6        =  16448