アルゴリズム

効率の良いアルゴリズムをつくるには、複雑性だけでなく、計算時間(running time)、領域(storage space)など、動的なものも考慮しなければならない。つまり、CPU・メモリの性能や、サーバー環境を熟知した上で、プログラムを組むことに他ならない。

また、高レベルのものは、問題の重要な構造に対応している。

アセンブラツール

よく使われる代表的なもの

1.MASA
Microsoft Macro Assemblerの略ともいわれ、当初は、Macro Assembler。MicrosoftのOS(DOSやWindows)上で実行するプログラムのために開発されたアセンブラです。

; hello.asm

	include ¥masm32¥include¥masm32rt.inc

	.code

start:

	print "Hello, Assembly Language!",13,10
	exit

end start

2.NASM
NASM(Netwide Assembler)はGNUのLGPLで公開されているフリーソフトウェアのアセンブラです。このアセンブラはIntel x86ファミリーをターゲットとしており、様々な形式で出力することができます。

; ha.asm
	bits 16
	org 0x100

	mov ah, 2 ;文字出力を指定
	mov dl,[msg]	;msgの先頭'H'
	int 21h
	mov dl,[msg+7] ; msgの8番目'a'
	int 21h
	mov ax,4C00h ;プログラム終了
	int 21h

msg db "Hello, assembler$"

3.GNU Assembler(GAS)
UNIX系の各種アーキテクチャ(x86, 680×0, SPARC, VAX)向けのアセンブラファミリーです。AT&T表記と呼ばれる構文を使っています。もともと、gcc(GNU C, C++コンパイラ)との親和性が高く、UNIX系OSでC/C++とリンクするアセンブリ言語プログラムを記述するためによく使われます。

# hello.S
.text
	.global _start

	_start:

	movl $len,%edx
	movl $msg,%ecx
	movl $1,%ebx
	movl $4,%eax
	int $0x80

	# exit

	movl $0, %ebx
	movl $1, %eax
	int $0x80

	.data

	msg:
		.ascii "Hello, world!¥n"
		len = . - msg

言語判定

<html><meta charset="utf-8"><body><?php
// フォームからの入力を得る
    $text = empty($_POST&#91;'text'&#93;) ? "" : $_POST&#91;'text'&#93;;
    $result = "";
    if ($text != ''){
    // 言語を判定する
        $data = count_text($text);
        $ann = fann_create_from_file('./lang.net');
        $r = fann_run($ann, $data);
        $i = array_max_index($r);
        $lang_list = &#91;'英語', 'タガログ語', 'インドネシア語'&#93;;
        $result = "<h3>".$lang_list[$i]."でしょう!</h3><ul>";
        foreach ($r as $i => $v){
            result .= "<li>".$lang_list[$i].":".floor($v*100)."%</li>";
        }
        $result .= "</ul>";
    }
    $text_enc = htmlspecialchars($text);
// 配列で値が最大のインデックスを返す
    function array_max_index($a){
        $mv = -1; $mi = -1;
        foreach ($a as $i => $v){
            if ($mv < $v){
                $mv = $v; $mi = $i;
            }
        }
        return $mi;
    }

// アルファベットの個数を数える
    function count_text($text){
        $text = strtolower($text);
        $text = str_replace(" ", '', $text);
        $cnt = array_fill(0, 26, 0);
        for ($i = 0; $i < strlen($text); $i++){
            $c = ord(substr($text, $i, 1));
            if (97 <= $c && $c <= 122){
                $c -= 97;
                $cnt&#91;$c&#93;++;
            }
        }
        return $cnt;
    }
?>
<h1>三ヶ国語の言語判定</h1>
<form method="post">
    <textarea name="text" rows=5 cols=60><?php echo $text_enc ?>
</textarea><br>
<input type="submit" value="言語の判定">
</form>
<div><?php echo $result ?></div>

simple XML

phpでxmlを扱うにも、いろいろな方法があります。文字列のxmlを読み込んで解析し、xmlの内容を出力します。

<?php
// set XML
$xml_str = <<<XML
<?xml version='1.0'?>
<items>
    <item id="101">
        <name>石鹸</name>
        <price>510</price>
    </item>
    <item id="102">
        <name>ブラシ</name>
        <price>330</price>
    </item>
</items>
XML;

// analyze XML
$xml = simplexml_load_string($xml_str);
// display each item info
foreach ($xml->item as $it){
    $attr = $it->attributes();
    echo "(id:".$attr["id"].")";
    echo $it->name." - ".$it->price." 円\n";
}

brk

ヒープ領域に新たにメモリを割り当て、そのメモリ上に文字列をコピーして、その文字列を標準出力に出力する例です。

#include 

#include 
#include 

int main(){
    char *s;
    
    if ((s = sbrk(7))== (void *)-1){
        perror("sbrk");
        return 1;
    }
    strcpy(s, "hello\n");
    write(1, s, 6);
    
    if (brk(s) < 0){
        perror("brk");
        return 1;
    }
    return 0;
}

lseekプログラム

#include < sys/types.h >
#include < unistd.h >

#include < sys/stat.h >
#include < fcntl.h >
#include < stdio.h >

int main()
{
    int fd;
    off_t offset;
    ssize_t n;
    char buf[4096];
    
    if((fd = open("file.txt", O_RDONLY)) < 0){
        perror("open");
        return 1;
    }
    
    if ((offset = lseek(fd, 10, SEEK_SET)) < 0){
        perror("lseek");
        return 1;
    }
    
    if ((n = read(fd, buf, sizeof buf)) < 0){
        perror("read");
        return 1;
    }
    write(1, buf, n);
    
    return 0;
}

setpgid

引数pid、引数pgidの両方にゼロを指定

#include < unistd.h >

#include < stdio.h >

int main()
{
    if (setpgid(0, 0) < 0){
        perror("setpgid");
        return 1;
    }
    return 0;
}

uid, euidの設定

#include < sys/types.h >
#include < unistd.h >

#include < stdio.h >

static void
printuid()
{
    printf("uid = %d euid = %d\n",
           (int)getuid(),(int)geteuid());
}

int main() {
    uid_t uid, euid;
    
    uid = getuid();
    euid=geteuid();
    
    printuid();
    
    if(setuid(uid) < 0){
        perror("setuid");
        return 1;
    }
    printuid();
    
    if(setuid(euid) < 0){
        perror("setuid");
        return 1;
    }
    printuid();
    
    return 0;
}