这可能听起来太疯狂但我只是想了想。在C为什么
char *pc = 'H'; // single character
char *ps = "hello"; // a string
两者都有效吗?我的意思是为什么char*
可以保持/引用一个字符以及一个以空字符结尾的字符串?
为什么没有为*pc
生成保护子句或编译器错误,因为char*
没有保留空终止字符串?
我在Ideone查看了它,但没有收到任何警告。
答案 0 :(得分:10)
可持有char
,因为存在从char
到char *
(通过int
)的隐式转换,并且因为{{ 1}}。但不应该执行此操作(从技术上讲,它是未定义的行为,因为字符的文字数值不太可能是sizeof(char *) >= sizeof(char)
类型的有效指针地址)。
在许多/大多数编译器中, 会生成警告:
char
答案 1 :(得分:3)
在
char *pc = 'H';
'H'
作为int
将被投放到char *
并将用于初始化pc
,编译器应对此发出警告。
在
char *ps = "hello";
"hello"
将评估其基地址,该地址将用于初始化ps
。
答案 2 :(得分:3)
char *pc = 'H';
上述语句定义pc
类型的char *
,这意味着它可以保存char
类型对象的地址。您正在使用字符H
初始化它 - 一种不同的类型。请记住,字符文字的类型为int
,并计算其字符代码,其中ASCII为72
。所以,上面的陈述等同于
char *pc = 72;
这是一个非法的操作,编译器应该警告你(在gcc中,使用标志-Wall
)。您不应该直接为指针分配地址,因为您不知道您是否有权访问内存地址。您应该使用address of
运算符&
来获取对象的地址,然后将其指定给指针。
char *ps = "hello";
在上面的语句中,字符串文字计算为指向其第一个元素的指针。此地址已分配给ps
,其类型相同,即char *
。但是,字符串文字在C
中是只读的,但不是const
限定的(与C++
不同),因此尝试使用指针ps
修改字符串文字不会导致编译器错误但未定义的行为,并且很可能由于段错误导致程序崩溃。因此,您应该将ps
定义为指向const object
-
const char *ps = "hello";
答案 3 :(得分:0)
当我使用g ++编译上面的代码行时,我收到以下警告:
test-12.c:1:12: warning: initialization makes pointer from integer without a cast [enabled by default]
编译器正在执行一些自动强制转换来初始化pc
。
char
- > int
- > char*
。
只需要注意编译器警告,以检测您正在尝试的异常操作。