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
。