C语言中修改stdout指针后fgetc读取行为的疑问咨询
对这段非法C代码的行为分析
首先必须明确:这段代码存在严重的未定义行为,标准C语言绝不允许对FILE*类型的指针进行算术运算(比如out=out-1),因为FILE是一个由编译器实现定义的结构体,直接操作其指针地址属于非法内存访问,程序的行为完全依赖于特定平台的内存布局,没有任何可移植性和正确性可言。
针对你的三个疑问,结合实际运行行为逐一解释:
1. out=out-1这行代码的作用是什么?
这行代码是完全错误的非法操作:
stdout是指向FILE结构体的指针,out-1是指针算术运算,它会让out指向stdout原本指向的内存地址的前一个位置。- 这个位置不属于
stdout对应的FILE结构体,甚至不属于程序的合法内存区域,所以这行代码没有任何合法作用,只是在制造非法内存访问。
2. 为何没有打印"Enter value:"的字符?为何不是仅打印末尾的一个字符?
实际运行中,你的代码里的fgetc(out)并没有读取stdout的内容,而是读取了**标准输入(stdin)**的内容,原因是:
- 你的平台上,
stdin和stdout的FILE结构体在内存中是相邻存放的,且stdin的地址刚好在stdout的前一个位置,所以out-1刚好指向了stdin的FILE结构体指针。 - 之前的
printf("\nEnter value: \n");因为包含换行符,触发了stdout的行缓冲刷新,内容已经输出到终端,而后续fgetc操作的是stdin,自然不会读取到stdout的输出内容。 - 读取
stdin时,fgetc会逐个读取用户输入的字符,直到遇到EOF,所以会打印所有输入的字符,而不是单个末尾字符。
3. 程序为何会等待用户输入?是否是因为fgetc?
是的,原因和上面的分析一致:
- 由于
out-1意外指向了stdin的FILE结构体,fgetc(out)等价于fgetc(stdin)。 - 当
stdin没有可用输入时,fgetc(stdin)会阻塞程序,等待用户输入内容,直到用户输入完毕并触发EOF(比如Linux下按Ctrl+D,Windows下按Ctrl+Z)。
内容的提问来源于stack exchange,提问作者NeuronB
相关产品推荐
相关产品推荐

