C:指针混乱

kin*_*er1 1 c pointers lvalue post-increment

我明白这是基本的东西的一部分,但我被卡住了:-(有人可以帮帮我吗?

计划1:

#include <stdio.h>
#include <stdlib.h> 

int main()
{
 int a=1,b=2,c;
 c=(a+b)++;
}
Run Code Online (Sandbox Code Playgroud)

为什么输出错误?是否需要左值?

计划2:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
 char *p1="name";
 char *p2;

 p2=(char*)malloc(20);
 memset(p2,0,20);

 while(*p2++=*p1++);
 printf("%s\n",p2);

}
Run Code Online (Sandbox Code Playgroud)

为什么是输出,一个空字符串?如果我颠倒增量的顺序,那就是:while(++*p2=++*p1);为什么左值误差来了?

Seb*_*olm 8

对于第一个问题,(a+b)++意味着"将值增加a+b1".

a+b但是,你不能增加它,因为它不是一个变量.您希望在以下代码中发生什么?

int a = 1, b = 2;
printf("a = %d, b = %d, a+b = %d\n", a, b, a+b);
(a+b)++;
printf("a = %d, b = %d, a+b = %d\n", a, b, a+b);
Run Code Online (Sandbox Code Playgroud)

显然第一个printf应该打印

a = 1,b = 2,a + b = 3

但是第二个呢?

a =?,b =?,a + b = 4

如果我们增加总和,则不清楚a或b应该是什么.

关于第二个问题,请记住,p2当您复制数据时,您正在进行更改,因此当您要求打印出它所指向的内容时,它指向字符串的末尾,而不是开头.

更简单的方法是使用字符串副本strcpy,如下所示:

strcpy(p2, p1);
Run Code Online (Sandbox Code Playgroud)

请注意,这只是安全的,因为您知道字符串p1的大小不大于p2.如果您不确定字符串的大小(例如,如果您从用户输入中获取字符串),则需要小心,如维基百科上所述.

至于为什么while(++*p2=++*p1);不起作用,同时while(*p2++=*p1++);:

Postfix- ++具有更高的优先级*.这意味着,*p2++意味着*(p2++).所以

*(p2++) = something;
Run Code Online (Sandbox Code Playgroud)

是相同的

*p2 = something;
p2 += 1;
Run Code Online (Sandbox Code Playgroud)

同时,++*p2意味着++(*p2),或"无论什么p2指向,增加一个".

如果你说,你再次遇到问题:

 int a = 5, *p2 = &a;
 ++*p2 = 10;
 printf("a = %d\n", a);
Run Code Online (Sandbox Code Playgroud)

您希望打印什么?如果有的话,它应该打印9,因为你告诉编译器*p2+1 = 10.

但是,你不能指望C编译器来解决这个等式,所以为了保持语言的简单和高效,这种事情是被禁止的.