2

我正在使用 Linux 中的 C 语言进行一些串行通信。我正在使用文件描述符来执行此操作。之后由于某种原因char* s = "Hello world",我可以s使用write方法写入串口,没问题。我正在使用串行监视器程序来检查另一端。但是,我无法发送任何其他类型的数据。我从写入函数中收到“错误地址”错误。

但是,我注意到如果我做了一些非常奇怪的事情:int* x = "5";那我可以发送 this x。我的问题是,这到底是什么int* x = "5"意思?

4

3 回答 3

3
int* x = "5"; 

这不是有效的 C 代码。您必须将数组的值转换为 anint *但指针的取消引用仍然会破坏对齐规则并且是未定义的行为。

int *x =  (int *) "5";

最后一段代码存储了一个类型为 的未命名数组对象char [2]。的值"5"是指向其第一个元素的指针,指针是 a char *。强制转换将 转换char *为 an int *并将其存储在x.

于 2012-04-28T19:46:31.963 回答
2
int* x = "5";

违反约束的。这意味着任何符合标准的编译器都必须为其发出诊断。不必将其视为致命错误;允许编译器发出警告,然后成功翻译程序。但是语言没有定义这个声明的行为。

没有从char*"5"衰减后的类型)到的隐式转换int*

这就像 C 说某事是非法的一样接近。

实际上,接受此声明的编译器可能会将其视为等同于:

int *x = (int*)"5";

即,他们将插入转换。(这不是唯一可能的解释,但大多数编译器要么以这种方式解释它,要么拒绝它。)它采用char*数组表达式衰减产生的值"5"(即,'5'字符开头的地址字符串),并转换为int*.

结果int*指针指向一个int可能有效也可能无效的对象。该字符串"5"有两个字节长 ( { '5', '\0' })。如果int是两个字节,*x则可以评估将这两个字节解释为一个int值的结果——这将取决于系统的字节序。或者,如果字符串文字未正确对齐int对象,则评估*x可能会终止您的程序。如果int大于两个字节(通常是这样),*x是指超过字符串文字末尾的内存。在任何情况下,尝试修改*x都有另一种未定义的行为,因为尝试修改字符串文字是明确未定义的。

当您编译该声明时,您至少应该得到一个警告。如果是这样,你绝对不应该忽略它。如果您没有收到警告,您应该了解如何哄骗您的编译器产生更多警告。

TL;DR:不要那样做。

于 2012-04-28T19:53:14.010 回答
0

int* x = "5""5"将(a )隐式转换const char*为 anint*并将其存储在x. 因此,x将指向sizeof(int)最低为 0x35(字符 '5')的字节,下一个为 0,其余的都是不确定的,并且在读取时会导致未定义的行为。

于 2012-04-28T19:41:21.583 回答