为指针的索引赋值
Assignment a value to index of pointer
我尝试给指针的第二个索引赋值,它给了我一个警告
"[Warning] assignment makes integer from pointer without a cast"
而且 运行 没有这个程序。我想知道,我在哪里犯了错误?
#include<stdio.h>
void main()
{
char *p="John";
*(p+2)="v";
printf("%s",p);
}
首先,在你的代码中,
char *p="John";
p
指向字符串文字,并尝试修改字符串文字调用 undefined behavior.
相关,C11
,章节 §6.4.5
[...] If the program attempts to modify such an array, the behavior is
undefined.
如果要修改,需要一个数组,比如
char p[]="John";
其次,*(p+2)="v";
是错误的,因为""
表示一个字符串,而你需要一个char
(提示:检查类型 os *(p+2)
)。将其更改为
*(p+2)='v';
要详细说明差异,请引用 C11
,章节 §6.4.4.4,用于 字符常量
An integer character constant is a sequence of one or more multibyte characters enclosed
in single-quotes, as in 'x'
.
和章节 §6.4.5,字符串文字
A character string literal is a sequence of zero or more multibyte characters enclosed in
double-quotes, as in "xyz"
.
第三,按照C标准,void main()
应该至少是int main(void)
.
您正在将一个指向字符串文字的指针分配给另一个字符串文字的元素。
首先,你需要改变指针,使之成为一个数组,所以任何修改都是合法的,这是一个例子
char p[] = "John";
则需要将由'v'
和'[=14=]'
两个字符组成的字符串字面量"v"
替换为字母的ascii值'v'
v
作为整数
*(p + 2) = 'v';
另外,这是第三个元素而不是第二个,因为第一个元素是p[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
的字符串文字不应该被修改;位于 0xfffdc100
的 p
中的字符串可能会被修改(尽管缓冲区将只有足够的 space 来存储最多 4 个字符的字符串)。
你的第二个错误(也是导致编译器报错的错误)在这一行:
*(p+2)="v";
表达式 "v"
是一个字符串文字,类型为“char
的 2 元素数组”;因为它不是 sizeof
或一元 &
运算符的操作数,类型 "decays" 到 "pointer to char
",并且表达式的值是字符串文字的地址 "v"
。
表达式*(p + 2)
的类型为char
(它解析为单个字符值),它是一个整数类型,而不是指针类型。您不能将指针值分配给 non-pointer 对象。
您可以通过将该行更改为
轻松解决该问题
*(p + 2) = 'v'; // note single quote vs double quote
这一次,您不是尝试将字符串文字的地址分配给 p[2]
,而是分配单个字符的值。
我尝试给指针的第二个索引赋值,它给了我一个警告
"[Warning] assignment makes integer from pointer without a cast"
而且 运行 没有这个程序。我想知道,我在哪里犯了错误?
#include<stdio.h>
void main()
{
char *p="John";
*(p+2)="v";
printf("%s",p);
}
首先,在你的代码中,
char *p="John";
p
指向字符串文字,并尝试修改字符串文字调用 undefined behavior.
相关,C11
,章节 §6.4.5
[...] If the program attempts to modify such an array, the behavior is undefined.
如果要修改,需要一个数组,比如
char p[]="John";
其次,*(p+2)="v";
是错误的,因为""
表示一个字符串,而你需要一个char
(提示:检查类型 os *(p+2)
)。将其更改为
*(p+2)='v';
要详细说明差异,请引用 C11
,章节 §6.4.4.4,用于 字符常量
An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in
'x'
.
和章节 §6.4.5,字符串文字
A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes, as in
"xyz"
.
第三,按照C标准,void main()
应该至少是int main(void)
.
您正在将一个指向字符串文字的指针分配给另一个字符串文字的元素。
首先,你需要改变指针,使之成为一个数组,所以任何修改都是合法的,这是一个例子
char p[] = "John";
则需要将由'v'
和'[=14=]'
两个字符组成的字符串字面量"v"
替换为字母的ascii值'v'
v
作为整数
*(p + 2) = 'v';
另外,这是第三个元素而不是第二个,因为第一个元素是p[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
的字符串文字不应该被修改;位于 0xfffdc100
的 p
中的字符串可能会被修改(尽管缓冲区将只有足够的 space 来存储最多 4 个字符的字符串)。
你的第二个错误(也是导致编译器报错的错误)在这一行:
*(p+2)="v";
表达式 "v"
是一个字符串文字,类型为“char
的 2 元素数组”;因为它不是 sizeof
或一元 &
运算符的操作数,类型 "decays" 到 "pointer to char
",并且表达式的值是字符串文字的地址 "v"
。
表达式*(p + 2)
的类型为char
(它解析为单个字符值),它是一个整数类型,而不是指针类型。您不能将指针值分配给 non-pointer 对象。
您可以通过将该行更改为
轻松解决该问题*(p + 2) = 'v'; // note single quote vs double quote
这一次,您不是尝试将字符串文字的地址分配给 p[2]
,而是分配单个字符的值。