彭尼玛 发表于 2018-9-14 18:02:39

看了甲鱼哥的视频_(:з」∠)_才有所感悟,但还是遇上问题了



为啥我的输入会变成乱码………………{:5_105:}

人造人 发表于 2018-9-14 22:09:22





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

int main(void)
{
#if 0
        char buf;
        setvbuf(stdout, buf, _IOFBF, 100);
        fprintf(stdout, "hello world\n");
        //fflush(stdout);
#elif 0
        char buf;
        setvbuf(stdout, buf, _IOFBF, 100);
        fprintf(stdout, "hello world\n");
        fflush(stdout);
#else
        static char buf;
        setvbuf(stdout, buf, _IOFBF, 100);
        fprintf(stdout, "hello world\n");
        //fflush(stdout);
#endif
        return 0;
}

彭尼玛 发表于 2018-9-14 22:21:36

人造人 发表于 2018-9-14 22:09


哇,感动,学习到了2个东东_(:з」∠)_一个是#if #什么的,第一次知道还有这种用法,开心啊。
第二个,想问,为什么申请了静态数组就阔以有这种操作了呢??
这个static 好漂亮,到底是啥原理
static 我记得是如果在块里的话就是静态局部无链接的变量。文件作用域。可是为啥会这样子捏??!!

人造人 发表于 2018-9-14 22:50:30

彭尼玛 发表于 2018-9-14 22:21
哇,感动,学习到了2个东东_(:з」∠)_一个是#if #什么的,第一次知道还有这种用法,开心啊。
第二个, ...





图1没有输出 "hello world",因为fprintf不是直接把内容输出到显示器,而是先把内容输出到缓冲区,之后main函数直接返回了,返回到了启动代码,启动代码调用了main函数,main函数执行完后返回到启动代码
之后启动代码调用了exit函数退出了程序

图2输出了 "hello world",因为调用了 fflush(stdout);

图3也没有输出 "hello world"

实际上图1和图3都输出了东西只是输出的不一样而且也看不到,输出是在调用exit函数之后,输出后直接就结束程序了

当检测到stdout的缓冲区还有数据时,exit内部调用了类似 fflush(stdout);的函数,但是已经没机会显示出来了(又或者说是 显示出来了只是太快看不到而已)

我们的程序把main函数中的buf作为缓冲区,main函数返回后buf已经不存在了,这时调用的 fflush(stdout);函数会输出错误的数据
当buf是static的时候,意味着buf在整个程序的运行期间都是有效的,在main函数返回后也有效

在直接运行,不调试的情况下可以看到exit函数中调用类似 fflush(stdout);函数后输出的内容

彭尼玛 发表于 2018-9-14 23:06:53

人造人 发表于 2018-9-14 22:50
图1没有输出 "hello world",因为fprintf不是直接把内容输出到显示器,而是先把内容输出到缓冲区 ...

太棒了,太棒了,简直太棒了,静态存储期的妙用居然竟然在这里有了体现,太棒了,
看得我简直太棒了!!!!非常感谢!!{:5_105:}

彭尼玛 发表于 2018-9-14 23:12:50

人造人 发表于 2018-9-14 22:50
图1没有输出 "hello world",因为fprintf不是直接把内容输出到显示器,而是先把内容输出到缓冲区 ...

main函数返回到了启动代码,是不是就是你所说的exit内部?

彭尼玛 发表于 2018-9-14 23:18:00

人造人 发表于 2018-9-14 22:50
图1没有输出 "hello world",因为fprintf不是直接把内容输出到显示器,而是先把内容输出到缓冲区 ...

试着尝试去看了下stdio.h里面的东西,就调试进去,看不懂哪个才是类似fflush的东西,好懵逼啊,这特么是用C语言写的吗……完全看不懂

人造人 发表于 2018-9-14 23:35:08

本帖最后由 人造人 于 2018-9-14 23:40 编辑

彭尼玛 发表于 2018-9-14 23:12
main函数返回到了启动代码,是不是就是你所说的exit内部?

操作系统加载了当前程序后先执行一段用来申请必要的资源、初始化运行环境的代码(我把这段代码称作 “启动代码”)运行环境初始化完成后调用main函数,如果main函数返回了,那就调用exit函数退出程序
也就是如果你在main函数中调用了exit函数那就直接退出程序了,不会返回到启动代码(释放资源的操作留给了exit函数),如果你的代码没有调用exit函数,那么返回到启动代码后,启动代码帮你调用exit函数

exit是一个函数,这个函数不仅你的代码可以调用,启动代码也可以调用
exit函数和启动代码是两回事

人造人 发表于 2018-9-14 23:36:16

彭尼玛 发表于 2018-9-14 23:18
试着尝试去看了下stdio.h里面的东西,就调试进去,看不懂哪个才是类似fflush的东西,好懵逼啊,这特么是 ...

stdio.h文件中只是声明,exit函数的实现不在stdio.h中

人造人 发表于 2018-9-14 23:40:02

彭尼玛 发表于 2018-9-15 09:03:25

人造人 发表于 2018-9-14 23:35
操作系统加载了当前程序后先执行一段用来申请必要的资源、初始化运行环境的代码(我把这段代码称作 “ ...

哦,明白了,启动代码是一开始就有的呀_(:з」∠)_明白了,按照你所说的我试着让buf缓冲区放到main外面和自己在内部添加exit(0)两者皆成功让乱码显示出来。
也就是说启动代码本来是准备帮我们调用exit函数的,可是由于出了main函数这个块,属于局部自动变量的buf的数据清空了,所以这时候我们的输出会变成乱码是吧。

人造人 发表于 2018-9-15 11:32:00

彭尼玛 发表于 2018-9-15 09:03
哦,明白了,启动代码是一开始就有的呀_(:з」∠)_明白了,按照你所说的我试着让buf缓冲区放到main外面和 ...

彭尼玛 发表于 2018-9-15 12:23:41

人造人 发表于 2018-9-15 11:32


谢谢,最后一个问题,是不是不管什么情况下的程序只要我没有添加exit()函数,系统的启动代码都自动会在main函数结束之后调用这个exit函数帮我们进行退出?那retrun不是退出的吗?

人造人 发表于 2018-9-15 12:37:55

彭尼玛 发表于 2018-9-15 12:23
谢谢,最后一个问题,是不是不管什么情况下的程序只要我没有添加exit()函数,系统的启动代码都自动会在ma ...

return 只是函数返回
main函数中的return也一样
main函数中的return会返回到启动代码

人造人 发表于 2018-9-15 12:39:29

彭尼玛 发表于 2018-9-15 12:23
谢谢,最后一个问题,是不是不管什么情况下的程序只要我没有添加exit()函数,系统的启动代码都自动会在ma ...

每一个函数都可以有return,main函数也一样
return可以看成是退出当前函数

彭尼玛 发表于 2018-9-15 12:54:08

人造人 发表于 2018-9-15 12:39
每一个函数都可以有return,main函数也一样
return可以看成是退出当前函数

o o oo 明白了,明白了,谢谢谢谢_(:з」∠)_感动感动死了
页: [1]
查看完整版本: 看了甲鱼哥的视频_(:з」∠)_才有所感悟,但还是遇上问题了