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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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,为什么即使k的数据类型是整数,这个hello也会打印出来?您的代码调用 您正在尝试使用字符串文字(字符*)初始化int。这没有任何意义,而且会引起争议 您正试图使用%s打印int,这需要一个char*。这也没有意义,需要调用。这里,hello是一个字符串文本,因此它存储在可执行文件的文本部分(沿着代码),当您将其分配给整数时,实际上指向文本的指针将分配给整数。由于两者通常大小相同(4字节),因此不会出现堆栈溢出之类的问题。 printf将正常工作,因为它将转到存储在变量中的地址(此处为k),并将

为什么即使k的数据类型是整数,这个hello也会打印出来?

您的代码调用

您正在尝试使用字符串文字(字符*)初始化
int
。这没有任何意义,而且会引起争议


您正试图使用
%s
打印
int
,这需要一个
char*
。这也没有意义,需要调用。

这里,
hello
是一个字符串文本,因此它存储在可执行文件的文本部分(沿着代码),当您将其分配给整数时,实际上指向文本的指针将分配给整数。由于两者通常大小相同(4字节),因此不会出现堆栈溢出之类的问题。 printf将正常工作,因为它将转到存储在变量中的地址(此处为k),并将打印字符串,直到找到字符串
\0
的结尾

注意-所做的是错误的,并且提供了不可取的结果 结果(忽略警告在某些情况下是犯罪,这是其中之一 这些案件)

关于它为什么为您打印字符串,下面是我的解释

在给定格式说明符%s的情况下,给定参数被标识/解释为字符串(char*)的基址。现在char*和int在逻辑上是相等的(忽略符号和C使用的其他属性)

所以在一个非常原始的层面上

printf("%s", k);
可能看起来像这样

int a = "String" ;
%s格式说明符的参数将被视为(char*)

现在,在%s作为格式说明符的情况下,程序应该从给定的地址开始扫描内存的每个字节,并将其类型转换为char,然后打印(当然,取决于可打印值与否,结果可能会很复杂) 可怕的)


在我们的例子中,虽然将a的给定值反引用到char*不会产生任何问题,因此没有错误,但是这并不一定总是这样。由于各种原因。

您的代码忽略了C的类型系统,因此在试图理解代码时需要忽略类型系统

我希望您的计算机上的sizeof(int)==sizeof(char*)。常量char*文本被分配给k。这是因为机器上的每个字节都有一个整数地址。类型系统的“引擎盖下”,指针就是这个整数

printf之所以能够工作,是因为它将k解释为以null结尾的数组的const char*,这是您分配给k的


正如其他人指出的,您的代码不能保证工作,因此它不应该出现在您计划发布的任何软件中。

我知道这没有意义,但为什么它会工作?什么工作?UB意味着任何事情都可能是结果。别再做那种蠢事了。您通常会得到意外的结果。这就是为什么在编译~1对未定义行为的法律响应是按照程序员的意图执行时,您应该使用
-Werror
标志的原因。然而,你不能指望它。上面的代码在ILP32型号上或像68k这样有单独地址和整数寄存器的CPU上不起作用。实际上,这会发出警告
初始化使指针变成整数。
这段代码是如何为您编译的???@thunderwilling代码编译时不会出错(假设没有
-Werror
标志),只有警告,我不知道怎么做。它是在CodeBlocks和Visual Studio 2013上编译的。对,我使用的是-weror。代码很可能不会在64位平台上运行,因为当该地址存储在
k
中时,
k
的地址的32位上限丢失,因为
k
只有32位宽。“因为两者大小相同”64位实现通常不会出现这种情况。
printf("%s", k);
int a = "String" ;
     a  contains Base address of String ( this is some read only location )
    +-----+-----+-----+-----+
    |  0x123456             |
    +-----+-----+-----+-----+

    And String may be defines as below with 'S' at location 0x123456

0x123456  
    +-----+-----+-----+-----+-----+-----+-----+
    |  S  | t   |  r  |  i  |  n  |  g  |  \0 |
    +-----+-----+-----+-----+-----+-----+-----+