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_Pointers_Memory Management_C89 - Fatal编程技术网

C 获取指向字符串常量的指针

C 获取指向字符串常量的指针,c,string,pointers,memory-management,c89,C,String,Pointers,Memory Management,C89,“BM”必须位于只读内存区域的某个位置,那么为什么我不能获取指向它的指针?(它进行编译,但表示内存区域无效(clang编译器))C不允许获取文本的地址: 一元&运算符的操作数应为函数指示符、[]或一元*运算符的结果,或指定非位字段且未使用寄存器存储类说明符声明的对象的左值 --C99 6.5.3.2/1 文字不属于任何允许的操作数类别。这是语言的一个正式约束——一致性实现不需要接受违反它的代码,而需要生成描述违反的诊断。C不定义违反约束的代码行为 您可以实现与您似乎想要的类似的目标: short

“BM”
必须位于只读内存区域的某个位置,那么为什么我不能获取指向它的指针?(它进行编译,但表示内存区域无效(clang编译器))

C不允许获取文本的地址:

一元
&
运算符的操作数应为函数指示符、
[]
或一元
*
运算符的结果,或指定非位字段且未使用
寄存器
存储类说明符声明的对象的左值

--C99 6.5.3.2/1

文字不属于任何允许的操作数类别。这是语言的一个正式约束——一致性实现不需要接受违反它的代码,而需要生成描述违反的诊断。C不定义违反约束的代码行为

您可以实现与您似乎想要的类似的目标:

short var = *((unsigned short*)&"BM");

除其他外,这避免了将指针解引用到未对齐存储的风险。C将对齐变量
u
的存储,以便所有成员在适当的边界上对齐。这避免了您最初尝试的任何方法可能出现的陷阱。

最简单的解决方案当然是:

union short_str {
    char str[3];
    int16_t sh;
} u = { "BM" };
short var = u.sh;


charvar=*((const char*)和“BM”)在MSVC2012上编译。我认为这是一个很好的形式。我认为您的示例的行为是未定义的。它返回无效内存区域中的
读取错误
,这意味着它试图访问不存在或受读取保护的内存地址。令人惊讶的是,它可以在MSVC2012上运行。
int main(){char var=*((const char*)和“BM”);printf(“%c”,var);}
编译并在gcc 4.7.3上运行。行为未定义,因为地址不能保证可强制转换为指针类型。常量字符串的内存地址可能未对齐或位于只读内存中。您确定吗?您可以为其分配一个
常量char*
,并将其用作printf中的%s参数。这在C89中合法吗?在我看来,这是一项创新。@Klaslindbkäck这是唯一一种不可携带但足够快的方式。另一种是显式转换(解决方案正在尝试的)。但是通过删除
&
-只要将其分配给一个字符,它就可以工作。即
short var=*((const short*)“BM”)抛出警告。还有阿福。。在大多数情况下,警告应解释为错误。在C89中,初始值设定项是合法的。括号中的第一个元素用于初始化联合的第一个成员。如果括号中有多个初始值设定项,我不确定是否定义了语义。另外,请注意,从不同的联合成员(而不是上次写入的成员)读取包含实现定义的行为,但这是因为
(void*)&u.str==(void*)&u.sh
,必须是真的,实际上,这种方法非常可靠。因为它是实现定义的(而不是未定义的),所以在您发现它很可能工作的情况下,您可以依靠它继续工作。
short var= 0x424D;    // memory reads 4D, 42 = 'M', 'B'
short var= 0x4D42;    // memory reads 42, 4D = 'B', 'M'