我尝试为指针的第二个索引赋值,它给我一个警告
“[Warning]赋值使用指针生成整数而不使用强制转换”
并且它不运行此程序。我想知道,我在哪里弄错了?
#include<stdio.h>
void main()
{
char *p="John";
*(p+2)="v";
printf("%s",p);
}
答案 0 :(得分:2)
首先,在您的代码中
char *p="John";
p
指向字符串文字,并尝试修改字符串文字调用undefined behavior。
相关,C11
,章节§6.4.5
[...]如果程序试图修改这样的数组,行为是 未定义。
如果要修改,则需要一个数组,如
char p[]="John";
其次,*(p+2)="v";
错误,因为""
表示字符串,而您需要char
(提示:检查类型os *(p+2)
)。将其更改为
*(p+2)='v';
详细说明差异,引用C11
,章节§6.4.4.4,字符常量
整数字符常量是包含的一个或多个多字节字符的序列 在单引号中,如
'x'
。
和章节§6.4.5,字符串文字
字符串文字是包含在其中的零个或多个多字节字符的序列 双引号,如
"xyz"
。
第三,根据C标准,void main()
至少应为int main(void)
。
答案 1 :(得分:1)
您正在将指向字符串文字的指针指定给另一个字符串文字的元素。
首先,您需要更改指针并使其成为数组,因此任何修改都是合法的,这是一个示例
char p[] = "John";
然后您需要将"v"
替换为'v'
,这是一个由两个字符'\0'
和'v'
组成的字符串文字,替换为v
,这是字母{{的ascii值1}}作为整数
*(p + 2) = 'v';
另外,这是第三个元素,而不是第二个元素,因为第一个元素是p[0]
。
答案 2 :(得分:0)
你犯了两个错误。
首先,您正在尝试修改字符串文字的内容;这会调用未定义的行为,这意味着以下任何一种都是可能的(并且被认为是同样正确的):您的代码可能会崩溃,它可能会运行完成而没有任何问题,它可能会运行完成但不会更改字符串文字,它可能会使你的系统处于不良状态等。你的编译器可能会完全拒绝代码,虽然我不知道任何编译器这样做。
如果您希望能够修改字符串的内容,则需要为该字符串留出存储空间,而不是仅指向字符串文字:
char p[] = "John"; // copies the contents of the string literal "John" to p
// p is sized automatically based on the length of the
// string literal
这是一个假设的内存映射,显示了声明和初始化的结果:
Address Item 0x00 0x01 0x02 0x03
------- ---- ---- ---- ---- ----
0x8000 "John" 'J' 'o' 'h' 'n'
0x8004 0x00 0x?? 0x?? 0x?? // 0x?? represents a random byte value
...
0xfffdc100 p 'J' 'o' 'h' 'n'
0xfffdc104 0x00 0x?? 0x?? 0x??
不应修改生活在0x8000
的字符串文字;生成在p
0xfffdc100
的字符串可能会被修改(尽管缓冲区只有足够的空间来存储最多4个字符的字符串)。
你的第二个错误(以及导致编译器抱怨的错误)在这一行:
*(p+2)="v";
表达式"v"
是一个字符串文字,类型为“{-1}}的2元素数组”;因为它不是char
或一元sizeof
运算符的操作数,所以类型“衰减”为“指向&
的指针”,表达式的值是字符串文字的地址char
。
表达式"v"
具有类型*(p + 2)
(它解析为单个字符值),这是一个整数类型,而不是指针类型。您不能将指针值分配给非指针对象。
您可以通过将该行更改为
来轻松解决此问题char
这一次,您不是尝试将字符串文字的地址分配给*(p + 2) = 'v'; // note single quote vs double quote
,而是指定单个字符的值。