継承

#include 
#include 
using namespace std;

enum yn {no, yes};
enum color {red, yellow, green, orange};
void out(enum yn x);
char *c[] = {
    "red","yellow","green","orange"
};

class fruit {
public:
    enum yn annual;
    enum yn perennial;
    enum yn tree;
    enum yn tropical;
    enum color clr;
    char name[40];
};

class Apple : public fruit {
    enum yn cooking;
    enum yn crunchy;
    enum yn eating;
public:
    void seta(char *n, enum color c, enum yn ck, enum yn crchy, enum yn e);
    void show();
};

class Orange : public fruit {
    enum yn juice;
    enum yn sour;
    enum yn eating;
public:
    void seto(char *n, enum color c, enum yn j, enum yn sr, enum yn e);
    void show();
};

void Apple::seta(char *n, enum color c, enum yn ck, enum yn crchy, enum yn e)
{
    strcpy(name, n);
    annual = no;
    perennial = yes;
    tree = yes;
    tropical = no;
    clr = c;
    cooking = ck;
    crunchy = crchy;
    eating = e;
}

void Orange::seto(char *n, enum color c, enum yn j,
                  enum yn sr, enum yn e)
{
    strcpy(name, n);
    annual = no;
    perennial = yes;
    tree = yes;
    tropical = yes;
    clr = c;
    juice = j;
    sour = sr;
    eating = e;
}

void Apple::show()
{
    cout << name << "apple: " << "\n";
    cout << "plant :"; out(annual);
    cout << "ta plant:"; out(perennial);
    cout << "tree:"; out(tree);
    cout << "nettai: "; out(tropical);
    cout << "color:" << c[clr] << "\n";
    cout << "for cook" ; out(cooking);
    cout << "solid: "; out(crunchy);
    cout << "food: "; out(eating);
    cout << "\n";
}

void Orange::show()
{
    cout << name << "orange: " << "\n";
    cout << "plant :"; out(annual);
    cout << "ta plant:"; out(perennial);
    cout << "tree:"; out(tree);
    cout << "nettai: "; out(tropical);
    cout << "color:" << c[clr] << "\n";
    cout << "juice" ; out(juice);
    cout << "suppi: "; out(sour);
    cout << "food: "; out(eating);
    cout << "\n";
}

void out(enum yn x)
{
    if(x==no) cout << "no\n";
    else cout << "yes\n";
}

int main()
{
    Apple a1, a2;
    Orange o1, o2;
    
    a1.seta("red delicious", red, no, yes, yes);
    a2.seta("jonasson", red, yes, no, yes);
    
    o1.seto("neble", orange, no, no, yes);
    o2.seto("ballensia", orange, yes, yes, no);
    
    a1.show();
    a2.show();
    
    o1.show();
    o2.show();
    
    return 0;
}

コンストラクタとデストラクタ

malloc()とfree()関数を使って、メモリの割り当てと解放をしています。

#include 
#include 
#include 
using namespace std;

#define SIZE 255

class strtype {
    char * p;
    int len;
public:
    strtype();
    ~strtype();
    void set(char *ptr);
    void show();
};

strtype::strtype()
{
    p = (char *) malloc(SIZE);
    if(!p){
        cout << "error memory\n";
        exit(1);
    }
    *p = '\0';
    len = 0;
}

strtype::~strtype()
{
    cout << "release p\n";
    free(p);
}

void strtype::set(char *ptr)
{
    if(strlen(ptr) >= SIZE){
        cout << "character is bigger \n";
        return;
    }
    strcpy(p, ptr);
    len = strlen(p);
}

void strtype::show()
{
    cout << p << " - long: " << len;
    cout << "\n";
}

int main()
{
    strtype s1, s2;
    
    s1.set("this is a test.");
    s2.set("I like C++.");
    s1.show();
    s2.show();
    
    return 0;
}

stack class

stckとtosの非公開変数

#include 
using namespace std;

#define SIZE 10

class stack {
    char stck[SIZE];
    int tos;
    
public:
    void init();
    void push(char ch);
    char pop();
};

void stack::init()
{
    tos = 0;
}

void stack::push(char ch)
{
    if(tos==SIZE){
        cout << "stack is full";
        return;
    }
    stck[tos] = ch;
    tos++;
}

char stack::pop()
{
    if(tos==0){
        cout << "tack is empty";
        return 0;
    }
    tos--;
    return stck[tos];
}

int main()
{
    stack s1, s2;
    int i;
    
    s1.init();
    s2.init();
    s1.push('a');
    s2.push('x');
    s1.push('b');
    s2.push('y');
    s1.push('c');
    s2.push('z');
    for(i=0; i<3; i++) cout << "s1 pop:" << s1.pop() << "\n";
    for(i=0; i<3; i++) cout << "s2 pop:" << s2.pop() << "\n";
    
    return 0;
}

二分探索木の形状

#include 
#include 
#include 

#define DATANUM 1000

struct BinarySearchTree{
    int data;
    struct BinarySearchTree *left;
    struct BinarySearchTree *right;
};

struct BinarySearchTree bst[DATANUM];

