【问题标题】:Are System.out, stdout and cout the exact same thing?System.out、stdout 和 cout 是一回事吗?
【发布时间】:2011-04-21 20:49:37
【问题描述】:

System.out、stdout 和 cout 在 Java、C 和 C++ 中是否分别是完全相同的东西?

为什么同一事物有三个不同的名称(尤其是当 C、C++ 和 Java 有很多共同点时)?

另外,我知道它们的用途,但它们到底是什么,我的意思是?

【问题讨论】:

  • C、C++ 和 Java 仅在语法上相似,但语义却大相径庭。
  • 它们是不同的计算机语言..
  • 这些都不是语言的一部分。这些是该语言附带的库的一部分。它们不是关键字,不是语言规范的一部分。

标签: java c++ c iostream stdio


【解决方案1】:

cout 本质上与stdout 相同,但区别在于cout 的类型为ostream(这实质上意味着您可以使用<< 输入格式化数据或使用write 输入未格式化数据方法。

stdout 附加到文件描述符(stdout 是 FILE*)。 stdout 文件描述符是 1。因为它返回对文件描述符的引用,所以可以在fputsfprintf 中使用。

Java System.out 本质上类似于stdout(它使用java.io.FileDescriptor 和句柄1)并传递到FileOutputStream 并最终包裹在BufferedOutputStream 中。

java.lang.System 是这样初始化的:

 /**
     * Initialize the system class.  Called after thread initialization.
     */
    private static void initializeSystemClass() {
    props = new Properties();
    initProperties(props);
    sun.misc.Version.init();

        // Workaround until DownloadManager initialization is revisited.
        // Make JavaLangAccess available early enough for internal
        // Shutdown hooks to be registered
        setJavaLangAccess();

        // Gets and removes system properties that configure the Integer
        // cache used to support the object identity semantics of autoboxing.
        // At this time, the size of the cache may be controlled by the
        // vm option -XX:AutoBoxCacheMax=<size>.
        Integer.getAndRemoveCacheProperties();

    // Load the zip library now in order to keep java.util.zip.ZipFile
    // from trying to use itself to load this library later.
    loadLibrary("zip");

    FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
    FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
    FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
    setIn0(new BufferedInputStream(fdIn));
    setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
    setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));

    // Setup Java signal handlers for HUP, TERM, and INT (where available).
        Terminator.setup();

        // Initialize any miscellenous operating system settings that need to be
        // set for the class libraries. Currently this is no-op everywhere except
        // for Windows where the process-wide error mode is set before the java.io
        // classes are used.
        sun.misc.VM.initializeOSEnvironment();

    // Set the maximum amount of direct memory.  This value is controlled
    // by the vm option -XX:MaxDirectMemorySize=<size>.  This method acts
    // as an initializer only if it is called before sun.misc.VM.booted().
    sun.misc.VM.maxDirectMemory();

    // Set a boolean to determine whether ClassLoader.loadClass accepts
    // array syntax.  This value is controlled by the system property
    // "sun.lang.ClassLoader.allowArraySyntax".  This method acts as
    // an initializer only if it is called before sun.misc.VM.booted().
    sun.misc.VM.allowArraySyntax();

    // Subsystems that are invoked during initialization can invoke
    // sun.misc.VM.isBooted() in order to avoid doing things that should
    // wait until the application class loader has been set up.
    sun.misc.VM.booted();

        // The main thread is not added to its thread group in the same
        // way as other threads; we must do it ourselves here.
        Thread current = Thread.currentThread();
        current.getThreadGroup().add(current);
    }

FileDescriptor.out 是:

/**
 * A handle to the standard output stream. Usually, this file
 * descriptor is not used directly, but rather via the output stream
 * known as <code>System.out</code>.
 * @see     java.lang.System#out
 */
public static final FileDescriptor out = standardStream(1);

来源

【讨论】:

  • “文件描述符”不是 C 语言的一部分,而是 POSIX。说stdout“返回文件描述符”是对语言的错误使用(变量怎么可能“返回”任何东西?)并且具有误导性。
【解决方案2】:

它们是相同的东西,但它们的类型不同。例如,stdoutFILE*coutstd::ostream。由于 C++ 支持两者,因此需要不同的名称。

在底层,所有这些变量都引用调用进程的标准输出。它是操作系统在生成新进程时始终打开的三个文件描述符之一(stdinstdoutstderr)。写入此文件描述符的所有内容都会显示在屏幕上或 stdout 被重定向到的任何位置(使用 &gt;&gt;&gt; shell 运算符)。

【讨论】:

    【解决方案3】:

    它们是用于写入程序“标准输出”文件的每种语言特定的方式,这个概念起源于 C/UNIX。它们在执行输出时提供的确切功能/方法不同。

    还值得一提的是,coutstdout 在 C++ 中都可用,因为它在中途试图成为 C 语言的超集,但除非禁用缓冲,否则混合使用这两者可能是个坏主意完全在两者上。我不知道两者共享缓冲区的任何要求,所以如果你混合它们,输出可能会出现错误。

    【讨论】:

      【解决方案4】:

      理论上它们是同一个东西,都发送到标准输出。

      但在 C 和 C++ 中,cout 构建在 stdout 之上,以添加 System.out 提供的一些功能,例如格式化。由于 java 没有指针的概念,System,out 被重新设计为使用 PrintStream 来执行与 cout 类似的任务。

      PritnStream 提供了一些额外的功能,例如,PrintStream 不会抛出 IOException,而是设置一个内部错误标志,然后可以使用 checkError 访问该标志。

      我认为遵循命名约定是因为每种语言的设计者都不同。 C、C++ 与 Unix 密切相关,因此它们使用标准输出和控制台等术语。Java 被设计为更加面向对象,因此 Java 的创建者决定将其命名为不同的名称。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-01
        • 2011-06-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多