2014-10-02 131 views
0

我不知道为什么这段代码不显示错误。 让我知道这是为什么。为什么没有错误在C中显示此代码?

char str[10][5]; 

scanf("%s",&str[1]); 
printf("%s",str[1]); 

我认为这必须显示错误,但这只显示警告,通常执行。 请告诉我为什么这通常执行。

+3

然后将警告视为错误。 – 2014-10-02 07:36:53

+2

编译所有警告和调试信息('gcc -Wall -g')。你在[] scanf(3)'](http://man7.org/linux/man-pages/man3)上有[未定义行为](http://en.wikipedia.org/wiki/Undefined_behavior) /scanf.3.html)。仔细阅读它的文档。 [C99](http://en.wikipedia.org/wiki/C99)标准在这种情况下不需要*任何诊断,所以很高兴得到警告。 – 2014-10-02 07:37:11

回答

5

正如前面讨论过的,数组的地址与其第一个元素的地址具有相同的数值(数组在传递给函数时会衰减)。也就是说,str[1]这是一个char数组会衰减到一个指向char的指针,该指针包含与&str[1]相同的地址,该地址是该数组的地址。而且,不管你信不信,阵列都从第一个元素开始,这样它们就可以共享相同的地址。

所以这两个指针指向str中的一些内存位置,也就是有效地址;它们的输入方式不同。 C的弱类型系统容忍类型差异。 scanf将从格式说明符%s中假定您传递了一个字符指针。由于内存很好(毕竟是s[1]),你可以扫描它。

是的,它是UB,但适用于凡人可用的每个平台。

+0

谢谢!我明白! – maekchi 2014-10-02 07:52:49

+0

您的用户图片的好分形! – Joao 2014-10-07 06:03:37

2

表达

&str[1] 

的值等于表达式

str[1] 

的值即两个寻址相同存储器程度。

所以你因为根据格式说明%s也就是在这个记忆程度scanf函数存储文字补上他们终止零,直到它遇到的printf输出从相同的内存程度人物scanfprintf过程中的价值得到正确的结果终止零。这两个表达式都提供相同的地址。

+0

@maekchi Expression&str [1]给出数组str [1]占用的内存地址。并且rvalue str [1]给出了与str [1] – 2014-10-02 07:50:14

+0

@maekchi占用的范围相同的地址的数组的第一个元素的地址澄清:值是相同的,类型不是,但它“起作用“因为阵列布局的方式。但在形式上它是*未定义的行为*。 – juanchopanza 2014-10-02 07:53:21

0

scanfprintf是得到variadic参数的函数。这意味着你可以传递任何数量的参数。任何错误使用这些功能后会导致不确定的行为,因此这些功能被认为是不安全的。

4

str[1]&str[1]的值是相同的。但他们的类型不是,类型分别是char*char(*)[5]

%s所需的类型是char*,如果您传递不兼容的类型,则会出现未定义的行为。现在由于价值是相同的,程序将工作,但代码本身不正确。

+0

谢谢!我明白! – maekchi 2014-10-02 07:54:02

相关问题