D 编程/第一个程序示例
外观
< D 编程
待完成。
每个程序都必须有一个起点。在 D 中,这个起点是名为 main 的函数,除了 Windows GUI 程序,它使用 WinMain。你必须有一个这些函数来创建一个可运行的应用程序。
注意
- 虽然这个函数是程序处理流程的起点,但你的代码的其他部分可能在 main 获得控制之前执行。这些是模块和类构造函数,将在后面讨论。
- 一个或多个没有 main 函数的模块集合被称为库,它不是一个可执行程序。相反,库中的函数被应用程序用作预先编写的功能。
注意
- 在 D 编程语言中,main 函数必须返回 void 或 int 数据类型。这个返回值将返回给操作系统。
- 如果指定了 void 返回类型,应用程序将返回一个值为 0 的 int,否则程序必须提供一个返回值。
- 在 D 编程语言中,main 函数必须指定不带参数或以 char[][] 形式带单个参数,它是一个包含命令行参数的 UTF8 字符串数组。
总之,main 函数可以采用四种格式之一 ...
int main() // Application defined return value, ignores command line
int main(char[][] args) // Application defined return value, uses command line
void main() // returns 0, ignores command line
void main(char[][] args) //returns 0, uses command line
import std.stdio; void main() { writefln("Hello World!"); }
这个程序只是在控制台上打印 "Hello World!",后面跟着一个换行符,然后退出。第一行导入标准库模块 std.stdio。这个模块定义了函数 writefln,它用于写入标准输出。这个程序不使用命令行参数,并将返回零给操作系统。
你需要编译它来将其转换为可执行程序。首先,你将源代码保存到一个具有 ".d" 扩展名的文本文件中。假设我们把这个文件叫做 hw.d,以下是使用 DigitalMars 编译器编译它的方法 ...
dmd hw.d
import std.stdio; void main(char[][] p_Args) { foreach(char[] l_Arg; p_Args) { writefln("Argument '%s'", l_Arg); } }
这个程序打印出每个命令行参数。main 的参数是
char[][] p_Args
它将参数命名为 p_Args 并将其数据类型声明为 char[][],它是一个可变长度的 UTF8 字符串数组。这意味着 main 传递了一组零个或多个字符串。
foreach 语句是处理数组中每个元素的一种方法。在上面的格式中,它命名了一个临时变量 l_Arg,它将依次接收每个元素,因为 foreach 在数组 p_Args 中移动。临时变量的范围限定在 foreach 块内,因此外部代码无法看到它。
writefln 函数不仅向控制台写入内容,还允许你格式化输出。%s 是一个格式化代码,它指定了后续参数将在控制台输出中出现的位置。在这种情况下,如果 l_Arg 包含 "abc",则输出将是 "Argument 'abc'"。
这个注释丰富的示例突出了许多比 C++ 的改进。
#!/usr/bin/dmd -run /* sh style script syntax is supported! */ /* Hello World in D To compile: dmd hello.d or to optimize: dmd -O -inline -release hello.d or to get generated documentation: dmd hello.d -D */ import std.stdio; // References to commonly used I/O routines. void main(char[][] args) // 'void' here means return 0 by default. { // Write-Formatted-Line writefln("Hello World, " // automatic concatenation of string literals "Reloaded"); // Strings are denoted as a dynamic array of chars 'char[]' // auto type inference and built-in foreach foreach(argc, argv; args) { // OOP is supported, of course! And automatic type inference. auto cl = new CmdLin(argc, argv); // 'writefln' is the improved 'printf' !! // user-defined class properties. writefln(cl.argnum, cl.suffix, " arg: %s", cl.argv); // Garbage Collection or explicit memory management - your choice!!! delete cl; } // Nested structs, classes and functions! struct specs { // all vars. automatically initialized int count, allocated; } // Note that declarations read right-to-left. // So that 'char[][]' reads as an array of an array of chars. specs argspecs(char[][] args) // Optional (built-in) function contracts. in{ assert (args.length > 0); // assert built in } out(result){ assert(result.count == CmdLin.total); assert(result.allocated > 0); } body{ specs* s = new specs; // no need for '->' s.count = args.length; // The 'length' property is number of elements. s.allocated = typeof(args).sizeof; // built-in properties for native types foreach(argv; args) s.allocated += argv.length * typeof(argv[0]).sizeof; return *s; } // built-in string and common string operations, e.g. '~' is concatenate. char[] argcmsg = "argc = %d"; char[] allocmsg = "allocated = %d"; writefln(argcmsg ~ ", " ~ allocmsg, argspecs(args).count,argspecs(args).allocated); } /** Stores a single command line argument. */ class CmdLin { private { int _argc; char[] _argv; static uint _totalc; } public: /************ Object constructor. params: argc = ordinal count of this argument. argv = text of the parameter *********/ this(int argc, char[] argv) { _argc = argc + 1; _argv = argv; _totalc++; } ~this() /// Object destructor { // Doesn't actually do anything for this example. } int argnum() /// A property that returns arg number { return _argc; } char[] argv() /// A property that returns arg text { return _argv; } wchar[] suffix() /// A property that returns ordinal suffix { wchar[] suffix; // Built in Unicode strings (utf8,utf16, utf32) switch(_argc) { case 1: suffix = "st"; break; case 2: suffix = "nd"; break; case 3: suffix = "rd"; break; default: // 'default' is mandatory with "-w" compile switch. suffix = "th"; } return suffix; } /* ************** * A property of the whole class, not just an instance. * returns: The total number of commandline args added. *************/ static typeof(_totalc) total() { return _totalc; } // Class invariant, things that must be true after any method is run. invariant { assert(_argc > 0); assert(_totalc >= _argc); } }