System.out、stdout 和 cout 在 Java、C 和 C++ 中分别是完全相同的吗?
为什么同一事物有三个不同的名称(尤其是当 C、C++ 和 Java 有很多共同点时)?
另外,我知道它们的用途,但它们到底是什么,在引擎盖下,我的意思是?
cout
本质上是一样的,stdout
但不同的是cout
是类型的ostream
(本质上意味着你可以使用<<
该方法输入格式化的数据或未格式化的数据write
。
stdout
附加到文件描述符(stdout 是 a FILE*
)。stdout
文件描述符是1
. 因为它返回对文件描述符的引用,所以可以在fputs
和中使用fprintf
。
JavaSystem.out
本质上就像stdout
(它java.io.FileDescriptor
与 handle 一起使用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);
来源:
它们是相同的东西,但它们没有相同的类型。例如,stdout
is aFILE*
和cout
is an std::ostream
。由于 C++ 支持两者,因此需要不同的名称。
在后台,所有这些变量都引用调用进程的标准输出。它是操作系统在生成新进程时始终打开的三个文件描述符 ( stdin
, stdout
, ) 之一。stderr
写入此文件描述符的所有内容最终都会显示在屏幕上或stdout
重定向到的任何位置(使用>
或>>
shell 运算符)。
它们是用于写入程序“标准输出”文件的每种语言特定的方式,这个概念起源于 C/UNIX。它们在为执行输出提供的确切功能/方法上有所不同。
It's also worth mentioning that both cout
and stdout
are available in C++, since it halfway tries to be a superset of the C language, but mixing the use of the two may be a bad idea unless you disable buffering entirely on both. I'm not aware of any requirement for the two to share a buffer, so it's possible that output will come out misordered if you mix them.
理论上它们是同一个东西,都发送到标准输出。
但在 C 和 C++ 中,cout 构建在 stdout 之上,以添加 System.out 提供的一些功能,例如格式化。由于 java 没有指针的概念,System,out 被重新设计为使用 PrintStream 来执行与 cout 类似的任务。
PritnStream 提供了一些额外的功能,例如,PrintStream 不会抛出 IOException,而是设置一个内部错误标志,然后可以使用 checkError 访问该标志。
我认为遵循命名约定是因为每种语言的设计者都不同。C、C++ 与 Unix 密切相关,因此它们使用标准输出和控制台等术语。Java 被设计为更加面向对象,因此 Java 的创建者决定将其命名为有点不同。