int makeBinarySearchTree(){
    struct BinarySearchTree *current;
    int i, depth, maxDepth;
    
    srand((unsigned int)time(NULL));
    bst[0].data = rand();
    bst[0].left = NULL;
    bst[0].right = NULL;
    maxDepth = 0;
    
    for (i = 1; i < DATANUM; i++){
        bst[i].data = rand();
        bst[i].left = NULL;
        bst[i].right = NULL;
        
        current = &bst[0];
        
        depth = 1;
        while (-1){
            if(bst[i].data < current->data){
                if (current->left == NULL){
                    current->left = &bst[i];
                    break;
                }
                else {
                    current = current->left;
                    depth++;
                }
            }
            else {
                if (current->right = NULL){
                    current->right = &bst[i];
                    break;
                }
                else {
                    current = current->right;
                    depth++;
                }
            }
        }
        
        if (depth > maxDepth) maxDepth = depth;
    }
    
    return maxDepth;
}

int main(){
    int i, sum;
    
    sum = 0;
    for (i = 1; i <= 10000; i++){
        sum += makeBinarySearchTree();
    }
    
    printf("DATANUM = %d\n", DATANUM);
    printf("max depth average is = %lf\n", sum / 10000.0);
    
    return 0;
}

ASCII文字コード表

ASCIIでは、半角英数記号の1文字を7ビットで表します。

#include 
int main(){
    int row, col;
    char data;
    printf("\t[20]\t[30]\t[40]\t[50]\t[60]\t[70]\n");
    for(row = 0x0; row <= 0xF; row++){
        printf("[%X]", row);
        for(col = 0x20; col <= 0x70; col += 0x10){
            data = col + row;
            if (data == 0x7F) break;
            else printf("\t%c", data);
        }
        printf("\n");
    }
    return 0;
}
	[20]	[30]	[40]	[50]	[60]	[70]
[0]	 	0	@	P	`	p
[1]	!	1	A	Q	a	q
[2]	"	2	B	R	b	r
[3]	#	3	C	S	c	s
[4]	$	4	D	T	d	t
[5]	%	5	E	U	e	u
[6]	&	6	F	V	f	v
[7]	'	7	G	W	g	w
[8]	(	8	H	X	h	x
[9]	)	9	I	Y	i	y
[A]	*	:	J	Z	j	z
[B]	+	;	K	[	k	{
[C]	,	<	L	\	l	|
[D]	-	=	M	]	m	}
[E]	.	>	N	^	n	~
[F]	/	?	O	_	o

x86系32ビットCPU

一般的なwindowsパソコンが採用しているCPUはx86系と呼ばれるCPUです。
86系32ビットCPUが持つ主要なレジスタです。

汎用レジスタ
EAX、EBX、ECX、EDX、ESI、EDI、EBP

特殊レジスタ
ESP、EIP、EFLAGS
CS、DS、ES、SS、FS、GS

windows EXEファイル

EXEファイルっはPortable Executableファイルと呼ばれ、MZヘッダー、PEヘッダー、セクションデータから構成されます。

MZ header:DOS header、MS-DOS header
PEヘッダー:シグネチャ、ファイルヘッダー、オプションヘッダー
セクションデータ:セクションヘッダー1,セクションヘッダー2・・セクション1,セクション2

MZヘッダーには、Windows用プログラムを、MS-DOS環境で誤って起動してしまったときに実行されるMS-DOS用プログラムが格納されています。
PEヘッダーには、Windows用プログラムの情報が格納されています。

Visual Studioに含まれるdumpbin.exeというコマンドラインツールを使えば、EXEファイルの構造を調べることができます。

ポインタ2

#include 
#include 
#include 

int main() {
    char buffer[1000] = "";
    int length;
    char *line = NULL;
    
    printf("type character and enter key");
    gets(buffer);
    length = strlen(buffer);
    if (length > 0) {
        line = (char *)malloc(length + 1);
        strcpy(line, buffer);
        printf("line = %s\n", line);
        free(line);
    }
    return 0;
}

ポインタ

ポインタはメモリーのアドレスを格納できる容器で、なおかつ、どの型のデータを指し示すかの情報を持っています。

下の例では、整数型のポインタ変数pと、整数型の変数iを宣言、iを1に初期化し、「*p」という表現で、変数iの中身を参照しています。

#include 

int main() {
    int *p, i = 1;
    p = &i;
    printf("%d\n", *p);
    return 0;
}

基本データ型

int, float, double, charの変数の大きさです。C言語には、文字列型がありません。C++はstringクラスがあります。

#include 

int main() {
    int i = 1;
    float f = 1;
    double d = 0.5;
    char c = 'a';
    
    printf("i = %d\n", i);
    printf("f = %f\n", f);
    printf("d = %f\n", d);
    printf("c = %c\n", c);
    
    printf("sizeof(i) = %d\n", sizeof(i));
    printf("sizeof(f) = %d\n", sizeof(f));
    printf("sizeof(d) = %d\n", sizeof(d));
    printf("sizeof(c) = %d\n", sizeof(c));
    
    return 0;
}
i = 1
f = 1.000000
d = 0.500000
c = a
sizeof(i) = 4
sizeof(f) = 4
sizeof(d) = 8
sizeof(c) = 1