C 为什么我可以使用指针作为write()的缓冲区,但需要使用指针地址作为read()的缓冲区?

C 为什么我可以使用指针作为write()的缓冲区,但需要使用指针地址作为read()的缓冲区?,c,pointers,pipe,C,Pointers,Pipe,我正在尝试将单个字符从父进程传输到子进程。通常这是用一个简单的变量来完成的,但我正在用指针来尝试。如果使用简单变量(var),write()和read()的缓冲区参数都是&var,但是当我使用指针(*ptr)时,read()的参数是ptr,write()的参数是&ptr 我是C语言的新手,我不太明白为什么会这样 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void)

我正在尝试将单个字符从父进程传输到子进程。通常这是用一个简单的变量来完成的,但我正在用指针来尝试。如果使用简单变量(
var
),write()和read()的缓冲区参数都是
&var
,但是当我使用指针(
*ptr
)时,read()的参数是
ptr
,write()的参数是
&ptr

我是C语言的新手,我不太明白为什么会这样

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

int main(void) {

  char *chPtr;
  int fd[2];
  pid_t pid;

  char value = 'z';

  pipe(fd);
  pid = fork();

  if (pid) {     // Parent
    close(fd[0]);
    chPtr = &value;
    write(fd[1], chPtr, 1);
    close(fd[1]);
  }

  if (! pid) {   // Child
    close(fd[1]);
    read(fd[0], &chPtr, 1);
    printf("the result is %c\n", (int)chPtr);
    close(fd[0]);
  }
  return 0;
}
#包括
#包括
#包括
内部主(空){
char*chPtr;
int-fd[2];
pid_t pid;
字符值='z';
管道(fd);
pid=fork();
if(pid){//Parent
关闭(fd[0]);
chPtr=&value;
写入(fd[1],chPtr,1);
关闭(fd[1]);
}
如果(!pid){//Child
关闭(fd[1]);
读取(fd[0],&chPtr,1);
printf(“结果是%c\n”,(int)chPtr);
关闭(fd[0]);
}
返回0;
}

您的子实现没有达到预期效果。虽然它可以工作,但它确实是一个设计缺陷

函数的作用是:读入调用者分配的缓冲区。因为要将&chPtr传递给read(),所以要使用指针的内存作为缓冲区,这恰好起作用,因为您只读取一个字符,该字符适合指针的内存

通常情况下,您会想要以下内容:

if (! pid) {   // Child
    char buf[1];
    close(fd[1]);
    read(fd[0], buf, 1);
    printf("the result is %c\n", buf[0]);
    close(fd[0]);
}

指针按其名称所示,指向内存位置。如果是
读取
,则将值存储在指针中,而不是将值放置在指针指向的位置。事实上,在指针上使用
&
运算符实际上就是在创建指向指针的指针。这就是为什么需要显式强制转换来使用
printf
中的值

相反,您应该将指针设置为
value
的地址,然后正常使用指针,如下所示:

chPtr = &value;
read(fd[0], chPtr, 1);
printf("the result is %c\n", value);

更常见的做法是使用字节数组(即char[])而不是指针,或者在堆上分配内存(请参见malloc)。

您认为它应该在哪里
&chPtr
?除非我遗漏了什么,否则它实际上应该只是普通的
chPtr
read
()将
void*
作为第二个参数,因此只需传递
chPtr
,因为它已经是
char*
。通过写入
&chPtr
获取地址会使其成为
char**
,而
读取的
不需要这样做。而且
printf
看起来更加可疑。“%c”说明符需要一个
char
,但您正在传递一个
int
。不仅如此,创建
int
的方法是通过铸造
char*
。很少需要将指针类型强制转换为实际标量。您可能想要的是不带
(int)
强制转换的
*chPtr