我有以下代码在我初始化ch
的行崩溃:
char * p = "Test";
char ch = *p++;
printf("Here : %s\n%c", p, ch);
但是以下代码没有问题:
char * p = "Test";
char ch = *p++;
ch++;
printf("Here : %s\n%c", p, ch);
答案 0 :(得分:5)
在第一种情况下,您尝试更改编译到程序中的“Test”字符串中的T
,该字符串保存在您的代码无意更改的内存中(通常;有些环境允许,但通常不允许)。这是因为(*p)++
表示(松散地说) *p = *p + 1
(例如,获取p
指向的字符,递增它并将其写回),以及当然,*p
指向已编译的“测试”。
您的第二个版本没有此问题,因为您正在递增ch
,您 允许更改。事实上,你的第二个版本实际上增加了两个不同的东西;首先它char ch = *p++;
检索*p
处的字符,然后递增p
(现在它指向“测试”中的“e”),然后执行ch = ch++
。 (你可能只是ch++;
,因为++
直接在其操作数上运行。)
答案 1 :(得分:4)
问题归结为运算符优先级和使用括号()
。
char ch = (*p)++;
此行将(尝试)增加p
char ch = *p++;
这个设置ch
等于p
中存储的地址处的字符,然后递增p
中存储的地址。 ++
运算符优先于指针解引用运算符,因此它将首先执行。需要说明的是,第二行相当于:
char ch = *(p++);
答案 2 :(得分:1)
您的第一个示例会增加*p
处的值。由于p指向一个字符串常量,因此许多编译器都不允许这样做。
你的第二个例子增加指针,而不是它指向的值。
答案 3 :(得分:1)
此代码:
(*p)++
正在尝试增加p指向的值。 p指向const char字符串“Test”,无法修改。
答案 4 :(得分:0)
第一个版本是这样做的:
char * p = "Test"; //this should really be const char *
*p = *p + 1; //CRASH! attempthing to modifiy the contents of a string literal
char ch = *p;
ch = ch++; //This is excessive, ch++ on it's own would do the same
printf("Here : %s\n%c", p, ch);
虽然第二个版本是这样做的:
char * p = "Test"; //still should be const char *
char ch = *p;
p++; //p now points to "est"
ch = ch++;
printf("Here : %s\n%c", p, ch); //prints est\nU