Jump to content

D Programming/First Program Examples

From Wikibooks, open books for an open world

To be completed.

Structure of a D program

[edit | edit source]

Every program must have a starting point. In D, this is the function named main except for Windows GUI programs which uses WinMain. You must have one of these functions to create a runnable application.

Note:

  • Even though this function is the starting point for the program processing flow, it is possible to have other parts of your code execute before main is given control. These are module and class constructors, and will be discussed later.
  • A collection of one or more modules that do not have a main function is known as a library and is not an executable program. Instead, the functions in libraries are used by applications as pre-written functionality.

Simple D Programs

[edit | edit source]

Note:

  • The main function, in the D programming language, must return either void or int data type. This return value is returned to the operating system.
  • If void return type is specified, the application returns an int with the value 0, otherwise the program must supply a return value.
  • The main function, in the D programming language, must specify either no arguments or a single argument in the form char[][], which is an array of UTF8 strings that contain the command line parameters.

In summary, the main function can take one of four formats ...

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

Example 1

[edit | edit source]
import std.stdio;
void main() 
{ 
 writefln("Hello World!");
}

This program merely prints "Hello World!" on the console, followed by a newline and then exits. The first line imports the standard library module std.stdio. This module defines the function writefln, which is used to write to the standard output. This program does not use the command line arguments and will return zero to the operating system.

You need to compile this to convert it to an executable program. First you save the source code to a text file that has the ".d" extension. Assuming we called this file hw.d, here is the way to compile it using the DigitalMars compiler ...

dmd hw.d

Example 2

[edit | edit source]
import std.stdio;
void main(char[][] p_Args) 
{ 
 foreach(char[] l_Arg; p_Args)
 {
   writefln("Argument '%s'", l_Arg);
 }
}

This program prints out each of the command line parameters. The argument to main is

char[][] p_Args

which names the argument as p_Args and declares its data type as char[][], which is a variable-length array of UTF8 strings. This is saying that main is passed a set of zero or more character strings.

The foreach statement is a way to process each of the elements in an array. In the format above, it names a temporary variable l_Arg that will receive each element in turn as the foreach moves through the array p_Args. The temporary variable is scoped to the foreach block and thus cannot be seen by code outside the foreach.

The writefln function not only writes out things to the console, it also allows you to format that output. The %s is a formating code that specifies where a subsequent argument will appear in the console output. In this case, if l_Arg contains "abc" then the output will be "Argument 'abc'".

Example 3

[edit | edit source]

This heavily annotated example highlights many of the enhancements over 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);
     }
}